comparison mx/mx_graal.py @ 21104:9690597d7a29

Group javap queries to discover Graal services
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Thu, 23 Apr 2015 21:30:54 +0200
parents 3f51d02e536f
children db2de6c2bf95
comparison
equal deleted inserted replaced
21103:ece51b327e71 21104:9690597d7a29
592 shutil.copyfile(src, tmp) 592 shutil.copyfile(src, tmp)
593 os.close(fd) 593 os.close(fd)
594 shutil.move(tmp, dstLib) 594 shutil.move(tmp, dstLib)
595 os.chmod(dstLib, permissions) 595 os.chmod(dstLib, permissions)
596 596
597 def _isGraalService(className, graalJars): 597 def _eraseGenerics(className):
598 if '<' in className:
599 return className[:className.index('<')]
600 return className
601
602 def _classifyGraalServices(classNames, graalJars):
603 classification = {}
604 for className in classNames:
605 classification[className] = None
598 javap = mx.java().javap 606 javap = mx.java().javap
599 output = subprocess.check_output([javap, '-cp', os.pathsep.join(graalJars), className], stderr=subprocess.STDOUT) 607 output = subprocess.check_output([javap, '-cp', os.pathsep.join(graalJars)] + classNames, stderr=subprocess.STDOUT)
600 lines = output.split(os.linesep) 608 lines = output.split(os.linesep)
601 decl = 'public interface ' + className
602 for line in lines: 609 for line in lines:
603 if line.startswith(decl): 610 if line.startswith('public interface '):
604 declLine = line.strip() 611 declLine = line[len('public interface '):].strip()
605 break 612 for className in classNames:
606 if not declLine: 613 if declLine.startswith(className):
607 mx.abort('Could not find interface for service ' + className + ':\n' + output) 614 assert classification[className] is None
608 afterName = declLine[len(decl):] 615 afterName = declLine[len(className):]
609 if not afterName.startswith(' extends '): 616 if not afterName.startswith(' extends '):
610 return False 617 classification[className] = False
611 superInterfaces = afterName[len(' extends '):-len(' {')].split(',') 618 break
612 if 'com.oracle.graal.api.runtime.Service' in superInterfaces: 619 superInterfaces = afterName[len(' extends '):-len(' {')].split(',')
613 return True 620 if 'com.oracle.graal.api.runtime.Service' in superInterfaces:
614 for superInterface in superInterfaces: 621 classification[className] = True
615 if '<' in superInterface: 622 break
616 superInterface = superInterface[:superInterface.index('<')] 623 maybe = [_eraseGenerics(superInterface) for superInterface in superInterfaces]
617 if _isGraalService(superInterface, graalJars): 624 classification[className] = maybe
618 return True 625 break
619 return False 626 for className, v in classification.items():
627 if v is None:
628 mx.abort('Could not find interface for service ' + className + ':\n' + output)
629 return classification
630
631 def _extractMaybes(classification):
632 maybes = []
633 for v in classification.values():
634 if isinstance(v, list):
635 maybes.extend(v)
636 return maybes
637
638 def _mergeClassification(classification, newClassification):
639 for className, value in classification.items():
640 if isinstance(value, list):
641 classification[className] = None
642 for superInterface in value:
643 if newClassification[superInterface] is True:
644 classification[className] = True
645 break
646 elif newClassification[superInterface] is False:
647 if classification[className] is None:
648 classification[className] = False
649 else:
650 if not classification[className]:
651 classification[className] = []
652 classification[className].extend(newClassification[superInterface])
653
654 def _filterGraalService(classNames, graalJars):
655 classification = _classifyGraalServices(classNames, graalJars)
656 needClassification = _extractMaybes(classification)
657 while needClassification:
658 _mergeClassification(classification, _classifyGraalServices(needClassification, graalJars))
659 needClassification = _extractMaybes(classification)
660 filtered = []
661 for className in classNames:
662 if classification[className] is True:
663 filtered.append(className)
664 return filtered
620 665
621 def _extractGraalServiceFiles(graalJars, destination, cleanDestination=True): 666 def _extractGraalServiceFiles(graalJars, destination, cleanDestination=True):
622 services = set() 667 graalServices = set()
623 if cleanDestination: 668 if cleanDestination:
624 if exists(destination): 669 if exists(destination):
625 shutil.rmtree(destination) 670 shutil.rmtree(destination)
626 os.makedirs(destination) 671 os.makedirs(destination)
627 for jar in graalJars: 672 for jar in graalJars:
628 if os.path.isfile(jar): 673 if os.path.isfile(jar):
629 with zipfile.ZipFile(jar) as zf: 674 with zipfile.ZipFile(jar) as zf:
675 services = []
630 for member in zf.namelist(): 676 for member in zf.namelist():
631 if not member.startswith('META-INF/services'): 677 if not member.startswith('META-INF/services'):
632 continue 678 continue
633 serviceName = basename(member) 679 serviceName = basename(member)
634 # we don't handle directories 680 # we don't handle directories
635 assert serviceName and member == 'META-INF/services/' + serviceName 681 assert serviceName and member == 'META-INF/services/' + serviceName
636 if not _isGraalService(serviceName, graalJars): 682 services.append(serviceName)
637 continue 683 services = _filterGraalService(services, graalJars)
638 services.add(serviceName) 684 for serviceName in services:
685 graalServices.add(serviceName)
639 target = join(destination, serviceName) 686 target = join(destination, serviceName)
640 lines = [] 687 lines = []
641 with zf.open(member) as serviceFile: 688 with zf.open(member) as serviceFile:
642 lines.extend(serviceFile.readlines()) 689 lines.extend(serviceFile.readlines())
643 if exists(target): 690 if exists(target):
644 with open(target) as targetFile: 691 with open(target) as targetFile:
645 lines.extend(targetFile.readlines()) 692 lines.extend(targetFile.readlines())
646 with open(target, "w+") as targetFile: 693 with open(target, "w+") as targetFile:
647 for line in lines: 694 for line in lines:
648 targetFile.write(line.rstrip() + os.linesep) 695 targetFile.write(line.rstrip() + os.linesep)
649 return services 696 return graalServices
650 697
651 def _updateGraalServiceFiles(jdkDir): 698 def _updateGraalServiceFiles(jdkDir):
652 jreGraalDir = join(jdkDir, 'jre', 'lib', 'graal') 699 jreGraalDir = join(jdkDir, 'jre', 'lib', 'graal')
653 graalJars = [join(jreGraalDir, e) for e in os.listdir(jreGraalDir) if e.startswith('graal') and e.endswith('.jar')] 700 graalJars = [join(jreGraalDir, e) for e in os.listdir(jreGraalDir) if e.startswith('graal') and e.endswith('.jar')]
654 jreGraalServicesDir = join(jreGraalDir, 'services') 701 jreGraalServicesDir = join(jreGraalDir, 'services')