JDK-8158318 : JVM on PPC64 LE crashes due to an illegal instruction in JITed code
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u91,9
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: ppc
  • Submitted: 2016-06-01
  • Updated: 2016-06-01
  • Resolved: 2016-06-01
Related Reports
Duplicate :  
Description
[from http://mail.openjdk.java.net/pipermail/ppc-aix-port-dev/2016-May/002534.html]

The following test case has been isolated by Hiroshi Horii and generates
the illegal instruction, crashing the JVM on PPC64 LE:

UnalignedUnsafeAccess.java:
http://hastebin.com/raw/uqegukific

$ javac UnalignedUnsafeAccess.java
$ java -Xcomp -Xbatch UnalignedUnsafeAccess

The issue can be reproduced on OpenJDK 8 downstream, OpenJDK 8, and
OpenJDK 9 - hs_err logs:

OpenJDK 9, tag 0be6f4f5d186 jdk-9+120:
http://hastebin.com/raw/ecuhukutur

OpenJDK 8, tag 5aaa43d91c73 tip:
http://hastebin.com/raw/ipohoyafos

OpenJDK 8 downstream:

Ubuntu 16.04 LTS
build 1.8.0_91-8u91-b14-0ubuntu4~16.04.1-b14
http://hastebin.com/raw/yetizebofo

RHEL 7.2:
build 1.8.0_91-b14
http://hastebin.com/raw/irequfawaw

The crash happens when an illegal instruction - 0xea2f0013 - is executed.

The backtrace shows:

Stack: [0x00003fff56030000,0x00003fff56430000],  sp=0x00003fff5642b8d0,  free space=4078k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x162104]  loadI2LNode::emit(CodeBuffer&, PhaseRegAlloc*) const+0x194
V  [libjvm.so+0x8ece28]  Compile::fill_buffer(CodeBuffer*, unsigned int*)+0x4e8
V  [libjvm.so+0x368e08]  Compile::Code_Gen()+0x3c8
V  [libjvm.so+0x369e04]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool)+0xf64
V  [libjvm.so+0x271380]  C2Compiler::compile_method(ciEnv*, ciMethod*, int)+0x1f0
V  [libjvm.so+0x3785a4]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0xd54
V  [libjvm.so+0x379dc8]  CompileBroker::compiler_thread_loop()+0x488
V  [libjvm.so+0xa5de90]  compiler_thread_entry(JavaThread*, Thread*)+0x20
V  [libjvm.so+0xa690c8]  JavaThread::thread_main_inner()+0x178
V  [libjvm.so+0x8c8c10]  java_start(Thread*)+0x170
C  [libpthread.so.0+0x833c]  start_thread+0xfc
C  [libc.so.6+0x12b014]  clone+0xe4

loadI2LNode class is generated according to the following ADL code in
ppc.ad file:

instruct loadI2L(iRegLdst dst, memory mem) %{
  match(Set dst (ConvI2L (LoadI mem)));
  predicate(_kids[0]->_leaf->as_Load()->is_unordered());
  ins_cost(MEMORY_REF_COST);

  format %{ "LWA     $dst, $mem \t// loadI2L" %}
  size(4);
  ins_encode %{
    // TODO: PPC port $archOpcode(ppc64Opcode_lwa);
    int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
    __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
  %}
  ins_pipe(pipe_class_memory);
%}

So the generated illegal instruction comes from:
lwa 17,17,15  (DS-form: lwa RT, DS, RA)

As DS field must always be 4-byte aligned (i.e. DS field is always
concatenated with 0b00), 17 as DS (middle 17 value) is illegal,
generating the illegal instruction in question:

11101010000000000000000000000010: LWA
00000010001000000000000000000000: 17
00000000000000000000000000010001: 17
00000000000011110000000000000000: 15
--------------------------------
11101010001011110000000000010011: 0xEA2F0013 => Illegal instruction

The following change is proposed to fix the issue and deals with the
unaligned displacements:

OpenJDK 9 webrev:
81.de.7a9f.ip4.static.sl-reverse.com./illegal/9

OpenJDK 8 webrev:
81.de.7a9f.ip4.static.sl-reverse.com./illegal/8