Some doubts about the LIR Operand

QQ mail 515248659 at
Fri Aug 4 16:29:44 UTC 2017

Hi all, 
	I want to Insert a runtime function to print the StoreField's write barrier information produced by C1 compiler.
But it seems that the passed LIR operands sometimes crash the hotspot.


First I write a debug function to print the values:

JRT_LEAF(void, Runtime1::debug_function(HeapWord* field_addr, HeapWord* target_addr))
  tty->print(" C1 : after  decode: src addr: %#lx , dst addr: %#lx \n",(unsigned long)field_addr, (unsigned long)target_addr);

Then, I build a runtime function invoke  in : void LIRGenerator::do_StoreField(StoreField* x) , just after the post_barrier() .

The source code:
void LIRGenerator::do_StoreField(StoreField* x) {
  bool needs_patching = x->needs_patching();
  bool is_volatile = x->field()->is_volatile();
  BasicType field_type = x->field_type();
  bool is_oop = (field_type == T_ARRAY || field_type == T_OBJECT);

  CodeEmitInfo* info = NULL;
  if (needs_patching) {
    assert(x->explicit_null_check() == NULL, "can't fold null check into patching field access");
    info = state_for(x, x->state_before());
  } else if (x->needs_null_check()) {
    NullCheck* nc = x->explicit_null_check();
    if (nc == NULL) {
      info = state_for(x);
    } else {
      info = state_for(nc);

  LIRItem object(x->obj(), this);
  LIRItem value(x->value(),  this);


  if (is_volatile || needs_patching) {
    // load item if field is volatile (fewer special cases for volatiles)
    // load item if field not initialized
    // load item if field not constant
    // because of code patching we cannot inline constants
    if (field_type == T_BYTE || field_type == T_BOOLEAN) {
    } else  {
  } else {


#ifndef PRODUCT
  if (PrintNotLoaded && needs_patching) {
    tty->print_cr("   ###class not loaded at store_%s bci %d",
                  x->is_static() ?  "static" : "field", x->printable_bci());

  if (x->needs_null_check() &&
      (needs_patching ||
       MacroAssembler::needs_explicit_null_check(x->offset()))) {
    // emit an explicit null check because the offset is too large
    __ null_check(object.result(), new CodeEmitInfo(info));

  LIR_Address* address;
  if (needs_patching) {
    // we need to patch the offset in the instruction so don't allow
    // generate_address to try to be smart about emitting the -1.
    // Otherwise the patching code won't know how to find the
    // instruction to patch.
    address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
  } else {
    address = generate_address(object.result(), x->offset(), field_type);

  if (is_volatile && os::is_MP()) {
    __ membar_release();

  if (is_oop) {
    // Do the pre-write barrier, if any.
                LIR_OprFact::illegalOpr /* pre_val */,
                true /* do_load*/,
                (info ? new CodeEmitInfo(info) : NULL));

  if (is_volatile && !needs_patching) {
    volatile_field_store(value.result(), address, info);
  } else {
    LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
    __ store(value.result(), address, info, patch_code);

  if (is_oop) {
    // Store to object so mark the card of the header
    post_barrier(object.result(), value.result());
    BasicTypeList signature;
    signature.append(NOT_LP64(T_INT) LP64_ONLY(T_LONG));  // 1st argument, HeapWord* src_addr,
    signature.append(NOT_LP64(T_INT) LP64_ONLY(T_LONG));  // 2nd argument, HeapWord* target_addr,
    CallingConvention* cc = frame_map()->c_calling_convention(&signature);
    __ move(object.result(), cc->args()->at(0));          // &obj.field  -> 1st arg
    __ move(value.result(), cc->args()->at(1));           // target addr -> 2nd arg

    __ call_runtime_leaf( CAST_FROM_FN_PTR(u_char*, Runtime1::debug_function), getThreadTemp(), LIR_OprFact::illegalOpr,cc->args());

  if (is_volatile && os::is_MP()) {
    __ membar();

Then it sometimes crashes and print the call stack:
(gdb) bt
#0  0x00007ffff7a47c37 in __GI_raise (sig=sig at entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff7a4b028 in __GI_abort () at abort.c:89
#2  0x00007ffff6ce804a in os::abort (dump_core=true) at /home2/spark06/jdk8u/hotspot/src/os/linux/vm/os_linux.cpp:1496
#3  0x00007ffff6eb4ba2 in VMError::report_and_die (this=0x7fff7b9f7e90) at /home2/spark06/jdk8u/hotspot/src/share/vm/utilities/vmError.cpp:1060
#4  0x00007ffff684647b in report_vm_error (file=0x7ffff6f610f0 "/home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIR.hpp", line=420, error_msg=0x7ffff6f612a8 "assert(is_single_cpu() && !is_virtual()) failed",
   detail_msg=0x7ffff6f61155 "type check") at /home2/spark06/jdk8u/hotspot/src/share/vm/utilities/debug.cpp:226
#5  0x00007ffff6673596 in LIR_OprDesc::cpu_regnr (this=0x93) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIR.hpp:420
#6  0x00007ffff666971e in LIR_OprDesc::as_register (this=0x93) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIR.cpp:34
#7  0x00007ffff667be52 in LIR_Assembler::const2reg (this=0x7fff7b9f8290, src=0x7ffe50056170, dest=0x93, patch_code=lir_patch_none, info=0x0) at /home2/spark06/jdk8u/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp:681
#8  0x00007ffff6677d2e in LIR_Assembler::move_op (this=0x7fff7b9f8290, src=0x7ffe50056170, dest=0x93, type=T_LONG, patch_code=lir_patch_none, info=0x0, pop_fpu_stack=false, unaligned=false, wide=false)
   at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp:841
#9  0x00007ffff6676dcc in LIR_Assembler::emit_op1 (this=0x7fff7b9f8290, op=0x7ffe5802f9d0) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp:523
#10 0x00007ffff666def7 in LIR_Op1::emit_code (this=0x7ffe5802f9d0, masm=0x7fff7b9f8290) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIR.cpp:1103
#11 0x00007ffff6676255 in LIR_Assembler::emit_lir_list (this=0x7fff7b9f8290, list=0x7ffe50056080) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp:308
#12 0x00007ffff6676081 in LIR_Assembler::emit_block (this=0x7fff7b9f8290, block=0x7ffe50052390) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp:274
#13 0x00007ffff6675e61 in LIR_Assembler::emit_code (this=0x7fff7b9f8290, hir=0x7ffe50054600) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp:233
#14 0x00007ffff663564b in Compilation::emit_code_body (this=0x7fff7b9f8590) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_Compilation.cpp:343
#15 0x00007ffff663593b in Compilation::compile_java_method (this=0x7fff7b9f8590) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_Compilation.cpp:395
#16 0x00007ffff6635c31 in Compilation::compile_method (this=0x7fff7b9f8590) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_Compilation.cpp:448
#17 0x00007ffff6636275 in Compilation::Compilation (this=0x7fff7b9f8590, compiler=0x7ffff01bda50, env=0x7fff7b9f8a30, method=0x7ffe58028400, osr_bci=-1, buffer_blob=0x7fffe11f5650)
   at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_Compilation.cpp:559
#18 0x00007ffff6638f7e in Compiler::compile_method (this=0x7ffff01bda50, env=0x7fff7b9f8a30, method=0x7ffe58028400, entry_bci=-1) at /home2/spark06/jdk8u/hotspot/src/share/vm/c1/c1_Compiler.cpp:106
#19 0x00007ffff67e20f4 in CompileBroker::invoke_compiler_on_method (task=0x7ffff027d680) at /home2/spark06/jdk8u/hotspot/src/share/vm/compiler/compileBroker.cpp:2000
#20 0x00007ffff67e1651 in CompileBroker::compiler_thread_loop () at /home2/spark06/jdk8u/hotspot/src/share/vm/compiler/compileBroker.cpp:1815
#21 0x00007ffff6e58c92 in compiler_thread_entry (thread=0x7ffff01fd800, __the_thread__=0x7ffff01fd800) at /home2/spark06/jdk8u/hotspot/src/share/vm/runtime/thread.cpp:3233
#22 0x00007ffff6e5402e in JavaThread::thread_main_inner (this=0x7ffff01fd800) at /home2/spark06/jdk8u/hotspot/src/share/vm/runtime/thread.cpp:1702
#23 0x00007ffff6e53efb in JavaThread::run (this=0x7ffff01fd800) at /home2/spark06/jdk8u/hotspot/src/share/vm/runtime/thread.cpp:1682
#24 0x00007ffff6ce6b33 in java_start (thread=0x7ffff01fd800) at /home2/spark06/jdk8u/hotspot/src/os/linux/vm/os_linux.cpp:782
#25 0x00007ffff75f7184 in start_thread (arg=0x7fff7b9f9700) at pthread_create.c:312
#26 0x00007ffff7b0effd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

It seems that, the operand , object.result() and value.result() cause the error.
But I can’t understand why, if this is a oop store field , I think the object.result() and value.result() should be pointer(LIR_OprPtr) or array address(LIR_Address),
Why it cause errors?

Can any one give me some advices ?
Thank you for your help.

Chenxi Wang.

More information about the hotspot-dev mailing list