< prev index next >

src/cpu/x86/vm/nativeInst_x86.hpp

Print this page

        

@@ -58,10 +58,11 @@
     nop_instruction_size        =    1
   };
 
   bool is_nop()                        { return ubyte_at(0) == nop_instruction_code; }
   inline bool is_call();
+  inline bool is_call_reg();
   inline bool is_illegal();
   inline bool is_return();
   inline bool is_jump();
   inline bool is_cond_jump();
   inline bool is_safepoint_poll();

@@ -178,10 +179,28 @@
   call->verify();
 #endif
   return call;
 }
 
+class NativeCallReg: public NativeInstruction {
+ public:
+  enum Intel_specific_constants {
+    instruction_code            = 0xFF,
+    instruction_offset          =    0,
+    return_address_offset_norex =    2,
+    return_address_offset_rex   =    3
+  };
+
+  int next_instruction_offset() const  {
+    if (ubyte_at(0) == NativeCallReg::instruction_code) {
+      return return_address_offset_norex;
+    } else {
+      return return_address_offset_rex;
+    }
+  }
+};
+
 // An interface for accessing/manipulating native mov reg, imm32 instructions.
 // (used to manipulate inlined 32bit data dll calls, etc.)
 class NativeMovConstReg: public NativeInstruction {
 #ifdef AMD64
   static const bool has_rex = true;

@@ -517,38 +536,39 @@
   };
 };
 
 inline bool NativeInstruction::is_illegal()      { return (short)int_at(0) == (short)NativeIllegalInstruction::instruction_code; }
 inline bool NativeInstruction::is_call()         { return ubyte_at(0) == NativeCall::instruction_code; }
+inline bool NativeInstruction::is_call_reg()     { return ubyte_at(0) == NativeCallReg::instruction_code ||
+                                                          (ubyte_at(1) == NativeCallReg::instruction_code &&
+                                                           (ubyte_at(0) == Assembler::REX || ubyte_at(0) == Assembler::REX_B)); }
 inline bool NativeInstruction::is_return()       { return ubyte_at(0) == NativeReturn::instruction_code ||
                                                           ubyte_at(0) == NativeReturnX::instruction_code; }
 inline bool NativeInstruction::is_jump()         { return ubyte_at(0) == NativeJump::instruction_code ||
                                                           ubyte_at(0) == 0xEB; /* short jump */ }
 inline bool NativeInstruction::is_cond_jump()    { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
                                                           (ubyte_at(0) & 0xF0) == 0x70;  /* short jump */ }
 inline bool NativeInstruction::is_safepoint_poll() {
 #ifdef AMD64
-  if (Assembler::is_polling_page_far()) {
+  // Try decoding a near safepoint first:
+  if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
+      ubyte_at(1) == 0x05) { // 00 rax 101
+    address fault = addr_at(6) + int_at(2);
+    NOT_JVMCI(assert(!Assembler::is_polling_page_far(), "unexpected poll encoding");)
+    return os::is_poll_address(fault);
+  }
+  // Now try decoding a far safepoint:
     // two cases, depending on the choice of the base register in the address.
     if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
          ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
          (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
         ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
         (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) {
+    NOT_JVMCI(assert(Assembler::is_polling_page_far(), "unexpected poll encoding");)
       return true;
-    } else {
-      return false;
     }
-  } else {
-    if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
-        ubyte_at(1) == 0x05) { // 00 rax 101
-      address fault = addr_at(6) + int_at(2);
-      return os::is_poll_address(fault);
-    } else {
       return false;
-    }
-  }
 #else
   return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
            ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) &&
            (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */
            (os::is_poll_address((address)int_at(2)));
< prev index next >