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.tools.jaotc;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map.Entry;
30
31 import jdk.tools.jaotc.binformat.BinaryContainer;
32 import jdk.tools.jaotc.binformat.ByteContainer;
33 import jdk.tools.jaotc.binformat.HeaderContainer;
34 import jdk.tools.jaotc.utils.Timer;
35 import org.graalvm.compiler.code.CompilationResult;
36 import org.graalvm.compiler.debug.Debug;
37 import org.graalvm.compiler.debug.Debug.Scope;
38 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
39 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
40 import org.graalvm.compiler.hotspot.stubs.Stub;
41
42 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
43 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
44 import jdk.vm.ci.hotspot.VMField;
45
46 class DataBuilder {
47
48 private final Main main;
49
50 private final HotSpotHostBackend backend;
51
52 private final List<AOTCompiledClass> classes;
53
54 /**
55 * Target-independent container in which text symbols and code bytes are created.
56 */
57 private final BinaryContainer binaryContainer;
107 * Returns the host backend used for this compilation.
108 *
109 * @return host backend
110 */
111 public HotSpotHostBackend getBackend() {
112 return backend;
113 }
114
115 /**
116 * Returns the binary container for this compilation.
117 *
118 * @return binary container
119 */
120 public BinaryContainer getBinaryContainer() {
121 return binaryContainer;
122 }
123
124 /**
125 * Prepare data with all compiled classes and stubs.
126 *
127 * @throws Exception
128 */
129 @SuppressWarnings("try")
130 public void prepareData() throws Exception {
131 try (Timer t = new Timer(main, "Parsing compiled code")) {
132 /*
133 * Copy compiled code into code section container and calls stubs (PLT trampoline).
134 */
135 CodeSectionProcessor codeSectionProcessor = new CodeSectionProcessor(this);
136 for (AOTCompiledClass c : classes) {
137 // For each class we need 2 GOT slots:
138 // first - for initialized klass
139 // second - only for loaded klass
140 c.addAOTKlassData(binaryContainer);
141 codeSectionProcessor.process(c);
142 }
143 }
144
145 AOTCompiledClass stubCompiledCode = retrieveStubCode();
146
147 // Free memory!
148 try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
149 main.printMemoryUsage();
150 System.gc();
151 }
152
153 MetadataBuilder metadataBuilder = null;
154 try (Timer t = new Timer(main, "Processing metadata")) {
155 /*
156 * Generate metadata for compiled code and copy it into metadata section. Create
157 * relocation information for all references (call, constants, etc) in compiled code.
158 */
159 metadataBuilder = new MetadataBuilder(this);
160 metadataBuilder.processMetadata(classes, stubCompiledCode);
161 }
162
163 // Free memory!
164 try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
165 main.printMemoryUsage();
166 System.gc();
167 }
168
169 try (Timer t = new Timer(main, "Preparing stubs binary")) {
170 prepareStubsBinary(stubCompiledCode);
171 }
172 try (Timer t = new Timer(main, "Preparing compiled binary")) {
173 // Should be called after Stubs because they can set dependent klasses.
174 prepareCompiledBinary(metadataBuilder);
175 }
176 }
177
178 /**
179 * Get all stubs from Graal and add them to the code section.
180 */
181 @SuppressWarnings("try")
182 private AOTCompiledClass retrieveStubCode() {
183 ArrayList<CompiledMethodInfo> stubs = new ArrayList<>();
184 HotSpotForeignCallsProvider foreignCallsProvider = backend.getProviders().getForeignCalls();
185 for (Stub stub : foreignCallsProvider.getStubs()) {
186 try (Scope scope = Debug.scope("CompileStubs")) {
187 CompilationResult result = stub.getCompilationResult(backend);
188 CompiledMethodInfo cm = new CompiledMethodInfo(result, new AOTStub(stub, backend));
189 stubs.add(cm);
190 } catch (Throwable e) {
191 throw Debug.handle(e);
192 }
193 }
194 AOTCompiledClass stubCompiledCode = new AOTCompiledClass(stubs);
195 CodeSectionProcessor codeSectionProcessor = new CodeSectionProcessor(this);
196 codeSectionProcessor.process(stubCompiledCode);
197 return stubCompiledCode;
198 }
199
200 /**
201 * Prepare metaspace.offsets section.
202 */
203 private void prepareCompiledBinary(MetadataBuilder metadataBuilder) {
204 for (AOTCompiledClass c : classes) {
205 // Create records for compiled AOT methods.
206 c.putMethodsData(binaryContainer);
207 }
208 // Create records for compiled AOT classes.
209 AOTCompiledClass.putAOTKlassData(binaryContainer);
210
211 // Fill in AOTHeader
|
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.tools.jaotc;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map.Entry;
30
31 import jdk.tools.jaotc.binformat.BinaryContainer;
32 import jdk.tools.jaotc.binformat.ByteContainer;
33 import jdk.tools.jaotc.binformat.HeaderContainer;
34 import jdk.tools.jaotc.utils.Timer;
35 import org.graalvm.compiler.code.CompilationResult;
36 import org.graalvm.compiler.debug.DebugContext;
37 import org.graalvm.compiler.hotspot.HotSpotHostBackend;
38 import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
39 import org.graalvm.compiler.hotspot.stubs.Stub;
40
41 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
42 import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
43 import jdk.vm.ci.hotspot.VMField;
44
45 class DataBuilder {
46
47 private final Main main;
48
49 private final HotSpotHostBackend backend;
50
51 private final List<AOTCompiledClass> classes;
52
53 /**
54 * Target-independent container in which text symbols and code bytes are created.
55 */
56 private final BinaryContainer binaryContainer;
106 * Returns the host backend used for this compilation.
107 *
108 * @return host backend
109 */
110 public HotSpotHostBackend getBackend() {
111 return backend;
112 }
113
114 /**
115 * Returns the binary container for this compilation.
116 *
117 * @return binary container
118 */
119 public BinaryContainer getBinaryContainer() {
120 return binaryContainer;
121 }
122
123 /**
124 * Prepare data with all compiled classes and stubs.
125 *
126 * @param debug
127 *
128 * @throws Exception
129 */
130 @SuppressWarnings("try")
131 public void prepareData(DebugContext debug) throws Exception {
132 try (Timer t = new Timer(main, "Parsing compiled code")) {
133 /*
134 * Copy compiled code into code section container and calls stubs (PLT trampoline).
135 */
136 CodeSectionProcessor codeSectionProcessor = new CodeSectionProcessor(this);
137 for (AOTCompiledClass c : classes) {
138 // For each class we need 2 GOT slots:
139 // first - for initialized klass
140 // second - only for loaded klass
141 c.addAOTKlassData(binaryContainer);
142 codeSectionProcessor.process(c);
143 }
144 }
145
146 AOTCompiledClass stubCompiledCode = retrieveStubCode(debug);
147
148 // Free memory!
149 try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
150 main.printMemoryUsage();
151 System.gc();
152 }
153
154 MetadataBuilder metadataBuilder = null;
155 try (Timer t = new Timer(main, "Processing metadata")) {
156 /*
157 * Generate metadata for compiled code and copy it into metadata section. Create
158 * relocation information for all references (call, constants, etc) in compiled code.
159 */
160 metadataBuilder = new MetadataBuilder(this);
161 metadataBuilder.processMetadata(classes, stubCompiledCode);
162 }
163
164 // Free memory!
165 try (Timer t = main.options.verbose ? new Timer(main, "Freeing memory") : null) {
166 main.printMemoryUsage();
167 System.gc();
168 }
169
170 try (Timer t = new Timer(main, "Preparing stubs binary")) {
171 prepareStubsBinary(stubCompiledCode);
172 }
173 try (Timer t = new Timer(main, "Preparing compiled binary")) {
174 // Should be called after Stubs because they can set dependent klasses.
175 prepareCompiledBinary(metadataBuilder);
176 }
177 }
178
179 /**
180 * Get all stubs from Graal and add them to the code section.
181 *
182 * @param debug
183 */
184 @SuppressWarnings("try")
185 private AOTCompiledClass retrieveStubCode(DebugContext debug) {
186 ArrayList<CompiledMethodInfo> stubs = new ArrayList<>();
187 HotSpotForeignCallsProvider foreignCallsProvider = backend.getProviders().getForeignCalls();
188 for (Stub stub : foreignCallsProvider.getStubs()) {
189 try (DebugContext.Scope scope = debug.scope("CompileStubs")) {
190 CompilationResult result = stub.getCompilationResult(debug, backend);
191 CompiledMethodInfo cm = new CompiledMethodInfo(result, new AOTStub(stub, backend));
192 stubs.add(cm);
193 } catch (Throwable e) {
194 throw debug.handle(e);
195 }
196 }
197 AOTCompiledClass stubCompiledCode = new AOTCompiledClass(stubs);
198 CodeSectionProcessor codeSectionProcessor = new CodeSectionProcessor(this);
199 codeSectionProcessor.process(stubCompiledCode);
200 return stubCompiledCode;
201 }
202
203 /**
204 * Prepare metaspace.offsets section.
205 */
206 private void prepareCompiledBinary(MetadataBuilder metadataBuilder) {
207 for (AOTCompiledClass c : classes) {
208 // Create records for compiled AOT methods.
209 c.putMethodsData(binaryContainer);
210 }
211 // Create records for compiled AOT classes.
212 AOTCompiledClass.putAOTKlassData(binaryContainer);
213
214 // Fill in AOTHeader
|