changeset 23674:09a536b9233c

8158850: [JVMCI] be more precise when enforcing OopMapValue encoding limitations
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 09 Jun 2016 18:45:12 -0700
parents 7ef84c807bfe
children 28dbeb87ec75
files jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java src/share/vm/jvmci/jvmciCodeInstaller.cpp src/share/vm/jvmci/jvmciRuntime.cpp src/share/vm/jvmci/jvmciRuntime.hpp
diffstat 6 files changed, 28 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Tue Jun 07 17:45:03 2016 -0700
+++ b/jvmci/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Thu Jun 09 18:45:12 2016 -0700
@@ -81,8 +81,6 @@
 
     private final Register[] allocatable;
 
-    private final int maxFrameSize;
-
     /**
      * The caller saved registers always include all parameter registers.
      */
@@ -92,10 +90,6 @@
 
     private final RegisterAttributes[] attributesMap;
 
-    public int getMaximumFrameSize() {
-        return maxFrameSize;
-    }
-
     @Override
     public Register[] getAllocatableRegisters() {
         return allocatable.clone();
@@ -161,13 +155,12 @@
     }
 
     public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
-        this(target, config, initAllocatable(target.arch, config.useCompressedOops));
+        this(target, initAllocatable(target.arch, config.useCompressedOops));
         assert callerSaved.length >= allocatable.length;
     }
 
-    public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
+    public AArch64HotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
         this.target = target;
-        this.maxFrameSize = config.maxFrameSize;
 
         this.allocatable = allocatable.clone();
         Set<Register> callerSaveSet = new HashSet<>();
--- a/jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Tue Jun 07 17:45:03 2016 -0700
+++ b/jvmci/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Thu Jun 09 18:45:12 2016 -0700
@@ -73,8 +73,6 @@
 
     private final Register[] allocatable;
 
-    private final int maxFrameSize;
-
     /**
      * The caller saved registers always include all parameter registers.
      */
@@ -84,10 +82,6 @@
 
     private final RegisterAttributes[] attributesMap;
 
-    public int getMaximumFrameSize() {
-        return maxFrameSize;
-    }
-
     @Override
     public Register[] getAllocatableRegisters() {
         return allocatable.clone();
@@ -153,7 +147,6 @@
 
     public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
         this.target = target;
-        this.maxFrameSize = config.maxFrameSize;
 
         if (config.windowsOs) {
             javaGeneralParameterRegisters = new Register[]{rdx, r8, r9, rdi, rsi, rcx};
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Tue Jun 07 17:45:03 2016 -0700
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Thu Jun 09 18:45:12 2016 -0700
@@ -71,11 +71,6 @@
         return runtime().getConfig();
     }
 
-    /**
-     * Maximum allowed size of allocated area for a frame.
-     */
-    public final int maxFrameSize = 16 * 1024;
-
     @Override
     public String toString() {
         return getClass().getSimpleName();
@@ -1293,6 +1288,12 @@
     @HotSpotVMConstant(name = "JVMCIRuntime::by_holder") @Stable public int compLevelAdjustmentByHolder;
     @HotSpotVMConstant(name = "JVMCIRuntime::by_full_signature") @Stable public int compLevelAdjustmentByFullSignature;
 
+    /**
+     * This is the largest stack offset encodeable in an OopMapValue. Offsets larger than this will
+     * throw an exception during code installation.
+     */
+    @HotSpotVMValue(expression = "JVMCIRuntime::max_oop_map_stack_offset") @Stable public int maxOopMapStackOffset;
+
     @HotSpotVMType(name = "BasicLock", get = HotSpotVMType.Type.SIZE) @Stable public int basicLockSize;
     @HotSpotVMField(name = "BasicLock::_displaced_header", type = "markOop", get = HotSpotVMField.Type.OFFSET) @Stable public int basicLockDisplacedHeaderOffset;
 
--- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Tue Jun 07 17:45:03 2016 -0700
+++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Thu Jun 09 18:45:12 2016 -0700
@@ -85,7 +85,19 @@
   } else {
     // stack slot
     if (offset % 4 == 0) {
-      return VMRegImpl::stack2reg(offset / 4);
+      VMReg vmReg = VMRegImpl::stack2reg(offset / 4);
+      if (!OopMapValue::legal_vm_reg_name(vmReg)) {
+        // This restriction only applies to VMRegs that are used in OopMap but
+        // since that's the only use of VMRegs it's simplest to put this test
+        // here.  This test should also be equivalent legal_vm_reg_name but JVMCI
+        // clients can use max_oop_map_stack_stack_offset to detect this problem
+        // directly.  The asserts just ensure that the tests are in agreement.
+        assert(offset > JVMCIRuntime::max_oop_map_stack_offset, "illegal VMReg");
+        JVMCI_ERROR_NULL("stack offset %d is too large to be encoded in OopMap (max %d)",
+                         offset, JVMCIRuntime::max_oop_map_stack_offset);
+      }
+      assert(OopMapValue::legal_vm_reg_name(vmReg), "illegal VMReg");
+      return vmReg;
     } else {
       JVMCI_ERROR_NULL("unaligned stack offset %d in oop map", offset);
     }
--- a/src/share/vm/jvmci/jvmciRuntime.cpp	Tue Jun 07 17:45:03 2016 -0700
+++ b/src/share/vm/jvmci/jvmciRuntime.cpp	Thu Jun 09 18:45:12 2016 -0700
@@ -51,6 +51,7 @@
 char** JVMCIRuntime::_trivial_prefixes = NULL;
 JVMCIRuntime::CompLevelAdjustment JVMCIRuntime::_comp_level_adjustment = JVMCIRuntime::none;
 bool JVMCIRuntime::_shutdown_called = false;
+int JVMCIRuntime::max_oop_map_stack_offset = (OopMapValue::register_mask - VMRegImpl::stack2reg(0)->value()) * VMRegImpl::stack_slot_size;
 
 BasicType JVMCIRuntime::kindToBasicType(jchar ch, TRAPS) {
   switch(ch) {
@@ -646,6 +647,10 @@
            "HotSpotJVMCIRuntime initialization should only be triggered through JVMCI initialization");
 #endif
 
+    int max_oop_map_stack_index = max_oop_map_stack_offset / VMRegImpl::stack_slot_size;
+    assert(OopMapValue::legal_vm_reg_name(VMRegImpl::stack2reg(max_oop_map_stack_index)), "should be valid");
+    assert(!OopMapValue::legal_vm_reg_name(VMRegImpl::stack2reg(max_oop_map_stack_index + 1)), "should be invalid");
+
     Handle result = callStatic("jdk/vm/ci/hotspot/HotSpotJVMCIRuntime",
                                "runtime",
                                "()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;", NULL, CHECK);
--- a/src/share/vm/jvmci/jvmciRuntime.hpp	Tue Jun 07 17:45:03 2016 -0700
+++ b/src/share/vm/jvmci/jvmciRuntime.hpp	Thu Jun 09 18:45:12 2016 -0700
@@ -78,6 +78,8 @@
      by_full_signature = 2 // adjust based on declaring class, name and signature of method
    };
 
+  static int max_oop_map_stack_offset;
+
  private:
   static jobject _HotSpotJVMCIRuntime_instance;
   static bool _HotSpotJVMCIRuntime_initialized;