1 /* 2 * Copyright (c) 2011, 2015, 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 package jdk.vm.ci.hotspot; 24 25 import java.nio.*; 26 import java.util.*; 27 import java.util.stream.*; 28 import java.util.stream.Stream.Builder; 29 30 import jdk.vm.ci.code.*; 31 import jdk.vm.ci.code.CompilationResult.CodeAnnotation; 32 import jdk.vm.ci.code.CompilationResult.CodeComment; 33 import jdk.vm.ci.code.CompilationResult.DataPatch; 34 import jdk.vm.ci.code.CompilationResult.ExceptionHandler; 35 import jdk.vm.ci.code.CompilationResult.Infopoint; 36 import jdk.vm.ci.code.CompilationResult.JumpTable; 37 import jdk.vm.ci.code.CompilationResult.Mark; 38 import jdk.vm.ci.code.CompilationResult.Site; 39 import jdk.vm.ci.meta.*; 40 import jdk.vm.ci.meta.Assumptions.Assumption; 41 42 /** 43 * A {@link CompilationResult} with additional HotSpot-specific information required for installing 44 * the code in HotSpot's code cache. 45 */ 46 public abstract class HotSpotCompiledCode { 47 48 public final String name; 49 public final Site[] sites; 50 public final ExceptionHandler[] exceptionHandlers; 51 public final Comment[] comments; 52 public final Assumption[] assumptions; 53 54 public final byte[] targetCode; 55 public final int targetCodeSize; 56 57 public final byte[] dataSection; 58 public final int dataSectionAlignment; 59 public final DataPatch[] dataSectionPatches; 60 public final boolean isImmutablePIC; 61 62 public final int totalFrameSize; 63 public final int customStackAreaOffset; 64 65 /** 66 * The list of the methods whose bytecodes were used as input to the compilation. If 67 * {@code null}, then the compilation did not record method dependencies. Otherwise, the first 68 * element of this array is the root method of the compilation. 69 */ 70 public final ResolvedJavaMethod[] methods; 71 72 public static class Comment { 73 74 public final String text; 75 public final int pcOffset; 76 77 public Comment(int pcOffset, String text) { 78 this.text = text; 79 this.pcOffset = pcOffset; 80 } 81 } 82 83 public HotSpotCompiledCode(CompilationResult compResult) { 84 name = compResult.getName(); 85 sites = getSortedSites(compResult); 86 if (compResult.getExceptionHandlers().isEmpty()) { 87 exceptionHandlers = null; 88 } else { 89 exceptionHandlers = compResult.getExceptionHandlers().toArray(new ExceptionHandler[compResult.getExceptionHandlers().size()]); 90 } 91 List<CodeAnnotation> annotations = compResult.getAnnotations(); 92 comments = new Comment[annotations.size()]; 93 if (!annotations.isEmpty()) { 94 for (int i = 0; i < comments.length; i++) { 95 CodeAnnotation annotation = annotations.get(i); 96 String text; 97 if (annotation instanceof CodeComment) { 98 CodeComment codeComment = (CodeComment) annotation; 99 text = codeComment.value; 100 } else if (annotation instanceof JumpTable) { 101 JumpTable jumpTable = (JumpTable) annotation; 102 text = "JumpTable [" + jumpTable.low + " .. " + jumpTable.high + "]"; 103 } else { 104 text = annotation.toString(); 105 } 106 comments[i] = new Comment(annotation.position, text); 107 } 108 } 109 assumptions = compResult.getAssumptions(); 110 assert validateFrames(); 111 112 targetCode = compResult.getTargetCode(); 113 targetCodeSize = compResult.getTargetCodeSize(); 114 115 DataSection data = compResult.getDataSection(); 116 if (!data.isFinalized()) { 117 data.finalizeLayout(); 118 } 119 dataSection = new byte[data.getSectionSize()]; 120 121 ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder()); 122 Builder<DataPatch> patchBuilder = Stream.builder(); 123 data.buildDataSection(buffer, patchBuilder); 124 125 dataSectionAlignment = data.getSectionAlignment(); 126 dataSectionPatches = patchBuilder.build().toArray(len -> new DataPatch[len]); 127 128 isImmutablePIC = compResult.isImmutablePIC(); 129 130 totalFrameSize = compResult.getTotalFrameSize(); 131 customStackAreaOffset = compResult.getCustomStackAreaOffset(); 132 133 methods = compResult.getMethods(); 134 } 135 136 /** 137 * Ensure that all the frames passed into HotSpot are properly formatted with an empty or 138 * illegal slot following double word slots. 139 */ 140 private boolean validateFrames() { 141 for (Site site : sites) { 142 if (site instanceof Infopoint) { 143 Infopoint info = (Infopoint) site; 144 if (info.debugInfo != null) { 145 BytecodeFrame frame = info.debugInfo.frame(); 146 assert frame == null || frame.validateFormat(); 147 } 148 } 149 } 150 return true; 151 } 152 153 static class SiteComparator implements Comparator<Site> { 154 155 public int compare(Site s1, Site s2) { 156 if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) { 157 return s1 instanceof Mark ? -1 : 1; 158 } 159 return s1.pcOffset - s2.pcOffset; 160 } 161 } 162 163 private static Site[] getSortedSites(CompilationResult target) { 164 List<?>[] lists = new List<?>[]{target.getInfopoints(), target.getDataPatches(), target.getMarks()}; 165 int count = 0; 166 for (List<?> list : lists) { 167 count += list.size(); 168 } 169 Site[] result = new Site[count]; 170 int pos = 0; 171 for (List<?> list : lists) { 172 for (Object elem : list) { 173 result[pos++] = (Site) elem; 174 } 175 } 176 Arrays.sort(result, new SiteComparator()); 177 return result; 178 } 179 }