# HG changeset patch # User Doug Simon # Date 1433068335 -7200 # Node ID 60154926b5139d2fbda526fdb70355447c2ca2f0 # Parent f2a6088ddebc66a1bc4384011bf430e79eda6ff8 replaced use of javap with a small Java utility for refining service class list to only those implementing com.oracle.jvmci.service.Service diff -r f2a6088ddebc -r 60154926b513 mx/FilterTypes.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mx/FilterTypes.java Sun May 31 12:32:15 2015 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class FilterTypes { + + /** + * Prints to {@link System#out} the values in {@code args[1 .. N]} that denote classes that are + * {@link Class#isAssignableFrom(Class) assignable} to the type denoted in {@code args[0]}. The + * values are separated by {@code "|"}. + */ + public static void main(String... args) throws Exception { + Class jvmciServiceInterface = Class.forName(args[0]); + boolean needSep = false; + StringBuilder buf = new StringBuilder(); + for (int i = 1; i < args.length; ++i) { + String serviceName = args[i]; + Class service = Class.forName(serviceName, false, FilterTypes.class.getClassLoader()); + if (jvmciServiceInterface.isAssignableFrom(service)) { + if (buf.length() != 0) { + buf.append('|'); + } + buf.append(serviceName); + needSep = true; + } + } + System.out.print(buf); + } +} diff -r f2a6088ddebc -r 60154926b513 mx/mx_graal.py --- a/mx/mx_graal.py Sat May 30 14:31:16 2015 +0200 +++ b/mx/mx_graal.py Sun May 31 12:32:15 2015 +0200 @@ -547,78 +547,17 @@ shutil.move(tmp, dstLib) os.chmod(dstLib, permissions) -def _eraseGenerics(className): - if '<' in className: - return className[:className.index('<')] - return className - -def _classifyJVMCIServices(classNames, jvmciJars): - classification = {} - if not classNames: - return classification - for className in classNames: - classification[className] = None - javap = mx.java().javap - output = subprocess.check_output([javap, '-cp', os.pathsep.join(jvmciJars)] + classNames, stderr=subprocess.STDOUT) - lines = output.split(os.linesep) - for line in lines: - if line.startswith('public interface '): - declLine = line[len('public interface '):].strip() - for className in classNames: - if declLine.startswith(className): - assert classification[className] is None - afterName = declLine[len(className):] - if not afterName.startswith(' extends '): - classification[className] = False - break - superInterfaces = afterName[len(' extends '):-len(' {')].split(',') - if 'com.oracle.jvmci.service.Service' in superInterfaces: - classification[className] = True - break - maybe = [_eraseGenerics(superInterface) for superInterface in superInterfaces] - classification[className] = maybe - break - for className, v in classification.items(): - if v is None: - mx.abort('Could not find interface for service ' + className + ':\n' + output) - return classification - -def _extractMaybes(classification): - maybes = set() - for v in classification.values(): - if isinstance(v, list): - maybes.update(v) - return list(maybes) - -def _mergeClassification(classification, newClassification): - for className, value in classification.items(): - if isinstance(value, list): - classification[className] = None - for superInterface in value: - if newClassification[superInterface] is True: - classification[className] = True - break - elif newClassification[superInterface] is False: - if classification[className] is None: - classification[className] = False - else: - if not classification[className]: - classification[className] = [] - classification[className].extend(newClassification[superInterface]) - -def _filterJVMCIService(classNames, jvmciJars): - classification = _classifyJVMCIServices(classNames, jvmciJars) - needClassification = _extractMaybes(classification) - while needClassification: - _mergeClassification(classification, _classifyJVMCIServices(needClassification, jvmciJars)) - needClassification = _extractMaybes(classification) - filtered = [] - for className in classNames: - if classification[className] is True: - filtered.append(className) - return filtered - -def _extractJVMCIFiles(jvmciJars, servicesDir, optionsDir, cleanDestination=True): +def _filterJVMCIServices(serviceImplNames, classpath): + """ + Filters and returns the names in 'serviceImplNames' that denote + types available in 'classpath' implementing or extending + com.oracle.jvmci.service.Service. + """ + _, binDir = mx._compile_mx_class('FilterTypes', os.pathsep.join(classpath), myDir=dirname(__file__)) + cmd = [mx.java().java, '-cp', mx._cygpathU2W(os.pathsep.join([binDir] + classpath)), 'FilterTypes', 'com.oracle.jvmci.service.Service'] + serviceImplNames + return subprocess.check_output(cmd, stderr=subprocess.PIPE).split('|') + +def _extractJVMCIFiles(jdkJars, jvmciJars, servicesDir, optionsDir, cleanDestination=True): if cleanDestination: if exists(servicesDir): shutil.rmtree(servicesDir) @@ -653,7 +592,7 @@ with zf.open(member) as optionsFile, \ file(targetpath, "wb") as target: shutil.copyfileobj(optionsFile, target) - jvmciServices = _filterJVMCIService(servicesMap.keys(), jvmciJars) + jvmciServices = _filterJVMCIServices(servicesMap.keys(), jdkJars) for serviceName in jvmciServices: serviceImpls = servicesMap[serviceName] fd, tmp = tempfile.mkstemp(prefix=serviceName) @@ -672,7 +611,7 @@ jvmciJars = [join(jreJVMCIDir, e) for e in os.listdir(jreJVMCIDir) if e.endswith('.jar')] jreGraalServicesDir = join(jreJVMCIDir, 'services') jreGraalOptionsDir = join(jreJVMCIDir, 'options') - _extractJVMCIFiles(jvmciJars, jreGraalServicesDir, jreGraalOptionsDir) + _extractJVMCIFiles(_getJdkDeployedJars(jdkDir), jvmciJars, jreGraalServicesDir, jreGraalOptionsDir) def _patchGraalVersionConstant(dist): """ @@ -732,6 +671,24 @@ # deploy service files _updateJVMCIFiles(jdkDir) +def _getJdkDeployedJars(jdkDir): + """ + Gets jar paths for all deployed distributions in the context of + a given JDK directory. + """ + jreLibDir = join(jdkDir, 'jre', 'lib') + jars = [] + for dist in _jdkDeployedDists: + jar = basename(mx.distribution(dist.name).path) + if dist.isExtension: + jars.append(join(jreLibDir, 'ext', jar)) + elif dist.usesJVMCIClassLoader: + jars.append(join(jreLibDir, 'jvmci', jar)) + else: + jars.append(join(jreLibDir, jar)) + return jars + + # run a command in the windows SDK Debug Shell def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None): if respondTo is None: @@ -892,8 +849,10 @@ with open(defsPath) as fp: defs = fp.read() jvmciJars = [] + jdkJars = [] for jdkDist in _jdkDeployedDists: dist = mx.distribution(jdkDist.name) + jdkJars.append(join(_graal_home, dist.path)) defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/' + basename(dist.path) if jdkDist.isExtension: defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_EXT_DIR)/' + basename(dist.path) @@ -905,7 +864,7 @@ if defLine not in defs: mx.abort('Missing following line in ' + defsPath + '\n' + defLine) shutil.copy(dist.path, opts2.export_dir) - services, optionsFiles = _extractJVMCIFiles(jvmciJars, join(opts2.export_dir, 'services'), join(opts2.export_dir, 'options')) + services, optionsFiles = _extractJVMCIFiles(jdkJars, jvmciJars, join(opts2.export_dir, 'services'), join(opts2.export_dir, 'options')) for service in services: defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/' + service if defLine not in defs: diff -r f2a6088ddebc -r 60154926b513 mxtool/mx.py --- a/mxtool/mx.py Sat May 30 14:31:16 2015 +0200 +++ b/mxtool/mx.py Sun May 31 12:32:15 2015 +0200 @@ -5434,8 +5434,8 @@ _show_section('projects', s.projects) _show_section('distributions', s.dists) -def _compile_mx_class(javaClassName, classpath=None, jdk=None): - myDir = dirname(__file__) +def _compile_mx_class(javaClassName, classpath=None, jdk=None, myDir=None): + myDir = dirname(__file__) if myDir is None else myDir binDir = join(myDir, 'bin' if not jdk else '.jdk' + str(jdk.version)) javaSource = join(myDir, javaClassName + '.java') javaClass = join(binDir, javaClassName + '.class')