hotspot/src/cpu/x86/vm/nativeInst_x86.cpp
changeset 42650 1f304d0c888b
parent 33198 b37ad9fbf681
child 44518 46f88691d812
equal deleted inserted replaced
42649:28238583a459 42650:1f304d0c888b
    37 
    37 
    38 void NativeInstruction::wrote(int offset) {
    38 void NativeInstruction::wrote(int offset) {
    39   ICache::invalidate_word(addr_at(offset));
    39   ICache::invalidate_word(addr_at(offset));
    40 }
    40 }
    41 
    41 
       
    42 void NativeLoadGot::report_and_fail() const {
       
    43   tty->print_cr("Addr: " INTPTR_FORMAT, p2i(instruction_address()));
       
    44   fatal("not a indirect rip mov to rbx");
       
    45 }
       
    46 
       
    47 void NativeLoadGot::verify() const {
       
    48   if (has_rex) {
       
    49     int rex = ubyte_at(0);
       
    50     if (rex != rex_prefix) {
       
    51       report_and_fail();
       
    52     }
       
    53   }
       
    54 
       
    55   int inst = ubyte_at(rex_size);
       
    56   if (inst != instruction_code) {
       
    57     report_and_fail();
       
    58   }
       
    59   int modrm = ubyte_at(rex_size + 1);
       
    60   if (modrm != modrm_rbx_code && modrm != modrm_rax_code) {
       
    61     report_and_fail();
       
    62   }
       
    63 }
       
    64 
       
    65 intptr_t NativeLoadGot::data() const {
       
    66   return *(intptr_t *) got_address();
       
    67 }
       
    68 
       
    69 address NativePltCall::destination() const {
       
    70   NativeGotJump* jump = nativeGotJump_at(plt_jump());
       
    71   return jump->destination();
       
    72 }
       
    73 
       
    74 address NativePltCall::plt_entry() const {
       
    75   return return_address() + displacement();
       
    76 }
       
    77 
       
    78 address NativePltCall::plt_jump() const {
       
    79   address entry = plt_entry();
       
    80   // Virtual PLT code has move instruction first
       
    81   if (((NativeGotJump*)entry)->is_GotJump()) {
       
    82     return entry;
       
    83   } else {
       
    84     return nativeLoadGot_at(entry)->next_instruction_address();
       
    85   }
       
    86 }
       
    87 
       
    88 address NativePltCall::plt_load_got() const {
       
    89   address entry = plt_entry();
       
    90   if (!((NativeGotJump*)entry)->is_GotJump()) {
       
    91     // Virtual PLT code has move instruction first
       
    92     return entry;
       
    93   } else {
       
    94     // Static PLT code has move instruction second (from c2i stub)
       
    95     return nativeGotJump_at(entry)->next_instruction_address();
       
    96   }
       
    97 }
       
    98 
       
    99 address NativePltCall::plt_c2i_stub() const {
       
   100   address entry = plt_load_got();
       
   101   // This method should be called only for static calls which has C2I stub.
       
   102   NativeLoadGot* load = nativeLoadGot_at(entry);
       
   103   return entry;
       
   104 }
       
   105 
       
   106 address NativePltCall::plt_resolve_call() const {
       
   107   NativeGotJump* jump = nativeGotJump_at(plt_jump());
       
   108   address entry = jump->next_instruction_address();
       
   109   if (((NativeGotJump*)entry)->is_GotJump()) {
       
   110     return entry;
       
   111   } else {
       
   112     // c2i stub 2 instructions
       
   113     entry = nativeLoadGot_at(entry)->next_instruction_address();
       
   114     return nativeGotJump_at(entry)->next_instruction_address();
       
   115   }
       
   116 }
       
   117 
       
   118 void NativePltCall::reset_to_plt_resolve_call() {
       
   119   set_destination_mt_safe(plt_resolve_call());
       
   120 }
       
   121 
       
   122 void NativePltCall::set_destination_mt_safe(address dest) {
       
   123   // rewriting the value in the GOT, it should always be aligned
       
   124   NativeGotJump* jump = nativeGotJump_at(plt_jump());
       
   125   address* got = (address *) jump->got_address();
       
   126   *got = dest;
       
   127 }
       
   128 
       
   129 void NativePltCall::set_stub_to_clean() {
       
   130   NativeLoadGot* method_loader = nativeLoadGot_at(plt_c2i_stub());
       
   131   NativeGotJump* jump          = nativeGotJump_at(method_loader->next_instruction_address());
       
   132   method_loader->set_data(0);
       
   133   jump->set_jump_destination((address)-1);
       
   134 }
       
   135 
       
   136 void NativePltCall::verify() const {
       
   137   // Make sure code pattern is actually a call rip+off32 instruction.
       
   138   int inst = ubyte_at(0);
       
   139   if (inst != instruction_code) {
       
   140     tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()),
       
   141                                                         inst);
       
   142     fatal("not a call rip+off32");
       
   143   }
       
   144 }
       
   145 
       
   146 address NativeGotJump::destination() const {
       
   147   address *got_entry = (address *) got_address();
       
   148   return *got_entry;
       
   149 }
       
   150 
       
   151 void NativeGotJump::verify() const {
       
   152   int inst = ubyte_at(0);
       
   153   if (inst != instruction_code) {
       
   154     tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()),
       
   155                                                         inst);
       
   156     fatal("not a indirect rip jump");
       
   157   }
       
   158 }
       
   159 
    42 void NativeCall::verify() {
   160 void NativeCall::verify() {
    43   // Make sure code pattern is actually a call imm32 instruction.
   161   // Make sure code pattern is actually a call imm32 instruction.
    44   int inst = ubyte_at(0);
   162   int inst = ubyte_at(0);
    45   if (inst != instruction_code) {
   163   if (inst != instruction_code) {
    46     tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()),
   164     tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()),
   420 
   538 
   421 //--------------------------------------------------------------------------------
   539 //--------------------------------------------------------------------------------
   422 
   540 
   423 void NativeJump::verify() {
   541 void NativeJump::verify() {
   424   if (*(u_char*)instruction_address() != instruction_code) {
   542   if (*(u_char*)instruction_address() != instruction_code) {
   425     fatal("not a jump instruction");
   543     // far jump
       
   544     NativeMovConstReg* mov = nativeMovConstReg_at(instruction_address());
       
   545     NativeInstruction* jmp = nativeInstruction_at(mov->next_instruction_address());
       
   546     if (!jmp->is_jump_reg()) {
       
   547       fatal("not a jump instruction");
       
   548     }
   426   }
   549   }
   427 }
   550 }
   428 
   551 
   429 
   552 
   430 void NativeJump::insert(address code_pos, address entry) {
   553 void NativeJump::insert(address code_pos, address entry) {
   512   // Invalidate.  Opteron requires a flush after every write.
   635   // Invalidate.  Opteron requires a flush after every write.
   513   n_jump->wrote(0);
   636   n_jump->wrote(0);
   514 
   637 
   515 }
   638 }
   516 
   639 
       
   640 address NativeFarJump::jump_destination() const          {
       
   641   NativeMovConstReg* mov = nativeMovConstReg_at(addr_at(0));
       
   642   return (address)mov->data();
       
   643 }
       
   644 
       
   645 void NativeFarJump::verify() {
       
   646   if (is_far_jump()) {
       
   647     NativeMovConstReg* mov = nativeMovConstReg_at(addr_at(0));
       
   648     NativeInstruction* jmp = nativeInstruction_at(mov->next_instruction_address());
       
   649     if (jmp->is_jump_reg()) return;
       
   650   }
       
   651   fatal("not a jump instruction");
       
   652 }
       
   653 
   517 void NativePopReg::insert(address code_pos, Register reg) {
   654 void NativePopReg::insert(address code_pos, Register reg) {
   518   assert(reg->encoding() < 8, "no space for REX");
   655   assert(reg->encoding() < 8, "no space for REX");
   519   assert(NativePopReg::instruction_size == sizeof(char), "right address unit for update");
   656   assert(NativePopReg::instruction_size == sizeof(char), "right address unit for update");
   520   *code_pos = (u_char)(instruction_code | reg->encoding());
   657   *code_pos = (u_char)(instruction_code | reg->encoding());
   521   ICache::invalidate_range(code_pos, instruction_size);
   658   ICache::invalidate_range(code_pos, instruction_size);