Top


定義場所(file name)

hotspot/src/cpu/x86/vm/assembler_x86.cpp

説明(description)

// 64bit only pieces of the assembler
// This should only be used by 64bit instructions that can use rip-relative
// it cannot be used by instructions that want an immediate value.

名前(function name)

bool Assembler::reachable(AddressLiteral adr) {

本体部(body)

  {- -------------------------------------------
  (1) 
      ---------------------------------------- -}

      int64_t disp;
      // None will force a 64bit literal to the code stream. Likely a placeholder
      // for something that will be patched later and we need to certain it will
      // always be reachable.
      if (adr.reloc() == relocInfo::none) {
        return false;
      }
      if (adr.reloc() == relocInfo::internal_word_type) {
        // This should be rip relative and easily reachable.
        return true;
      }
      if (adr.reloc() == relocInfo::virtual_call_type ||
          adr.reloc() == relocInfo::opt_virtual_call_type ||
          adr.reloc() == relocInfo::static_call_type ||
          adr.reloc() == relocInfo::static_stub_type ) {
        // This should be rip relative within the code cache and easily
        // reachable until we get huge code caches. (At which point
        // ic code is going to have issues).
        return true;
      }
      if (adr.reloc() != relocInfo::external_word_type &&
          adr.reloc() != relocInfo::poll_return_type &&  // these are really external_word but need special
          adr.reloc() != relocInfo::poll_type &&         // relocs to identify them
          adr.reloc() != relocInfo::runtime_call_type ) {
        return false;
      }

      // Stress the correction code
      if (ForceUnreachable) {
        // Must be runtimecall reloc, see if it is in the codecache
        // Flipping stuff in the codecache to be unreachable causes issues
        // with things like inline caches where the additional instructions
        // are not handled.
        if (CodeCache::find_blob(adr._target) == NULL) {
          return false;
        }
      }
      // For external_word_type/runtime_call_type if it is reachable from where we
      // are now (possibly a temp buffer) and where we might end up
      // anywhere in the codeCache then we are always reachable.
      // This would have to change if we ever save/restore shared code
      // to be more pessimistic.
      disp = (int64_t)adr._target - ((int64_t)CodeCache::low_bound() + sizeof(int));
      if (!is_simm32(disp)) return false;
      disp = (int64_t)adr._target - ((int64_t)CodeCache::high_bound() + sizeof(int));
      if (!is_simm32(disp)) return false;

      disp = (int64_t)adr._target - ((int64_t)_code_pos + sizeof(int));

      // Because rip relative is a disp + address_of_next_instruction and we
      // don't know the value of address_of_next_instruction we apply a fudge factor
      // to make sure we will be ok no matter the size of the instruction we get placed into.
      // We don't have to fudge the checks above here because they are already worst case.

      // 12 == override/rex byte, opcode byte, rm byte, sib byte, a 4-byte disp , 4-byte literal
      // + 4 because better safe than sorry.
      const int fudge = 12 + 4;
      if (disp < 0) {
        disp -= fudge;
      } else {
        disp += fudge;
      }
      return is_simm32(disp);
    }

This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.