src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java
Index Unified diffs Context diffs Sdiffs Frames Patch New Old Previous File Next File hotspot Sdiff src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc

src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java

Print this page


   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.tools.jaotc;
  25 
  26 import java.util.concurrent.atomic.AtomicInteger;
  27 import java.util.HashMap;
  28 import java.util.Map;
  29 
  30 import jdk.tools.jaotc.binformat.BinaryContainer;
  31 import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
  32 import jdk.tools.jaotc.AOTCompiledClass.AOTKlassData;
  33 import org.graalvm.compiler.code.CompilationResult;
  34 
  35 import jdk.vm.ci.code.site.Mark;
  36 import jdk.vm.ci.code.site.Site;
  37 import jdk.vm.ci.hotspot.HotSpotCompiledCode;
  38 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
  39 
  40 public class CompiledMethodInfo {
  41 
  42     public static class StubInformation {
  43         int stubOffset;         // the offset inside the code (text + stubOffset)
  44         int stubSize;           // the stub size
  45         int dispatchJumpOffset; // offset after main dispatch jump instruction
  46         int resolveJumpOffset;  // offset after jump instruction to runtime call resolution
  47                                // function.
  48         int resolveJumpStart;   // offset of jump instruction to VM runtime call resolution
  49                               // function.
  50         int c2iJumpOffset;      // offset after jump instruction to c2i adapter for static calls.
  51         int movOffset; // offset after move instruction which loads from got cell:
  52                        // - Method* for static call
  53                        // - Klass* for virtual call
  54 
  55         boolean isVirtual;  // virtual call stub
  56 
  57         // maybe add type of stub as well, right now we only have static stubs
  58 
  59         public StubInformation(int stubOffset, boolean isVirtual) {
  60             this.stubOffset = stubOffset;
  61             this.isVirtual = isVirtual;
  62             this.stubSize = -1;
  63             this.movOffset = -1;
  64             this.c2iJumpOffset = -1;
  65             this.resolveJumpOffset = -1;
  66             this.resolveJumpStart = -1;
  67             this.dispatchJumpOffset = -1;
  68         }
  69 
  70         public int getOffset() {
  71             return stubOffset;
  72         }
  73 
  74         public boolean isVirtual() {
  75             return isVirtual;
  76         }
  77 
  78         public void setSize(int stubSize) {
  79             this.stubSize = stubSize;
  80         }
  81 
  82         public int getSize() {
  83             return stubSize;
  84         }
  85 
  86         public void setMovOffset(int movOffset) {
  87             this.movOffset = movOffset + stubOffset;
  88         }
  89 
  90         public int getMovOffset() {
  91             return movOffset;
  92         }
  93 
  94         public void setC2IJumpOffset(int c2iJumpOffset) {
  95             this.c2iJumpOffset = c2iJumpOffset + stubOffset;
  96         }
  97 
  98         public int getC2IJumpOffset() {
  99             return c2iJumpOffset;
 100         }
 101 
 102         public void setResolveJumpOffset(int resolveJumpOffset) {
 103             this.resolveJumpOffset = resolveJumpOffset + stubOffset;
 104         }
 105 
 106         public int getResolveJumpOffset() {
 107             return resolveJumpOffset;
 108         }
 109 
 110         public void setResolveJumpStart(int resolveJumpStart) {
 111             this.resolveJumpStart = resolveJumpStart + stubOffset;
 112         }
 113 
 114         public int getResolveJumpStart() {
 115             return resolveJumpStart;
 116         }
 117 
 118         public void setDispatchJumpOffset(int dispatchJumpOffset) {
 119             this.dispatchJumpOffset = dispatchJumpOffset + stubOffset;
 120         }
 121 
 122         public int getDispatchJumpOffset() {
 123             return dispatchJumpOffset;
 124         }
 125 
 126         public void verify() {
 127             assert stubOffset > 0 : "incorrect stubOffset: " + stubOffset;
 128             assert stubSize > 0 : "incorrect stubSize: " + stubSize;
 129             assert movOffset > 0 : "incorrect movOffset: " + movOffset;
 130             assert dispatchJumpOffset > 0 : "incorrect dispatchJumpOffset: " + dispatchJumpOffset;
 131             assert resolveJumpStart > 0 : "incorrect resolveJumpStart: " + resolveJumpStart;
 132             assert resolveJumpOffset > 0 : "incorrect resolveJumpOffset: " + resolveJumpOffset;
 133             if (!isVirtual) {
 134                 assert c2iJumpOffset > 0 : "incorrect c2iJumpOffset: " + c2iJumpOffset;
 135             }
 136         }
 137     }
 138 
 139     private static final int UNINITIALIZED_OFFSET = -1;
 140 
 141     private static class AOTMethodOffsets {
 142         /**
 143          * Offset in metaspace names section.
 144          */
 145         private int nameOffset;
 146 
 147         /**
 148          * Offset in the text section at which compiled code starts.
 149          */
 150         private int textSectionOffset;
 151 
 152         /**
 153          * Offset in the metadata section.
 154          */
 155         private int metadataOffset;
 156 
 157         /**
 158          * Offset to the metadata in the GOT table.
 159          */
 160         private int metadataGotOffset;
 161 
 162         /**
 163          * Size of the metadata.
 164          */
 165         private int metadataGotSize;
 166 
 167         /**
 168          * The sequential number corresponding to the order of methods code in code buffer.
 169          */
 170         private int codeId;
 171 
 172         public AOTMethodOffsets() {
 173             this.nameOffset = UNINITIALIZED_OFFSET;
 174             this.textSectionOffset = UNINITIALIZED_OFFSET;
 175             this.metadataOffset = UNINITIALIZED_OFFSET;
 176             this.metadataGotOffset = UNINITIALIZED_OFFSET;
 177             this.metadataGotSize = -1;
 178             this.codeId = -1;
 179         }
 180 
 181         protected void addMethodOffsets(ReadOnlyDataContainer container, String name) {
 182             verify(name);
 183             // @formatter:off
 184             /*
 185              * The offsets layout should match AOTMethodOffsets structure in AOT JVM runtime
 186              */
 187                       // Add the offset to the name in the .metaspace.names section
 188             container.appendInt(nameOffset).
 189                       // Add the offset to the code in the .text section
 190                       appendInt(textSectionOffset).
 191                       // Add the offset to the metadata in the .method.metadata section
 192                       appendInt(metadataOffset).
 193                       // Add the offset to the metadata in the .metadata.got section
 194                       appendInt(metadataGotOffset).
 195                       // Add the size of the metadata
 196                       appendInt(metadataGotSize).
 197                       // Add code ID.
 198                       appendInt(codeId);
 199             // @formatter:on
 200         }
 201 


 274     /**
 275      * Method's offsets.
 276      */
 277     private AOTMethodOffsets methodOffsets;
 278 
 279     /**
 280      * List of stubs (PLT trampoline).
 281      */
 282     private Map<String, StubInformation> stubs = new HashMap<>();
 283 
 284     /**
 285      * List of referenced classes.
 286      */
 287     private Map<String, AOTKlassData> dependentKlasses = new HashMap<>();
 288 
 289     /**
 290      * Methods count used to generate unique global method id.
 291      */
 292     private static final AtomicInteger methodsCount = new AtomicInteger();
 293 
 294     public CompiledMethodInfo(CompilationResult compilationResult, JavaMethodInfo methodInfo) {
 295         this.name = methodInfo.getNameAndSignature();
 296         this.compilationResult = compilationResult;
 297         this.methodInfo = methodInfo;
 298         this.stubsOffset = UNINITIALIZED_OFFSET;
 299         this.methodOffsets = new AOTMethodOffsets();
 300     }
 301 
 302     public String name() {
 303         return name;
 304     }
 305 
 306     public void addMethodOffsets(BinaryContainer binaryContainer, ReadOnlyDataContainer container) {
 307         this.methodOffsets.setNameOffset(binaryContainer.addMetaspaceName(name));
 308         this.methodOffsets.addMethodOffsets(container, name);
 309         for (AOTKlassData data : dependentKlasses.values()) {
 310             data.addDependentMethod(this);
 311         }
 312     }
 313 
 314     public CompilationResult getCompilationResult() {
 315         return compilationResult;
 316     }
 317 
 318     public JavaMethodInfo getMethodInfo() {
 319         return methodInfo;
 320     }
 321 
 322     public void setTextSectionOffset(int textSectionOffset) {
 323         methodOffsets.setTextSectionOffset(textSectionOffset);
 324     }
 325 
 326     public int getTextSectionOffset() {
 327         return methodOffsets.getTextSectionOffset();
 328     }
 329 
 330     public void setCodeId() {
 331         methodOffsets.setCodeId(CompiledMethodInfo.getNextCodeId());
 332     }
 333 
 334     public int getCodeId() {
 335         return this.methodOffsets.getCodeId();
 336     }
 337 
 338     public static int getMethodsCount() {
 339         return methodsCount.get();
 340     }
 341 
 342     public static int getNextCodeId() {
 343         return methodsCount.getAndIncrement();
 344     }
 345 
 346     public int getCodeSize() {
 347         return stubsOffset + getStubCodeSize();
 348     }
 349 
 350     public int getStubCodeSize() {
 351         return totalStubSize;
 352     }
 353 
 354     public void setMetadataOffset(int offset) {
 355         this.methodOffsets.setMetadataOffset(offset);
 356     }
 357 
 358     /**
 359      * Offset into the code of this method where the stub section starts.
 360      */
 361     public void setStubsOffset(int offset) {
 362         stubsOffset = offset;
 363     }
 364 
 365     public int getStubsOffset() {
 366         return stubsOffset;
 367     }
 368 
 369     public void setMetadataGotOffset(int metadataGotOffset) {
 370         this.methodOffsets.setMetadataGotOffset(metadataGotOffset);
 371     }
 372 
 373     public void setMetadataGotSize(int length) {
 374         this.methodOffsets.setMetadataGotSize(length);
 375     }
 376 
 377     public void addStubCode(String call, StubInformation stub) {
 378         stubs.put(call, stub);
 379         totalStubSize += stub.getSize();
 380     }
 381 
 382     public StubInformation getStubFor(String call) {
 383         StubInformation stub = stubs.get(call);
 384         assert stub != null : "missing stub for call " + call;
 385         stub.verify();
 386         return stub;
 387     }
 388 
 389     public void addDependentKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
 390         AOTKlassData klassData = AOTCompiledClass.addFingerprintKlassData(binaryContainer, type);
 391         String klassName = type.getName();
 392 
 393         if (dependentKlasses.containsKey(klassName)) {
 394             assert dependentKlasses.get(klassName) == klassData : "duplicated data for klass: " + klassName;
 395         } else {
 396             dependentKlasses.put(klassName, klassData);
 397         }
 398     }
 399 
 400     public AOTKlassData getDependentKlassData(String klassName) {
 401         return dependentKlasses.get(klassName);
 402     }
 403 
 404     public boolean hasMark(Site call, MarkId id) {
 405         for (Mark m : compilationResult.getMarks()) {
 406             // TODO: X64-specific code.
 407             // Call instructions are aligned to 8
 408             // bytes - 1 on x86 to patch address atomically,
 409             int adjOffset = (m.pcOffset & (-8)) + 7;
 410             // Mark points before aligning nops.
 411             if ((call.pcOffset == adjOffset) && MarkId.getEnum((int) m.id) == id) {
 412                 return true;
 413             }
 414         }
 415         return false;
 416     }
 417 
 418     public String asTag() {
 419         return "[" + methodInfo.getSymbolName() + "]";
 420     }
 421 
 422     public HotSpotCompiledCode compiledCode() {
 423         if (code == null) {
 424             code = methodInfo.compiledCode(compilationResult);
 425         }
 426         return code;
 427     }
 428 
 429     // Free memory
 430     public void clear() {
 431         this.dependentKlasses = null;
 432         this.name = null;
 433     }
 434 
 435     public void clearCompileData() {
 436         this.code = null;
 437         this.stubs = null;
 438         this.compilationResult = null;
 439         this.methodInfo = null;
 440     }
 441 }
   1 /*
   2  * Copyright (c) 2016, 2017, 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.tools.jaotc;
  25 
  26 import java.util.concurrent.atomic.AtomicInteger;
  27 import java.util.HashMap;
  28 import java.util.Map;
  29 
  30 import jdk.tools.jaotc.binformat.BinaryContainer;
  31 import jdk.tools.jaotc.binformat.ReadOnlyDataContainer;
  32 import jdk.tools.jaotc.AOTCompiledClass.AOTKlassData;
  33 import org.graalvm.compiler.code.CompilationResult;
  34 
  35 import jdk.vm.ci.code.site.Mark;
  36 import jdk.vm.ci.code.site.Site;
  37 import jdk.vm.ci.hotspot.HotSpotCompiledCode;
  38 import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
  39 
  40 final class CompiledMethodInfo {

































































































  41 
  42     private static final int UNINITIALIZED_OFFSET = -1;
  43 
  44     private static class AOTMethodOffsets {
  45         /**
  46          * Offset in metaspace names section.
  47          */
  48         private int nameOffset;
  49 
  50         /**
  51          * Offset in the text section at which compiled code starts.
  52          */
  53         private int textSectionOffset;
  54 
  55         /**
  56          * Offset in the metadata section.
  57          */
  58         private int metadataOffset;
  59 
  60         /**
  61          * Offset to the metadata in the GOT table.
  62          */
  63         private int metadataGotOffset;
  64 
  65         /**
  66          * Size of the metadata.
  67          */
  68         private int metadataGotSize;
  69 
  70         /**
  71          * The sequential number corresponding to the order of methods code in code buffer.
  72          */
  73         private int codeId;
  74 
  75         AOTMethodOffsets() {
  76             this.nameOffset = UNINITIALIZED_OFFSET;
  77             this.textSectionOffset = UNINITIALIZED_OFFSET;
  78             this.metadataOffset = UNINITIALIZED_OFFSET;
  79             this.metadataGotOffset = UNINITIALIZED_OFFSET;
  80             this.metadataGotSize = -1;
  81             this.codeId = -1;
  82         }
  83 
  84         void addMethodOffsets(ReadOnlyDataContainer container, String name) {
  85             verify(name);
  86             // @formatter:off
  87             /*
  88              * The offsets layout should match AOTMethodOffsets structure in AOT JVM runtime
  89              */
  90                       // Add the offset to the name in the .metaspace.names section
  91             container.appendInt(nameOffset).
  92                       // Add the offset to the code in the .text section
  93                       appendInt(textSectionOffset).
  94                       // Add the offset to the metadata in the .method.metadata section
  95                       appendInt(metadataOffset).
  96                       // Add the offset to the metadata in the .metadata.got section
  97                       appendInt(metadataGotOffset).
  98                       // Add the size of the metadata
  99                       appendInt(metadataGotSize).
 100                       // Add code ID.
 101                       appendInt(codeId);
 102             // @formatter:on
 103         }
 104 


 177     /**
 178      * Method's offsets.
 179      */
 180     private AOTMethodOffsets methodOffsets;
 181 
 182     /**
 183      * List of stubs (PLT trampoline).
 184      */
 185     private Map<String, StubInformation> stubs = new HashMap<>();
 186 
 187     /**
 188      * List of referenced classes.
 189      */
 190     private Map<String, AOTKlassData> dependentKlasses = new HashMap<>();
 191 
 192     /**
 193      * Methods count used to generate unique global method id.
 194      */
 195     private static final AtomicInteger methodsCount = new AtomicInteger();
 196 
 197     CompiledMethodInfo(CompilationResult compilationResult, JavaMethodInfo methodInfo) {
 198         this.name = methodInfo.getNameAndSignature();
 199         this.compilationResult = compilationResult;
 200         this.methodInfo = methodInfo;
 201         this.stubsOffset = UNINITIALIZED_OFFSET;
 202         this.methodOffsets = new AOTMethodOffsets();
 203     }
 204 
 205     String name() {
 206         return name;
 207     }
 208 
 209     void addMethodOffsets(BinaryContainer binaryContainer, ReadOnlyDataContainer container) {
 210         this.methodOffsets.setNameOffset(binaryContainer.addMetaspaceName(name));
 211         this.methodOffsets.addMethodOffsets(container, name);
 212         for (AOTKlassData data : dependentKlasses.values()) {
 213             data.addDependentMethod(this);
 214         }
 215     }
 216 
 217     CompilationResult getCompilationResult() {
 218         return compilationResult;
 219     }
 220 
 221     JavaMethodInfo getMethodInfo() {
 222         return methodInfo;
 223     }
 224 
 225     void setTextSectionOffset(int textSectionOffset) {
 226         methodOffsets.setTextSectionOffset(textSectionOffset);
 227     }
 228 
 229     public int getTextSectionOffset() {
 230         return methodOffsets.getTextSectionOffset();
 231     }
 232 
 233     void setCodeId() {
 234         methodOffsets.setCodeId(CompiledMethodInfo.getNextCodeId());
 235     }
 236 
 237     int getCodeId() {
 238         return this.methodOffsets.getCodeId();
 239     }
 240 
 241     static int getMethodsCount() {
 242         return methodsCount.get();
 243     }
 244 
 245     static int getNextCodeId() {
 246         return methodsCount.getAndIncrement();
 247     }
 248 
 249     int getCodeSize() {
 250         return stubsOffset + getStubCodeSize();
 251     }
 252 
 253     int getStubCodeSize() {
 254         return totalStubSize;
 255     }
 256 
 257     void setMetadataOffset(int offset) {
 258         this.methodOffsets.setMetadataOffset(offset);
 259     }
 260 
 261     /**
 262      * Offset into the code of this method where the stub section starts.
 263      */
 264     void setStubsOffset(int offset) {
 265         stubsOffset = offset;
 266     }
 267 
 268     int getStubsOffset() {
 269         return stubsOffset;
 270     }
 271 
 272     void setMetadataGotOffset(int metadataGotOffset) {
 273         this.methodOffsets.setMetadataGotOffset(metadataGotOffset);
 274     }
 275 
 276     void setMetadataGotSize(int length) {
 277         this.methodOffsets.setMetadataGotSize(length);
 278     }
 279 
 280     void addStubCode(String call, StubInformation stub) {
 281         stubs.put(call, stub);
 282         totalStubSize += stub.getSize();
 283     }
 284 
 285     StubInformation getStubFor(String call) {
 286         StubInformation stub = stubs.get(call);
 287         assert stub != null : "missing stub for call " + call;
 288         stub.verify();
 289         return stub;
 290     }
 291 
 292     void addDependentKlassData(BinaryContainer binaryContainer, HotSpotResolvedObjectType type) {
 293         AOTKlassData klassData = AOTCompiledClass.addFingerprintKlassData(binaryContainer, type);
 294         String klassName = type.getName();
 295 
 296         if (dependentKlasses.containsKey(klassName)) {
 297             assert dependentKlasses.get(klassName) == klassData : "duplicated data for klass: " + klassName;
 298         } else {
 299             dependentKlasses.put(klassName, klassData);
 300         }
 301     }
 302 
 303     AOTKlassData getDependentKlassData(String klassName) {
 304         return dependentKlasses.get(klassName);
 305     }
 306 
 307     boolean hasMark(Site call, MarkId id) {
 308         for (Mark m : compilationResult.getMarks()) {
 309             // TODO: X64-specific code.
 310             // Call instructions are aligned to 8
 311             // bytes - 1 on x86 to patch address atomically,
 312             int adjOffset = (m.pcOffset & (-8)) + 7;
 313             // Mark points before aligning nops.
 314             if ((call.pcOffset == adjOffset) && MarkId.getEnum((int) m.id) == id) {
 315                 return true;
 316             }
 317         }
 318         return false;
 319     }
 320 
 321     String asTag() {
 322         return "[" + methodInfo.getSymbolName() + "]";
 323     }
 324 
 325     HotSpotCompiledCode compiledCode() {
 326         if (code == null) {
 327             code = methodInfo.compiledCode(compilationResult);
 328         }
 329         return code;
 330     }
 331 
 332     // Free memory
 333     void clear() {
 334         this.dependentKlasses = null;
 335         this.name = null;
 336     }
 337 
 338     void clearCompileData() {
 339         this.code = null;
 340         this.stubs = null;
 341         this.compilationResult = null;
 342         this.methodInfo = null;
 343     }
 344 }
src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/CompiledMethodInfo.java
Index Unified diffs Context diffs Sdiffs Frames Patch New Old Previous File Next File