Some doubts about the LIR Operand

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Some doubts about the LIR Operand

QQ mail
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.



Details:

First I write a debug function to print the values:

jdk8u/hotspot/src/share/vm/c1/c1_Runtime1.cpp
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);
JRT_END




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

The source code:
jdk8u/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
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);

  object.load_item();

  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) {
      value.load_byte_item();
    } else  {
      value.load_item();
    }
  } else {
    value.load_for_store(field_type);
  }

  set_no_result(x);

#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());
  }
#endif

  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.
    pre_barrier(LIR_OprFact::address(address),
                LIR_OprFact::illegalOpr /* pre_val */,
                true /* do_load*/,
                needs_patching,
                (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());
 
    //debug
    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@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.












Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Some doubts about the LIR Operand

QQ mail
I think I know the reason.
This crash is caused by the wrong type assigned to arguments.
Some times, the object.result() can be T_INT, so it’s better to assign T_OBJECT as the parameter type.


    BasicTypeList signature;
  //  signature.append(NOT_LP64(T_INT) LP64_ONLY(T_LONG));  // 1st argument, HeapWord* src_addr,
    signature.append(T_OBJECT);  // 1st argument, 
    signature.append(T_OBJECT);  // 2nd argument, 

    CallingConvention* cc = frame_map()->c_calling_convention(&signature);
    __ move(object.result(), cc->args()->at(0));         
    __ move(value.result(), cc->args()->at(1));       

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


I’m new here. If I asked questions in a wrong way, please tell me. I will correct it.
Thank you for your help.

On 5 August 2017 at 12:29:44 AM, QQ mail ([hidden email]) wrote:

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.



Details:

First I write a debug function to print the values:

jdk8u/hotspot/src/share/vm/c1/c1_Runtime1.cpp
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);
JRT_END




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

The source code:
jdk8u/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
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);

  object.load_item();

  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) {
      value.load_byte_item();
    } else  {
      value.load_item();
    }
  } else {
    value.load_for_store(field_type);
  }

  set_no_result(x);

#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());
  }
#endif

  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.
    pre_barrier(LIR_OprFact::address(address),
                LIR_OprFact::illegalOpr /* pre_val */,
                true /* do_load*/,
                needs_patching,
                (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());
 
    //debug
    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@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.












Loading...