Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8312495

assert(0 <= i && i < _len) failed: illegal index after JDK-8287061 on big endian platforms

XMLWordPrintable

    • b07
    • 22
    • b09

      After JDK-8287061 the following assertion fails on big endian platforms (AIX, s390, Linux/PPC64be).

      assert(0 <= i && i < _len) failed: illegal index at growableArray.hpp:145

      Stack:

      Stack: [0x00000fff6ac00000,0x00000fff6ae00000], sp=0x00000fff6adfc280, free space=2032k
      Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
      V [libjvm.so+0xde9a10] GrowableArrayView<ScopeValue*>::at(int)+0x84 (growableArray.hpp:145)
      V [libjvm.so+0x109fbd0] ObjectMergeValue::select(frame&, RegisterMap&)+0x1dc (debugInfo.cpp:263)
      V [libjvm.so+0x1b7e374] ScopeDesc::objects_to_rematerialize(frame&, RegisterMap&)+0x224 (scopeDesc.cpp:150)
      V [libjvm.so+0x10d6694] rematerialize_objects(JavaThread*, int, CompiledMethod*, frame&, RegisterMap&, GrowableArray<compiledVFrame*>*, bool&)+0x1b8 (deoptimization.cpp:333)
      V [libjvm.so+0x10d7924] Deoptimization::fetch_unroll_info_helper(JavaThread*, int)+0x56c (deoptimization.cpp:523)
      V [libjvm.so+0x10dfb24] Deoptimization::uncommon_trap(JavaThread*, int, int)+0x64 (deoptimization.cpp:2572)
      v ~UncommonTrapBlob 0x00000fff8beca2f4
      J 1520 c2 vm.mlvm.meth.share.transform.v2.MHCall.check()V (97 bytes) @ 0x00000fff8c63ed58 [0x00000fff8c63e900+0x0000000000000458]
      j vm.mlvm.meth.share.transform.v2.MHPrimitiveTF.computeInboundCall()Lvm/mlvm/meth/share/transform/v2/MHCall;+26
      J 1392 c1 vm.mlvm.meth.share.transform.v2.MHMacroTF.addTransformation(Lvm/mlvm/meth/share/transform/v2/MHTF;)Lvm/mlvm/meth/share/transform/v2/MHCall; (95 bytes) @ 0x00000fff84bb96b4 [0x00000fff84bb9080+0x0000000000000634]
      j vm.mlvm.meth.share.MHTransformationGen.createSequence(Lvm/mlvm/meth/share/Argument;Ljava/lang/Object;Ljava/lang/invoke/MethodHandle;[Lvm/mlvm/meth/share/Argument;)Lvm/mlvm/meth/share/transform/v2/MHMacroTF;+66
      j vm.mlvm.meth.stress.compiler.sequences.Test.runThread(I)Z+34

      The illegal index is always -559030609 (0xDEADDEAF)

      vmTestbase/vm/mlvm/meth/stress/compiler/sequences/Test.java
      vmTestbase/jit/escape/AdaptiveBlocking/AdaptiveBlocking001/AdaptiveBlocking001.java
      are 2 tests that are prone to the assertion failure.

      Analysis:

      At https://github.com/openjdk/jdk/blob/master/src/hotspot/share/runtime/stackValue.cpp#L208-L213
      the jint value is always put in the part with the lower address of the intptr_t value. On big endian platforms thats the location of the high word therefore the value cannot be cast directly back to jint.
      Instead workarounds like these are needed:

      https://github.com/openjdk/jdk/blob/8d29329138d44800ee4c0c02dacc01a06097de66/src/hotspot/share/runtime/deoptimization.cpp#L1358-L1391
      https://github.com/openjdk/jdk/blob/8d29329138d44800ee4c0c02dacc01a06097de66/src/hotspot/share/runtime/deoptimization.cpp#L1489-L1519

      I wonder if this is needed at all or if we could just do this instead:
      return UCONST64(0xDEADDEAF00000000) | *(juint*)value_addr

      EDIT: yes it is indeed needed but only on big endian. The size of a stack slot is sizeof(intptr_t). On big endian it depends on the type of an integer value where in the slot it is stored (at lower or higher address). Therefore reading the complete intptr_t and then casting it to jint does not work.

      Details:

      - Let intptr_t* S be the address of a stack slot

      - When accessing S, interpreter and compiled code use load/store instructions matching the size of the integer value to be transferred.

      - E.g. to access a jint in S, 32bit load/store instructions are used. Thats very much like casting S to jint*

      - (jint)*(intptr_t*)S does not work on big endian because the jint part is in the high word of *(intptr_t*)S

      - StackValue has to mimic this to be able to transfer the complete intptr_t value. E.g. `interpretedVFrame::set_locals`[1] transfers stack slot values without knowing if the value is a jint or jlong.

      [1] https://github.com/openjdk/jdk/blob/842d6329cf5a3da8df7eddb195b5fcb7baadbdc3/src/hotspot/share/runtime/vframe.cpp#L456

            rrich Richard Reingruber
            rrich Richard Reingruber
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: