3030import java .io .IOException ;
3131import java .io .InputStream ;
3232import java .io .OutputStream ;
33+ import java .lang .management .ManagementFactory ;
3334import java .nio .file .Files ;
3435import java .nio .file .NoSuchFileException ;
3536import java .nio .file .Paths ;
4142import java .util .Set ;
4243
4344import org .graalvm .launcher .AbstractLanguageLauncher ;
45+ import org .graalvm .nativeimage .ProcessProperties ;
4446import org .graalvm .options .OptionCategory ;
4547import org .graalvm .polyglot .Context ;
4648import org .graalvm .polyglot .Context .Builder ;
@@ -78,6 +80,8 @@ public static void main(String[] args) {
7880 @ Override
7981 protected List <String > preprocessArguments (List <String > arguments , Map <String , String > polyglotOptions ) {
8082 ArrayList <String > unrecognized = new ArrayList <>();
83+ List <String > inputArgs = new ArrayList <>(arguments );
84+ List <String > subprocessArgs = new ArrayList <>();
8185 programArgs = new ArrayList <>();
8286 for (int i = 0 ; i < arguments .size (); i ++) {
8387 String arg = arguments .get (i );
@@ -143,6 +147,23 @@ protected List<String> preprocessArguments(List<String> arguments, Map<String, S
143147 runLD = true ;
144148 programArgs .addAll (arguments .subList (i + 1 , arguments .size ()));
145149 return unrecognized ;
150+ case "-debug-perf" :
151+ subprocessArgs .add ("Dgraal.TraceTruffleCompilation=true" );
152+ subprocessArgs .add ("Dgraal.TraceTrufflePerformanceWarnings=true" );
153+ subprocessArgs .add ("Dgraal.TruffleCompilationExceptionsArePrinted=true" );
154+ subprocessArgs .add ("Dgraal.TraceTruffleInlining=true" );
155+ subprocessArgs .add ("Dgraal.TruffleTraceSplittingSummary=true" );
156+ inputArgs .remove ("-debug-perf" );
157+ break ;
158+ case "-dump" :
159+ subprocessArgs .add ("Dgraal.Dump=" );
160+ inputArgs .remove ("-dump" );
161+ break ;
162+ case "-compile-truffle-immediately" :
163+ subprocessArgs .add ("Dgraal.TruffleCompileImmediately=true" );
164+ subprocessArgs .add ("Dgraal.TruffleCompilationExceptionsAreThrown=true" );
165+ inputArgs .remove ("-compile-truffle-immediately" );
166+ break ;
146167 default :
147168 if (!arg .startsWith ("-" )) {
148169 inputFile = arg ;
@@ -167,6 +188,10 @@ protected List<String> preprocessArguments(List<String> arguments, Map<String, S
167188 programArgs .add ("" );
168189 }
169190
191+ if (!subprocessArgs .isEmpty ()) {
192+ subExec (inputArgs , subprocessArgs );
193+ }
194+
170195 return unrecognized ;
171196 }
172197
@@ -486,7 +511,7 @@ protected void printHelp(OptionCategory maxCategory) {
486511 // " a defense against denial-of-service attacks\n" +
487512 // "-Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n"
488513 // +
489- "-q : don't print version and copyright messages on interactive startup" +
514+ "-q : don't print version and copyright messages on interactive startup\n " +
490515 "-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n " +
491516 "-S : don't imply 'import site' on initialization\n " +
492517 // "-t : issue warnings about inconsistent tab usage (-tt: issue errors)\n"
@@ -496,7 +521,7 @@ protected void printHelp(OptionCategory maxCategory) {
496521 "-v : verbose (trace import statements); also PYTHONVERBOSE=x\n " +
497522 " can be supplied multiple times to increase verbosity\n " +
498523 "-V : print the Python version number and exit (also --version)\n " +
499- " when given twice, print more information about the build" +
524+ " when given twice, print more information about the build\n " +
500525 // "-W arg : warning control; arg is
501526 // action:message:category:module:lineno\n" +
502527 // " also PYTHONWARNINGS=arg\n" +
@@ -508,7 +533,7 @@ protected void printHelp(OptionCategory maxCategory) {
508533 // "- : program read from stdin (default; interactive mode if a tty)\n" +
509534 "arg ...: arguments passed to program in sys.argv[1:]\n " +
510535 "\n " +
511- "Arguments specific to GraalPython. \n " +
536+ "Arguments specific to GraalPython: \n " +
512537 "--show-version : print the Python version number and continue.\n " +
513538 "-CC : run the C compiler used for generating GraalPython C extensions.\n " +
514539 " All following arguments are passed to the compiler.\n " +
@@ -527,6 +552,12 @@ protected void printHelp(OptionCategory maxCategory) {
527552 " as specifying the -R option: a random value is used to seed the hashes of\n " +
528553 " str, bytes and datetime objects. It can also be set to an integer\n " +
529554 " in the range [0,4294967295] to get hash values with a predictable seed." );
555+ if (maxCategory .compareTo (OptionCategory .DEBUG ) >= 0 ) {
556+ print ("\n GraalPython performance debugging options:\n " +
557+ "-debug-perf : Enable tracing of Truffle compilations and its warnings\n " +
558+ "-dump : Enable dumping of compilation graphs to IGV\n " +
559+ "-compile-truffle-immediately : Start compiling on first invocation and throw compilation exceptions" );
560+ }
530561 }
531562
532563 @ Override
@@ -678,6 +709,51 @@ private void setupREPL(Context context, ConsoleHandler consoleHandler) {
678709 }
679710 }
680711
712+ /**
713+ * Some system properties have already been read at this point, so to change them, we just
714+ * re-execute the process with the additional options.
715+ */
716+ private static void subExec (List <String > args , List <String > subProcessDefs ) {
717+ List <String > cmd = new ArrayList <>();
718+ if (isAOT ()) {
719+ cmd .add (ProcessProperties .getExecutableName ());
720+ for (String subProcArg : subProcessDefs ) {
721+ assert subProcArg .startsWith ("D" );
722+ cmd .add ("--native." + subProcArg );
723+ }
724+ } else {
725+ cmd .add (System .getProperty ("java.home" ) + File .separator + "bin" + File .separator + "java" );
726+ switch (System .getProperty ("java.vm.name" )) {
727+ case "Java HotSpot(TM) 64-Bit Server VM" :
728+ cmd .add ("-server" );
729+ cmd .add ("-d64" );
730+ break ;
731+ case "Java HotSpot(TM) 64-Bit Client VM" :
732+ cmd .add ("-client" );
733+ cmd .add ("-d64" );
734+ break ;
735+ default :
736+ break ;
737+ }
738+ cmd .addAll (ManagementFactory .getRuntimeMXBean ().getInputArguments ());
739+ cmd .add ("-cp" );
740+ cmd .add (ManagementFactory .getRuntimeMXBean ().getClassPath ());
741+ for (String subProcArg : subProcessDefs ) {
742+ assert subProcArg .startsWith ("D" );
743+ cmd .add ("-" + subProcArg );
744+ }
745+ cmd .add (GraalPythonMain .class .getName ());
746+ }
747+
748+ cmd .addAll (args );
749+ try {
750+ System .exit (new ProcessBuilder (cmd .toArray (new String [0 ])).inheritIO ().start ().waitFor ());
751+ } catch (IOException | InterruptedException e ) {
752+ System .err .println (e .getMessage ());
753+ System .exit (-1 );
754+ }
755+ }
756+
681757 private static final class ExitException extends RuntimeException {
682758 private static final long serialVersionUID = 1L ;
683759 private final int code ;
0 commit comments