Mercurial > hg > graal-compiler
comparison pytools/gl.py @ 3607:de066dcbf607
Added Python scripts in new 'shell' project. The shell/commands.py script should replace all the existing run*.sh scripts in the top level Graal directory and is where new commands should go.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 31 Oct 2011 21:06:04 +0100 |
parents | |
children | 3b2ab8970aa4 |
comparison
equal
deleted
inserted
replaced
3606:f2fd47582524 | 3607:de066dcbf607 |
---|---|
1 #!/usr/bin/python | |
2 # | |
3 # gl.py - shell interface for Graal source code | |
4 # | |
5 # ---------------------------------------------------------------------------------------------------- | |
6 # | |
7 # Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. | |
8 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
9 # | |
10 # This code is free software; you can redistribute it and/or modify it | |
11 # under the terms of the GNU General Public License version 2 only, as | |
12 # published by the Free Software Foundation. | |
13 # | |
14 # This code is distributed in the hope that it will be useful, but WITHOUT | |
15 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 # version 2 for more details (a copy is included in the LICENSE file that | |
18 # accompanied this code). | |
19 # | |
20 # You should have received a copy of the GNU General Public License version | |
21 # 2 along with this work; if not, write to the Free Software Foundation, | |
22 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
23 # | |
24 # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
25 # or visit www.oracle.com if you need additional information or have any | |
26 # questions. | |
27 # | |
28 # ---------------------------------------------------------------------------------------------------- | |
29 # | |
30 # A launcher for Graal executables and tools. | |
31 # | |
32 | |
33 import subprocess | |
34 from threading import Thread | |
35 from argparse import ArgumentParser, REMAINDER | |
36 from os.path import join, dirname, abspath, exists, isfile, isdir | |
37 import commands | |
38 import types | |
39 import sys | |
40 import os | |
41 | |
42 class Env(ArgumentParser): | |
43 | |
44 # Override parent to append the list of available commands | |
45 def format_help(self): | |
46 msg = ArgumentParser.format_help(self) + '\navailable commands:\n\n' | |
47 for cmd in sorted(commands.table.iterkeys()): | |
48 c, _ = commands.table[cmd][:2] | |
49 doc = c.__doc__ | |
50 if doc is None: | |
51 doc = '' | |
52 msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) | |
53 return msg + '\n' | |
54 | |
55 def __init__(self): | |
56 self.dacapo = os.getenv('DACAPO') | |
57 self.jdk7 = os.getenv('JDK7') | |
58 self.jdk7g = os.getenv('JDK7G') | |
59 self.maxine_home = os.getenv('MAXINE') | |
60 | |
61 ArgumentParser.__init__(self, prog='gl') | |
62 | |
63 self.add_argument('-v', action='store_true', dest='verbose', help='enable verbose output') | |
64 self.add_argument('--dacapo', help='path to DaCapo 91.12 jar file') | |
65 self.add_argument('--jdk7', help='JDK7 installation in which the GraalVM binary is installed', metavar='<path>') | |
66 self.add_argument('--jdk7g', help='JDK7G installation in which the GraalVM binary is installed', metavar='<path>') | |
67 self.add_argument('-M', '--maxine', dest='maxine_home', help='path to Maxine code base', metavar='<path>') | |
68 | |
69 def parse_cmd_line(self): | |
70 | |
71 self.add_argument('commandAndArgs', nargs=REMAINDER, metavar='command args...') | |
72 | |
73 self.parse_args(namespace=self) | |
74 | |
75 if not isdir(self.jdk7): | |
76 self.log('JDK7 is required. Use --jdk7 option or set JDK7 environment variable') | |
77 self.abort(1) | |
78 | |
79 if not isdir(self.jdk7g): | |
80 self.log('JDK7G is required. Use --jdk7g option or set JDK7G environment variable') | |
81 self.abort(1) | |
82 | |
83 self.graal_home = dirname(abspath(dirname(sys.argv[0]))) | |
84 | |
85 def load_config_file(self, configFile): | |
86 """ adds attributes to this object from a file containing key=value lines """ | |
87 if exists(configFile): | |
88 with open(configFile) as f: | |
89 self.log('[loading vars from ' + configFile + ']') | |
90 for line in f: | |
91 kv = line.split('=', 1) | |
92 if len(kv) == 2: | |
93 k = kv[0].strip().lower() | |
94 setattr(self, k, os.path.expandvars(kv[1].strip())) | |
95 | |
96 def get_os(self): | |
97 if sys.platform.startswith('darwin'): | |
98 return 'darwin' | |
99 elif sys.platform.startswith('linux'): | |
100 return 'linux' | |
101 elif sys.platform.startswith('sunos'): | |
102 return 'solaris' | |
103 elif sys.platform.startswith('win32') or sys.platform.startswith('cygwin'): | |
104 return 'windows' | |
105 else: | |
106 print 'Supported operating system could not be derived from', sys.platform | |
107 self.abort(1) | |
108 | |
109 | |
110 def exe(self, name): | |
111 if self.get_os() == 'windows': | |
112 return name + '.exe' | |
113 return name | |
114 | |
115 def run_dacapo(self, args): | |
116 if not isfile(self.dacapo) or not self.dacapo.endswith('.jar'): | |
117 self.log('Specified DaCapo jar file does not exist or is not a jar file: ' + self.dacapo) | |
118 self.abort(1) | |
119 return self.run_vm(['-Xms1g', '-Xmx2g', '-esa', '-XX:-GraalBailoutIsFatal', '-G:-QuietBailout', '-cp', self.dacapo] + args) | |
120 | |
121 def run_vm(self, args): | |
122 if self.maxine_home is None: | |
123 self.log('Path to Maxine code base must be specified with -M option of MAXINE environment variable') | |
124 self.abort(1) | |
125 if not exists(join(self.maxine_home, 'com.oracle.max.graal.hotspot', 'bin', 'com', 'oracle', 'max', 'graal', 'hotspot', 'VMEntriesNative.class')): | |
126 self.log('Maxine code base path specified -M option or MAXINE environment variable does not contain com.oracle.max.graal.hotspot/bin/com/oracle/max/graal/hotspot/VMEntriesNative.class: ' + self.maxine_home) | |
127 self.abort(1) | |
128 | |
129 os.environ['MAXINE'] = self.maxine_home | |
130 exe = join(self.jdk7, 'bin', self.exe('java')) | |
131 return self.run([exe, '-graal'] + args) | |
132 | |
133 def run(self, args, nonZeroIsFatal=True, out=None, err=None, cwd=None): | |
134 """ | |
135 | |
136 Run a command in a subprocess, wait for it to complete and return the exit status of the process. | |
137 If the exit status is non-zero and `nonZeroIsFatal` is true, then the program is exited with | |
138 the same exit status. | |
139 Each line of the standard output and error streams of the subprocess are redirected to the | |
140 provided out and err functions if they are not None. | |
141 | |
142 """ | |
143 | |
144 assert isinstance(args, types.ListType), "'args' must be a list: " + str(args) | |
145 for arg in args: | |
146 if not isinstance(arg, types.StringTypes): | |
147 self.log('argument is not a string: ' + str(arg)) | |
148 self.abort(1) | |
149 | |
150 if self.verbose: | |
151 self.log(' '.join(args)) | |
152 | |
153 try: | |
154 if out is None and err is None: | |
155 retcode = subprocess.call(args, cwd=cwd) | |
156 else: | |
157 def redirect(stream, f): | |
158 for line in iter(stream.readline, ''): | |
159 f(line) | |
160 stream.close() | |
161 p = subprocess.Popen(args, stdout=None if out is None else subprocess.PIPE, stderr=None if err is None else subprocess.PIPE) | |
162 if out is not None: | |
163 t = Thread(target=redirect, args=(p.stdout, out)) | |
164 t.daemon = True # thread dies with the program | |
165 t.start() | |
166 if err is not None: | |
167 t = Thread(target=redirect, args=(p.stderr, err)) | |
168 t.daemon = True # thread dies with the program | |
169 t.start() | |
170 retcode = p.wait() | |
171 except OSError as e: | |
172 self.log('Error executing \'' + ' '.join(args) + '\': ' + str(e)) | |
173 if self.verbose: | |
174 raise e | |
175 self.abort(e.errno) | |
176 | |
177 | |
178 if retcode and nonZeroIsFatal: | |
179 if self.verbose: | |
180 raise subprocess.CalledProcessError(retcode, ' '.join(args)) | |
181 self.abort(retcode) | |
182 | |
183 return retcode | |
184 | |
185 | |
186 def log(self, msg=None): | |
187 if msg is None: | |
188 print | |
189 else: | |
190 print msg | |
191 | |
192 def abort(self, code): | |
193 """ raises a SystemExit exception with the provided exit code """ | |
194 raise SystemExit(code) | |
195 | |
196 def main(env): | |
197 configFile = join(dirname(sys.argv[0]), 'glrc') | |
198 env.load_config_file(configFile) | |
199 env.parse_cmd_line() | |
200 | |
201 if len(env.commandAndArgs) == 0: | |
202 env.print_help() | |
203 return | |
204 | |
205 env.command = env.commandAndArgs[0] | |
206 env.command_args = env.commandAndArgs[1:] | |
207 | |
208 if not commands.table.has_key(env.command): | |
209 env.error('unknown command "' + env.command + '"') | |
210 | |
211 c, _ = commands.table[env.command][:2] | |
212 try: | |
213 retcode = c(env, env.command_args) | |
214 if retcode is not None and retcode != 0: | |
215 env.abort(retcode) | |
216 except KeyboardInterrupt: | |
217 env.abort(1) | |
218 | |
219 #This idiom means the below code only runs when executed from command line | |
220 if __name__ == '__main__': | |
221 main(Env()) |