src/hotspot/cpu/arm/nativeInst_arm_64.cpp
author stefank
Fri, 04 May 2018 11:41:35 +0200
changeset 49982 9042ffe5b7fe
parent 49592 77fb0be7d19f
permissions -rw-r--r--
8200729: Conditional compilation of GCs Reviewed-by: ehelin, coleenp, kvn, ihse
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     1
/*
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     2
 * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     4
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     7
 * published by the Free Software Foundation.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     8
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    13
 * accompanied this code).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    14
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    18
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    21
 * questions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    22
 *
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    23
 */
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    24
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    25
#include "precompiled.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    26
#include "assembler_arm.inline.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    27
#include "code/codeCache.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    28
#include "memory/resourceArea.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    29
#include "nativeInst_arm.hpp"
49592
77fb0be7d19f 8199946: Move load/store and encode/decode out of oopDesc
stefank
parents: 47216
diff changeset
    30
#include "oops/compressedOops.inline.hpp"
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    31
#include "oops/klass.inline.hpp"
49592
77fb0be7d19f 8199946: Move load/store and encode/decode out of oopDesc
stefank
parents: 47216
diff changeset
    32
#include "oops/oop.hpp"
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    33
#include "runtime/handles.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    34
#include "runtime/sharedRuntime.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    35
#include "runtime/stubRoutines.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    36
#include "utilities/ostream.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    37
#ifdef COMPILER1
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    38
#include "c1/c1_Runtime1.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    39
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    40
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    41
void RawNativeInstruction::verify() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    42
  // make sure code pattern is actually an instruction address
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    43
  address addr = instruction_address();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    44
  if (addr == NULL || ((intptr_t)addr & (instruction_size - 1)) != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    45
    fatal("not an instruction address");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    46
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    47
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    48
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    49
void NativeMovRegMem::set_offset(int x) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    50
  int scale = get_offset_scale();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    51
  assert((x & right_n_bits(scale)) == 0, "offset should be aligned");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    52
  guarantee((x >> 24) == 0, "encoding constraint");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    53
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    54
  if (Assembler::is_unsigned_imm_in_range(x, 12, scale)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    55
    set_unsigned_imm(x, 12, get_offset_scale(), 10);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    56
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    57
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    58
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    59
  // If offset is too large to be placed into single ldr/str instruction, we replace
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    60
  //   ldr/str  Rt, [Rn, #offset]
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    61
  //   nop
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    62
  // with
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    63
  //   add  LR, Rn, #offset_hi
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    64
  //   ldr/str  Rt, [LR, #offset_lo]
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    65
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    66
  // Note: Rtemp cannot be used as a temporary register as it could be used
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    67
  // for value being stored (see LIR_Assembler::reg2mem).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    68
  // Patchable NativeMovRegMem instructions are generated in LIR_Assembler::mem2reg and LIR_Assembler::reg2mem
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    69
  // which do not use LR, so it is free. Also, it does not conflict with LR usages in c1_LIRGenerator_arm.cpp.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    70
  const int tmp = LR->encoding();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    71
  const int rn = (encoding() >> 5) & 0x1f;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    72
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    73
  NativeInstruction* next = nativeInstruction_at(next_raw_instruction_address());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    74
  assert(next->is_nop(), "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    75
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    76
  next->set_encoding((encoding() & 0xffc0001f) | Assembler::encode_unsigned_imm((x & 0xfff), 12, scale, 10) | tmp << 5);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    77
  this->set_encoding(0x91400000 | Assembler::encode_unsigned_imm((x >> 12), 12, 0, 10) | rn << 5 | tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    78
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    79
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    80
intptr_t NativeMovConstReg::_data() const {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    81
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    82
  if (is_movz()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    83
    // narrow constant or ic call cached value
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    84
    RawNativeInstruction* ni = next_raw();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    85
    assert(ni->is_movk(), "movz;movk expected");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    86
    uint lo16 = (encoding() >> 5) & 0xffff;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    87
    intptr_t hi = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    88
    int i = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    89
    while (ni->is_movk() && i < 3) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    90
      uint hi16 = (ni->encoding() >> 5) & 0xffff;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    91
      int shift = ((ni->encoding() >> 21) & 0x3) << 4;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    92
      hi |= (intptr_t)hi16 << shift;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    93
      ni = ni->next_raw();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    94
      ++i;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    95
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    96
    return lo16 | hi;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    97
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    98
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    99
  return (intptr_t)(nativeLdrLiteral_at(instruction_address())->literal_value());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   100
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   101
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   102
static void raw_set_data(RawNativeInstruction* si, intptr_t x, oop* oop_addr, Metadata** metadata_addr) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   103
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   104
  if (si->is_movz()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   105
    // narrow constant or ic call cached value
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   106
    uintptr_t nx = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   107
    int val_size = 32;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   108
    if (oop_addr != NULL) {
49592
77fb0be7d19f 8199946: Move load/store and encode/decode out of oopDesc
stefank
parents: 47216
diff changeset
   109
      narrowOop encoded_oop = CompressedOops::encode(*oop_addr);
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   110
      nx = encoded_oop;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   111
    } else if (metadata_addr != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   112
      assert((*metadata_addr)->is_klass(), "expected Klass");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   113
      narrowKlass encoded_k = Klass::encode_klass((Klass *)*metadata_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   114
      nx = encoded_k;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   115
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   116
      nx = x;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   117
      val_size = 64;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   118
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   119
    RawNativeInstruction* ni = si->next_raw();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   120
    uint lo16 = nx & 0xffff;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   121
    int shift = 16;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   122
    int imm16 = 0xffff << 5;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   123
    si->set_encoding((si->encoding() & ~imm16) | (lo16 << 5));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   124
    while (shift < val_size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   125
      assert(ni->is_movk(), "movk expected");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   126
      assert((((ni->encoding() >> 21) & 0x3) << 4) == shift, "wrong shift");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   127
      uint hi16 = (nx >> shift) & 0xffff;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   128
      ni->set_encoding((ni->encoding() & ~imm16) | (hi16 << 5));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   129
      shift += 16;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   130
      ni = ni->next_raw();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   131
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   132
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   133
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   134
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   135
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   136
  assert(si->is_ldr_literal(), "should be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   137
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   138
  if (oop_addr == NULL && metadata_addr == NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   139
    // A static ldr_literal without oop_relocation
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   140
    nativeLdrLiteral_at(si->instruction_address())->set_literal_value((address)x);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   141
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   142
    // Oop is loaded from oops section
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   143
    address addr = oop_addr != NULL ? (address)oop_addr : (address)metadata_addr;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   144
    int offset = addr - si->instruction_address();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   145
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   146
    assert((((intptr_t)addr) & 0x7) == 0, "target address should be aligned");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   147
    assert((offset & 0x3) == 0, "offset should be aligned");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   148
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   149
    guarantee(Assembler::is_offset_in_range(offset, 19), "offset is not in range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   150
    nativeLdrLiteral_at(si->instruction_address())->set_literal_address(si->instruction_address() + offset);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   151
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   152
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   153
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   154
void NativeMovConstReg::set_data(intptr_t x) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   155
  // Find and replace the oop corresponding to this instruction in oops section
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   156
  oop* oop_addr = NULL;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   157
  Metadata** metadata_addr = NULL;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   158
  CodeBlob* cb = CodeCache::find_blob(instruction_address());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   159
  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   160
    nmethod* nm = cb->as_nmethod_or_null();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   161
    if (nm != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   162
      RelocIterator iter(nm, instruction_address(), next_raw()->instruction_address());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   163
      while (iter.next()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   164
        if (iter.type() == relocInfo::oop_type) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   165
          oop_addr = iter.oop_reloc()->oop_addr();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   166
          *oop_addr = cast_to_oop(x);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   167
          break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   168
        } else if (iter.type() == relocInfo::metadata_type) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   169
          metadata_addr = iter.metadata_reloc()->metadata_addr();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   170
          *metadata_addr = (Metadata*)x;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   171
          break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   172
        }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   173
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   174
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   175
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   176
  raw_set_data(adjust(this), x, oop_addr,  metadata_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   177
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   178
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   179
void NativeJump::check_verified_entry_alignment(address entry, address verified_entry) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   180
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   181
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   182
void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   183
  assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   184
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   185
  NativeInstruction* instr = nativeInstruction_at(verified_entry);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   186
  assert(instr->is_nop() || instr->encoding() == zombie_illegal_instruction, "required for MT-safe patching");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   187
  instr->set_encoding(zombie_illegal_instruction);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   188
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   189
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   190
void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   191
  assert (nativeInstruction_at(instr_addr)->is_b(), "MT-safe patching of arbitrary instructions is not allowed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   192
  assert (nativeInstruction_at(code_buffer)->is_nop(), "MT-safe patching of arbitrary instructions is not allowed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   193
  nativeInstruction_at(instr_addr)->set_encoding(*(int*)code_buffer);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   194
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   195
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   196
void NativeGeneralJump::insert_unconditional(address code_pos, address entry) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   197
  // Insert at code_pos unconditional B instruction jumping to entry
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   198
  intx offset = entry - code_pos;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   199
  assert (Assembler::is_offset_in_range(offset, 26), "offset is out of range");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   200
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   201
  NativeInstruction* instr = nativeInstruction_at(code_pos);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   202
  assert (instr->is_b() || instr->is_nop(), "MT-safe patching of arbitrary instructions is not allowed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   203
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   204
  instr->set_encoding(0x5 << 26 | Assembler::encode_offset(offset, 26, 0));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   205
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   206
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   207
static address call_for(address return_address) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   208
  CodeBlob* cb = CodeCache::find_blob(return_address);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   209
  nmethod* nm = cb->as_nmethod_or_null();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   210
  if (nm == NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   211
    ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   212
    return NULL;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   213
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   214
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   215
  // Look back 8 instructions (for LIR_Assembler::ic_call and MacroAssembler::patchable_call)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   216
  address begin = return_address - 8*NativeInstruction::instruction_size;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   217
  if (begin < nm->code_begin()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   218
    begin = nm->code_begin();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   219
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   220
  RelocIterator iter(nm, begin, return_address);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   221
  while (iter.next()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   222
    Relocation* reloc = iter.reloc();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   223
    if (reloc->is_call()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   224
      address call = reloc->addr();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   225
      if (nativeInstruction_at(call)->is_call()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   226
        if (nativeCall_at(call)->return_address() == return_address) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   227
          return call;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   228
        }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   229
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   230
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   231
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   232
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   233
  return NULL;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   234
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   235
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   236
bool NativeCall::is_call_before(address return_address) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   237
  return (call_for(return_address) != NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   238
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   239
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   240
NativeCall* nativeCall_before(address return_address) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   241
  assert(NativeCall::is_call_before(return_address), "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   242
  return nativeCall_at(call_for(return_address));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   243
}