changeset 22041:56c50504d60d

mx: removed JVMCI code from Distribution.make_archive
author Doug Simon <doug.simon@oracle.com>
date Sat, 20 Jun 2015 12:37:01 +0200
parents 0751fdae4e7a
children db48a62aba36 595eccce0ae1
files mx.graal/mx_graal.py mxtool/mx.py
diffstat 2 files changed, 89 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/mx.graal/mx_graal.py	Sat Jun 20 09:00:58 2015 +0200
+++ b/mx.graal/mx_graal.py	Sat Jun 20 12:37:01 2015 +0200
@@ -2343,6 +2343,47 @@
 
     mx.update_commands(suite, commands)
 
+class JVMCIArchiveParticipant:
+    def __init__(self, dist):
+        self.dist = dist
+        self.jvmciServices = {}
+
+    def __opened__(self, arc, srcArc, services):
+        self.services = services
+        self.arc = arc
+        self.expectedOptionsProviders = set()
+
+    def __add__(self, arcname, contents):
+        if arcname.startswith('META-INF/jvmci.services/'):
+            service = arcname[len('META-INF/jvmci.services/'):]
+            self.jvmciServices.setdefault(service, []).extend([provider for provider in contents.split('\n')])
+            return True
+        if arcname.startswith('META-INF/jvmci.providers/'):
+            provider = arcname[len('META-INF/jvmci.providers/'):]
+            for service in contents.split('\n'):
+                self.jvmciServices.setdefault(service, []).append(provider)
+            return True
+        elif arcname.startswith('META-INF/jvmci.options/'):
+            # Need to create service files for the providers of the
+            # com.oracle.jvmci.options.Options service created by
+            # com.oracle.jvmci.options.processor.OptionProcessor.
+            optionsOwner = arcname[len('META-INF/jvmci.options/'):]
+            provider = optionsOwner + '_Options'
+            self.expectedOptionsProviders.add(provider.replace('.', '/') + '.class')
+            #assert exists(providerClassfile), 'missing generated Options provider ' + providerClassfile
+            self.services.setdefault('com.oracle.jvmci.options.Options', []).append(provider)
+        return False
+
+    def __addsrc__(self, arcname, contents):
+        return False
+
+    def __closing__(self):
+        self.expectedOptionsProviders -= set(self.arc.zf.namelist())
+        assert len(self.expectedOptionsProviders) == 0, 'missing generated Options providers:\n  ' + '\n  '.join(self.expectedOptionsProviders)
+        for service, providers in self.jvmciServices.iteritems():
+            arcname = 'META-INF/jvmci.services/' + service
+            self.arc.zf.writestr(arcname, '\n'.join(providers))
+
 def mx_post_parse_cmd_line(opts):  #
     # TODO _minVersion check could probably be part of a Suite in mx?
     def _versionCheck(version):
@@ -2377,4 +2418,8 @@
                 if not jdkDist.partOfHotSpot:
                     _installDistInJdks(jdkDeployable)
             return _install
-        mx.distribution(jdkDist.name).add_update_listener(_close(jdkDist))
+        dist = mx.distribution(jdkDist.name)
+        dist.add_update_listener(_close(jdkDist))
+        if jdkDist.usesJVMCIClassLoader:
+            dist.set_archiveparticipant(JVMCIArchiveParticipant(dist))
+
--- a/mxtool/mx.py	Sat Jun 20 09:00:58 2015 +0200
+++ b/mxtool/mx.py	Sat Jun 20 12:37:01 2015 +0200
@@ -127,6 +127,7 @@
         self.sourcesPath = _make_absolute(sourcesPath.replace('/', os.sep), suite.dir) if sourcesPath else None
         self.deps = deps
         self.update_listeners = set()
+        self.archiveparticipant = None
         self.mainClass = mainClass
         self.excludedDependencies = excludedDependencies
         self.distDependencies = distDependencies
@@ -152,6 +153,27 @@
     def add_update_listener(self, listener):
         self.update_listeners.add(listener)
 
+    def set_archiveparticipant(self, archiveparticipant):
+        """
+        Adds an object that participates in the make_archive method of this distribution by defining the following methods:
+
+        __opened__(arc, srcArc, services)
+            Called when archiving starts. The 'arc' and 'srcArc' Archiver objects are for writing to the
+            binary and source jars for the distribution. The 'services' dict is for collating the files
+            that will be written to META-INF/services in the binary jar. It's a map from service names
+            to a list of providers for the named service.
+        __add__(arcname, contents)
+            Submits an entry for addition to the binary archive (via the 'zf' ZipFile field of the 'arc' object).
+            Returns True if this object writes to the archive or wants to exclude the entry from the archive,
+            False if the caller should add the entry.
+        __addsrc__(arcname, contents)
+            Same as __add__ except if targets the source archive.
+        __closing__()
+            Called just before the 'services' are written to the binary archive and both archives are
+            written to their underlying files.
+        """
+        self.archiveparticipant = archiveparticipant
+
     def get_dist_deps(self, includeSelf=True, transitive=False):
         deps = []
         if includeSelf:
@@ -190,7 +212,10 @@
             with Archiver(None if unified else self.sourcesPath) as srcArcRaw:
                 srcArc = arc if unified else srcArcRaw
                 services = {}
-                jvmciServices = {}
+
+                if self.archiveparticipant:
+                    self.archiveparticipant.__opened__(arc, srcArc, services)
+
                 def overwriteCheck(zf, arcname, source):
                     if os.path.basename(arcname).startswith('.'):
                         logv('Excluding dotfile: ' + source)
@@ -237,15 +262,17 @@
                                         assert '/' not in service
                                         services.setdefault(service, []).extend(lp.read(arcname).splitlines())
                                     else:
-                                        assert not arcname.startswith('META-INF/jvmci.services/'), 'did not expect to see jvmci.services in ' + lpath
-                                        assert not arcname.startswith('META-INF/jvmci.options/'), 'did not expect to see jvmci.options in ' + lpath
                                         if not overwriteCheck(arc.zf, arcname, lpath + '!' + arcname):
-                                            arc.zf.writestr(arcname, lp.read(arcname))
+                                            contents = lp.read(arcname)
+                                            if not self.archiveparticipant or not self.archiveparticipant.__add__(arcname, contents):
+                                                arc.zf.writestr(arcname, contents)
                         if srcArc.zf and libSourcePath:
                             with zipfile.ZipFile(libSourcePath, 'r') as lp:
                                 for arcname in lp.namelist():
                                     if not overwriteCheck(srcArc.zf, arcname, lpath + '!' + arcname):
-                                        srcArc.zf.writestr(arcname, lp.read(arcname))
+                                        contents = lp.read(arcname)
+                                        if not self.archiveparticipant or not self.archiveparticipant.__addsrc__(arcname, contents):
+                                            srcArc.zf.writestr(arcname, contents)
                     elif dep.isProject():
                         p = dep
 
@@ -261,29 +288,13 @@
                                 for service in files:
                                     with open(join(root, service), 'r') as fp:
                                         services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
-                            elif relpath == join('META-INF', 'jvmci.services'):
-                                for service in files:
-                                    with open(join(root, service), 'r') as fp:
-                                        jvmciServices.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
-                            elif relpath == join('META-INF', 'jvmci.providers'):
-                                for provider in files:
-                                    with open(join(root, provider), 'r') as fp:
-                                        for service in fp:
-                                            jvmciServices.setdefault(service.strip(), []).append(provider)
                             else:
-                                if relpath == join('META-INF', 'jvmci.options'):
-                                    # Need to create service files for the providers of the
-                                    # com.oracle.jvmci.options.Options service created by
-                                    # com.oracle.jvmci.options.processor.OptionProcessor.
-                                    for optionsOwner in files:
-                                        provider = optionsOwner + '_Options'
-                                        providerClassfile = join(outputDir, provider.replace('.', os.sep) + '.class')
-                                        assert exists(providerClassfile), 'missing generated Options provider ' + providerClassfile
-                                        services.setdefault('com.oracle.jvmci.options.Options', []).append(provider)
                                 for f in files:
                                     arcname = join(relpath, f).replace(os.sep, '/')
-                                    if not overwriteCheck(arc.zf, arcname, join(root, f)):
-                                        arc.zf.write(join(root, f), arcname)
+                                    with open(join(root, f), 'r') as fp:
+                                        contents = fp.read()
+                                    if not self.archiveparticipant or not self.archiveparticipant.__add__(arcname, contents):
+                                        arc.zf.writestr(arcname, contents)
                         if srcArc.zf:
                             sourceDirs = p.source_dirs()
                             if p.source_gen_dir():
@@ -295,14 +306,17 @@
                                         if f.endswith('.java'):
                                             arcname = join(relpath, f).replace(os.sep, '/')
                                             if not overwriteCheck(srcArc.zf, arcname, join(root, f)):
-                                                srcArc.zf.write(join(root, f), arcname)
+                                                with open(join(root, f), 'r') as fp:
+                                                    contents = fp.read()
+                                                if not self.archiveparticipant or not self.archiveparticipant.__addsrc__(arcname, contents):
+                                                    srcArc.zf.writestr(arcname, contents)
+
+                if self.archiveparticipant:
+                    self.archiveparticipant.__closing__()
 
                 for service, providers in services.iteritems():
                     arcname = 'META-INF/services/' + service
                     arc.zf.writestr(arcname, '\n'.join(providers))
-                for service, providers in jvmciServices.iteritems():
-                    arcname = 'META-INF/jvmci.services/' + service
-                    arc.zf.writestr(arcname, '\n'.join(providers))
 
         self.notify_updated()