1 /*
2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package jdk.test.lib.jittester;
25 
26 import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
27 
28 import java.io.IOException;
29 import java.io.PrintWriter;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.nio.file.StandardOpenOption;
33 import java.util.function.Function;
34 
35 /**
36  * Generates class files from IRTree
37  */
38 class ByteCodeGenerator extends TestsGenerator {
39     private static final String DEFAULT_SUFFIX = "bytecode_tests";
40 
ByteCodeGenerator()41     ByteCodeGenerator() {
42         super(DEFAULT_SUFFIX);
43     }
44 
ByteCodeGenerator(String suffix, Function<String, String[]> preRunActions, String jtDriverOptions)45     ByteCodeGenerator(String suffix, Function<String, String[]> preRunActions, String jtDriverOptions) {
46         super(suffix, preRunActions, jtDriverOptions);
47     }
48 
49     @Override
accept(IRNode mainClass, IRNode privateClasses)50     public void accept(IRNode mainClass, IRNode privateClasses) {
51         generateClassFiles(mainClass, privateClasses);
52         generateSeparateJtregHeader(mainClass);
53         compilePrinter();
54         generateGoldenOut(mainClass.getName());
55     }
56 
generateSeparateJtregHeader(IRNode mainClass)57     private void generateSeparateJtregHeader(IRNode mainClass) {
58         String mainClassName = mainClass.getName();
59         writeFile(generatorDir, mainClassName + ".java", getJtregHeader(mainClassName));
60     }
61 
generateClassFiles(IRNode mainClass, IRNode privateClasses)62     private void generateClassFiles(IRNode mainClass, IRNode privateClasses) {
63         String mainClassName = mainClass.getName();
64         ensureExisting(generatorDir);
65         try {
66             ByteCodeVisitor vis = new ByteCodeVisitor();
67             if (privateClasses != null) {
68                 privateClasses.accept(vis);
69             }
70             mainClass.accept(vis);
71             writeFile(mainClassName + ".class", vis.getByteCode(mainClassName));
72             if (privateClasses != null) {
73                 privateClasses.getChildren().forEach(c -> {
74                     String name = c.getName();
75                     writeFile(name + ".class", vis.getByteCode(name));
76                 });
77             }
78         } catch (Throwable t) {
79             Path errFile = generatorDir.resolve(mainClassName + ".err");
80             try (PrintWriter pw = new PrintWriter(Files.newOutputStream(errFile,
81                     StandardOpenOption.CREATE, StandardOpenOption.WRITE))) {
82                 t.printStackTrace(pw);
83             } catch (IOException e) {
84                 t.printStackTrace();
85                 throw new Error("can't write error to error file " + errFile, e);
86             }
87         }
88     }
89 
writeFile(String fileName, byte[] bytecode)90     private void writeFile(String fileName, byte[] bytecode) {
91         try {
92             Files.write(generatorDir.resolve(fileName), bytecode);
93         } catch (IOException ex) {
94             ex.printStackTrace();
95         }
96     }
97 }
98