src/hotspot/cpu/arm/macroAssembler_arm.cpp
author vlivanov
Fri, 26 May 2017 18:39:27 +0300
changeset 48557 2e867226b914
parent 47580 96392e113a0a
child 49010 9010e596f391
permissions -rw-r--r--
8174962: Better interface invocations Reviewed-by: jrose, coleenp, ahgross, acorn, iignatyev
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
     1
/*
44406
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
     2
 * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
42664
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 "asm/assembler.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    27
#include "asm/assembler.inline.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    28
#include "asm/macroAssembler.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    29
#include "ci/ciEnv.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    30
#include "code/nativeInst.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    31
#include "compiler/disassembler.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    32
#include "gc/shared/cardTableModRefBS.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    33
#include "gc/shared/collectedHeap.inline.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    34
#include "interpreter/interpreter.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    35
#include "memory/resourceArea.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    36
#include "oops/klass.inline.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    37
#include "prims/methodHandles.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    38
#include "runtime/biasedLocking.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    39
#include "runtime/interfaceSupport.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    40
#include "runtime/objectMonitor.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    41
#include "runtime/os.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    42
#include "runtime/sharedRuntime.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    43
#include "runtime/stubRoutines.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    44
#include "utilities/macros.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    45
#if INCLUDE_ALL_GCS
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    46
#include "gc/g1/g1CollectedHeap.inline.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    47
#include "gc/g1/g1SATBCardTableModRefBS.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    48
#include "gc/g1/heapRegion.hpp"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    49
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    50
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    51
// Implementation of AddressLiteral
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    52
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    53
void AddressLiteral::set_rspec(relocInfo::relocType rtype) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    54
  switch (rtype) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    55
  case relocInfo::oop_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    56
    // Oops are a special case. Normally they would be their own section
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    57
    // but in cases like icBuffer they are literals in the code stream that
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    58
    // we don't have a section for. We use none so that we get a literal address
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    59
    // which is always patchable.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    60
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    61
  case relocInfo::external_word_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    62
    _rspec = external_word_Relocation::spec(_target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    63
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    64
  case relocInfo::internal_word_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    65
    _rspec = internal_word_Relocation::spec(_target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    66
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    67
  case relocInfo::opt_virtual_call_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    68
    _rspec = opt_virtual_call_Relocation::spec();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    69
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    70
  case relocInfo::static_call_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    71
    _rspec = static_call_Relocation::spec();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    72
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    73
  case relocInfo::runtime_call_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    74
    _rspec = runtime_call_Relocation::spec();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    75
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    76
  case relocInfo::poll_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    77
  case relocInfo::poll_return_type:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    78
    _rspec = Relocation::spec_simple(rtype);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    79
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    80
  case relocInfo::none:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    81
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    82
  default:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    83
    ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    84
    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    85
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    86
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    87
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    88
// Initially added to the Assembler interface as a pure virtual:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    89
//   RegisterConstant delayed_value(..)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    90
// for:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    91
//   6812678 macro assembler needs delayed binding of a few constants (for 6655638)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    92
// this was subsequently modified to its present name and return type
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    93
RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_addr,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    94
                                                      Register tmp,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    95
                                                      int offset) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    96
  ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    97
  return RegisterOrConstant(-1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    98
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
    99
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
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   102
// Note: ARM32 version is OS dependent
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   103
void MacroAssembler::breakpoint(AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   104
  if (cond == al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   105
    brk();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   106
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   107
    Label L;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   108
    b(L, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   109
    brk();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   110
    bind(L);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   111
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   112
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   113
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   114
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   115
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   116
// virtual method calling
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   117
void MacroAssembler::lookup_virtual_method(Register recv_klass,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   118
                                           Register vtable_index,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   119
                                           Register method_result) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   120
  const int base_offset = in_bytes(Klass::vtable_start_offset()) + vtableEntry::method_offset_in_bytes();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   121
  assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   122
  add(recv_klass, recv_klass, AsmOperand(vtable_index, lsl, LogBytesPerWord));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   123
  ldr(method_result, Address(recv_klass, base_offset));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   124
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   125
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   126
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   127
// Simplified, combined version, good for typical uses.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   128
// Falls through on failure.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   129
void MacroAssembler::check_klass_subtype(Register sub_klass,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   130
                                         Register super_klass,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   131
                                         Register temp_reg,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   132
                                         Register temp_reg2,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   133
                                         Register temp_reg3,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   134
                                         Label& L_success) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   135
  Label L_failure;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   136
  check_klass_subtype_fast_path(sub_klass, super_klass, temp_reg, temp_reg2, &L_success, &L_failure, NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   137
  check_klass_subtype_slow_path(sub_klass, super_klass, temp_reg, temp_reg2, temp_reg3, &L_success, NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   138
  bind(L_failure);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   139
};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   140
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   141
void MacroAssembler::check_klass_subtype_fast_path(Register sub_klass,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   142
                                                   Register super_klass,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   143
                                                   Register temp_reg,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   144
                                                   Register temp_reg2,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   145
                                                   Label* L_success,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   146
                                                   Label* L_failure,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   147
                                                   Label* L_slow_path) {
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
  assert_different_registers(sub_klass, super_klass, temp_reg, temp_reg2, noreg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   150
  const Register super_check_offset = temp_reg2;
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
  Label L_fallthrough;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   153
  int label_nulls = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   154
  if (L_success == NULL)   { L_success   = &L_fallthrough; label_nulls++; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   155
  if (L_failure == NULL)   { L_failure   = &L_fallthrough; label_nulls++; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   156
  if (L_slow_path == NULL) { L_slow_path = &L_fallthrough; label_nulls++; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   157
  assert(label_nulls <= 1, "at most one NULL in the batch");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   158
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   159
  int sc_offset = in_bytes(Klass::secondary_super_cache_offset());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   160
  int sco_offset = in_bytes(Klass::super_check_offset_offset());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   161
  Address super_check_offset_addr(super_klass, sco_offset);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   162
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   163
  // If the pointers are equal, we are done (e.g., String[] elements).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   164
  // This self-check enables sharing of secondary supertype arrays among
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   165
  // non-primary types such as array-of-interface.  Otherwise, each such
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   166
  // type would need its own customized SSA.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   167
  // We move this check to the front of the fast path because many
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   168
  // type checks are in fact trivially successful in this manner,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   169
  // so we get a nicely predicted branch right at the start of the check.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   170
  cmp(sub_klass, super_klass);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   171
  b(*L_success, eq);
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
  // Check the supertype display:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   174
  ldr_u32(super_check_offset, super_check_offset_addr);
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
  Address super_check_addr(sub_klass, super_check_offset);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   177
  ldr(temp_reg, super_check_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   178
  cmp(super_klass, temp_reg); // load displayed supertype
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   179
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   180
  // This check has worked decisively for primary supers.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   181
  // Secondary supers are sought in the super_cache ('super_cache_addr').
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   182
  // (Secondary supers are interfaces and very deeply nested subtypes.)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   183
  // This works in the same check above because of a tricky aliasing
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   184
  // between the super_cache and the primary super display elements.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   185
  // (The 'super_check_addr' can address either, as the case requires.)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   186
  // Note that the cache is updated below if it does not help us find
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   187
  // what we need immediately.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   188
  // So if it was a primary super, we can just fail immediately.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   189
  // Otherwise, it's the slow path for us (no success at this point).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   190
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   191
  b(*L_success, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   192
  cmp_32(super_check_offset, sc_offset);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   193
  if (L_failure == &L_fallthrough) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   194
    b(*L_slow_path, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   195
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   196
    b(*L_failure, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   197
    if (L_slow_path != &L_fallthrough) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   198
      b(*L_slow_path);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   199
    }
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
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   202
  bind(L_fallthrough);
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
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
void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   207
                                                   Register super_klass,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   208
                                                   Register temp_reg,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   209
                                                   Register temp2_reg,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   210
                                                   Register temp3_reg,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   211
                                                   Label* L_success,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   212
                                                   Label* L_failure,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   213
                                                   bool set_cond_codes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   214
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   215
  NOT_IMPLEMENTED();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   216
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   217
  // Note: if used by code that expects a register to be 0 on success,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   218
  // this register must be temp_reg and set_cond_codes must be true
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
  Register saved_reg = noreg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   221
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   222
  // get additional tmp registers
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   223
  if (temp3_reg == noreg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   224
    saved_reg = temp3_reg = LR;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   225
    push(saved_reg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   226
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   227
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   228
  assert(temp2_reg != noreg, "need all the temporary registers");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   229
  assert_different_registers(sub_klass, super_klass, temp_reg, temp2_reg, temp3_reg);
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
  Register cmp_temp = temp_reg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   232
  Register scan_temp = temp3_reg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   233
  Register count_temp = temp2_reg;
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
  Label L_fallthrough;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   236
  int label_nulls = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   237
  if (L_success == NULL)   { L_success   = &L_fallthrough; label_nulls++; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   238
  if (L_failure == NULL)   { L_failure   = &L_fallthrough; label_nulls++; }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   239
  assert(label_nulls <= 1, "at most one NULL in the batch");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   240
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   241
  // a couple of useful fields in sub_klass:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   242
  int ss_offset = in_bytes(Klass::secondary_supers_offset());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   243
  int sc_offset = in_bytes(Klass::secondary_super_cache_offset());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   244
  Address secondary_supers_addr(sub_klass, ss_offset);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   245
  Address super_cache_addr(     sub_klass, sc_offset);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   246
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   247
#ifndef PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   248
  inc_counter((address)&SharedRuntime::_partial_subtype_ctr, scan_temp, count_temp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   249
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   250
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   251
  // We will consult the secondary-super array.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   252
  ldr(scan_temp, Address(sub_klass, ss_offset));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   253
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   254
  assert(! UseCompressedOops, "search_key must be the compressed super_klass");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   255
  // else search_key is the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   256
  Register search_key = super_klass;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   257
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   258
  // Load the array length.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   259
  ldr(count_temp, Address(scan_temp, Array<Klass*>::length_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   260
  add(scan_temp, scan_temp, Array<Klass*>::base_offset_in_bytes());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   261
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   262
  add(count_temp, count_temp, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   263
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   264
  Label L_loop, L_setnz_and_fail, L_fail;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   265
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   266
  // Top of search loop
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   267
  bind(L_loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   268
  // Notes:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   269
  //  scan_temp starts at the array elements
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   270
  //  count_temp is 1+size
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   271
  subs(count_temp, count_temp, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   272
  if ((L_failure != &L_fallthrough) && (! set_cond_codes) && (saved_reg == noreg)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   273
    // direct jump to L_failure if failed and no cleanup needed
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   274
    b(*L_failure, eq); // not found and
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   275
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   276
    b(L_fail, eq); // not found in the array
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   277
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   278
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   279
  // Load next super to check
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   280
  // In the array of super classes elements are pointer sized.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   281
  int element_size = wordSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   282
  ldr(cmp_temp, Address(scan_temp, element_size, post_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   283
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   284
  // Look for Rsuper_klass on Rsub_klass's secondary super-class-overflow list
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   285
  subs(cmp_temp, cmp_temp, search_key);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   286
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   287
  // A miss means we are NOT a subtype and need to keep looping
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   288
  b(L_loop, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   289
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   290
  // Falling out the bottom means we found a hit; we ARE a subtype
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   291
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   292
  // Note: temp_reg/cmp_temp is already 0 and flag Z is set
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   293
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   294
  // Success.  Cache the super we found and proceed in triumph.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   295
  str(super_klass, Address(sub_klass, sc_offset));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   296
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   297
  if (saved_reg != noreg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   298
    // Return success
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   299
    pop(saved_reg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   300
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   301
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   302
  b(*L_success);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   303
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   304
  bind(L_fail);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   305
  // Note1: check "b(*L_failure, eq)" above if adding extra instructions here
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   306
  if (set_cond_codes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   307
    movs(temp_reg, sub_klass); // clears Z and sets temp_reg to non-0 if needed
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   308
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   309
  if (saved_reg != noreg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   310
    pop(saved_reg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   311
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   312
  if (L_failure != &L_fallthrough) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   313
    b(*L_failure);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   314
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   315
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   316
  bind(L_fallthrough);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   317
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   318
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   319
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   320
// Returns address of receiver parameter, using tmp as base register. tmp and params_count can be the same.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   321
Address MacroAssembler::receiver_argument_address(Register params_base, Register params_count, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   322
  assert_different_registers(params_base, params_count);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   323
  add(tmp, params_base, AsmOperand(params_count, lsl, Interpreter::logStackElementSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   324
  return Address(tmp, -Interpreter::stackElementSize);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   325
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   326
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   327
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   328
void MacroAssembler::align(int modulus) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   329
  while (offset() % modulus != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   330
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   331
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   332
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   333
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   334
int MacroAssembler::set_last_Java_frame(Register last_java_sp,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   335
                                        Register last_java_fp,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   336
                                        bool save_last_java_pc,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   337
                                        Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   338
  int pc_offset;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   339
  if (last_java_fp != noreg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   340
    // optional
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   341
    str(last_java_fp, Address(Rthread, JavaThread::last_Java_fp_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   342
    _fp_saved = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   343
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   344
    _fp_saved = false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   345
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   346
  if (AARCH64_ONLY(true) NOT_AARCH64(save_last_java_pc)) { // optional on 32-bit ARM
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   347
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   348
    pc_offset = mov_pc_to(tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   349
    str(tmp, Address(Rthread, JavaThread::last_Java_pc_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   350
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   351
    str(PC, Address(Rthread, JavaThread::last_Java_pc_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   352
    pc_offset = offset() + VM_Version::stored_pc_adjustment();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   353
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   354
    _pc_saved = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   355
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   356
    _pc_saved = false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   357
    pc_offset = -1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   358
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   359
  // According to comment in javaFrameAnchorm SP must be saved last, so that other
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   360
  // entries are valid when SP is set.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   361
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   362
  // However, this is probably not a strong constrainst since for instance PC is
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   363
  // sometimes read from the stack at SP... but is pushed later (by the call). Hence,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   364
  // we now write the fields in the expected order but we have not added a StoreStore
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   365
  // barrier.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   366
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   367
  // XXX: if the ordering is really important, PC should always be saved (without forgetting
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   368
  // to update oop_map offsets) and a StoreStore barrier might be needed.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   369
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   370
  if (last_java_sp == noreg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   371
    last_java_sp = SP; // always saved
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   372
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   373
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   374
  if (last_java_sp == SP) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   375
    mov(tmp, SP);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   376
    str(tmp, Address(Rthread, JavaThread::last_Java_sp_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   377
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   378
    str(last_java_sp, Address(Rthread, JavaThread::last_Java_sp_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   379
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   380
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   381
  str(last_java_sp, Address(Rthread, JavaThread::last_Java_sp_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   382
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   383
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   384
  return pc_offset; // for oopmaps
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   385
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   386
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   387
void MacroAssembler::reset_last_Java_frame(Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   388
  const Register Rzero = zero_register(tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   389
  str(Rzero, Address(Rthread, JavaThread::last_Java_sp_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   390
  if (_fp_saved) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   391
    str(Rzero, Address(Rthread, JavaThread::last_Java_fp_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   392
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   393
  if (_pc_saved) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   394
    str(Rzero, Address(Rthread, JavaThread::last_Java_pc_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   395
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   396
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   397
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   398
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   399
// Implementation of call_VM versions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   400
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   401
void MacroAssembler::call_VM_leaf_helper(address entry_point, int number_of_arguments) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   402
  assert(number_of_arguments >= 0, "cannot have negative number of arguments");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   403
  assert(number_of_arguments <= 4, "cannot have more than 4 arguments");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   404
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   405
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   406
  // Safer to save R9 here since callers may have been written
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   407
  // assuming R9 survives. This is suboptimal but is not worth
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   408
  // optimizing for the few platforms where R9 is scratched.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   409
  push(RegisterSet(R4) | R9ifScratched);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   410
  mov(R4, SP);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   411
  bic(SP, SP, StackAlignmentInBytes - 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   412
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   413
  call(entry_point, relocInfo::runtime_call_type);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   414
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   415
  mov(SP, R4);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   416
  pop(RegisterSet(R4) | R9ifScratched);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   417
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   418
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   419
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   420
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   421
void MacroAssembler::call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   422
  assert(number_of_arguments >= 0, "cannot have negative number of arguments");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   423
  assert(number_of_arguments <= 3, "cannot have more than 3 arguments");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   424
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   425
  const Register tmp = Rtemp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   426
  assert_different_registers(oop_result, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   427
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   428
  set_last_Java_frame(SP, FP, true, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   429
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   430
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   431
  AARCH64_ONLY(if (UseCompressedOops || UseCompressedClassPointers) { verify_heapbase("call_VM_helper: heap base corrupted?"); });
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   432
#endif // ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   433
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   434
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   435
#if R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   436
  // Safer to save R9 here since callers may have been written
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   437
  // assuming R9 survives. This is suboptimal but is not worth
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   438
  // optimizing for the few platforms where R9 is scratched.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   439
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   440
  // Note: cannot save R9 above the saved SP (some calls expect for
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   441
  // instance the Java stack top at the saved SP)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   442
  // => once saved (with set_last_Java_frame), decrease SP before rounding to
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   443
  // ensure the slot at SP will be free for R9).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   444
  sub(SP, SP, 4);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   445
  bic(SP, SP, StackAlignmentInBytes - 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   446
  str(R9, Address(SP, 0));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   447
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   448
  bic(SP, SP, StackAlignmentInBytes - 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   449
#endif // R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   450
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   451
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   452
  mov(R0, Rthread);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   453
  call(entry_point, relocInfo::runtime_call_type);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   454
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   455
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   456
#if R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   457
  ldr(R9, Address(SP, 0));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   458
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   459
  ldr(SP, Address(Rthread, JavaThread::last_Java_sp_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   460
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   461
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   462
  reset_last_Java_frame(tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   463
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   464
  // C++ interp handles this in the interpreter
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   465
  check_and_handle_popframe();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   466
  check_and_handle_earlyret();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   467
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   468
  if (check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   469
    // check for pending exceptions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   470
    ldr(tmp, Address(Rthread, Thread::pending_exception_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   471
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   472
    Label L;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   473
    cbz(tmp, L);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   474
    mov_pc_to(Rexception_pc);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   475
    b(StubRoutines::forward_exception_entry());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   476
    bind(L);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   477
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   478
    cmp(tmp, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   479
    mov(Rexception_pc, PC, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   480
    b(StubRoutines::forward_exception_entry(), ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   481
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   482
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   483
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   484
  // get oop result if there is one and reset the value in the thread
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   485
  if (oop_result->is_valid()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   486
    get_vm_result(oop_result, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   487
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   488
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   489
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   490
void MacroAssembler::call_VM(Register oop_result, address entry_point, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   491
  call_VM_helper(oop_result, entry_point, 0, check_exceptions);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   492
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   493
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   494
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   495
void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   496
  assert (arg_1 == R1, "fixed register for arg_1");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   497
  call_VM_helper(oop_result, entry_point, 1, check_exceptions);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   498
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   499
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   500
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   501
void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   502
  assert (arg_1 == R1, "fixed register for arg_1");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   503
  assert (arg_2 == R2, "fixed register for arg_2");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   504
  call_VM_helper(oop_result, entry_point, 2, check_exceptions);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   505
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   506
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   507
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   508
void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   509
  assert (arg_1 == R1, "fixed register for arg_1");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   510
  assert (arg_2 == R2, "fixed register for arg_2");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   511
  assert (arg_3 == R3, "fixed register for arg_3");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   512
  call_VM_helper(oop_result, entry_point, 3, check_exceptions);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   513
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   514
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   515
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   516
void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, int number_of_arguments, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   517
  // Not used on ARM
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   518
  Unimplemented();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   519
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   520
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   521
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   522
void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   523
  // Not used on ARM
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   524
  Unimplemented();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   525
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   526
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   527
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   528
void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   529
// Not used on ARM
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   530
  Unimplemented();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   531
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   532
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   533
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   534
void MacroAssembler::call_VM(Register oop_result, Register last_java_sp, address entry_point, Register arg_1, Register arg_2, Register arg_3, bool check_exceptions) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   535
  // Not used on ARM
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   536
  Unimplemented();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   537
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   538
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   539
// Raw call, without saving/restoring registers, exception handling, etc.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   540
// Mainly used from various stubs.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   541
void MacroAssembler::call_VM(address entry_point, bool save_R9_if_scratched) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   542
  const Register tmp = Rtemp; // Rtemp free since scratched by call
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   543
  set_last_Java_frame(SP, FP, true, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   544
#if R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   545
  if (save_R9_if_scratched) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   546
    // Note: Saving also R10 for alignment.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   547
    push(RegisterSet(R9, R10));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   548
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   549
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   550
  mov(R0, Rthread);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   551
  call(entry_point, relocInfo::runtime_call_type);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   552
#if R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   553
  if (save_R9_if_scratched) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   554
    pop(RegisterSet(R9, R10));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   555
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   556
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   557
  reset_last_Java_frame(tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   558
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   559
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   560
void MacroAssembler::call_VM_leaf(address entry_point) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   561
  call_VM_leaf_helper(entry_point, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   562
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   563
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   564
void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   565
  assert (arg_1 == R0, "fixed register for arg_1");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   566
  call_VM_leaf_helper(entry_point, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   567
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   568
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   569
void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1, Register arg_2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   570
  assert (arg_1 == R0, "fixed register for arg_1");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   571
  assert (arg_2 == R1, "fixed register for arg_2");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   572
  call_VM_leaf_helper(entry_point, 2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   573
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   574
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   575
void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   576
  assert (arg_1 == R0, "fixed register for arg_1");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   577
  assert (arg_2 == R1, "fixed register for arg_2");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   578
  assert (arg_3 == R2, "fixed register for arg_3");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   579
  call_VM_leaf_helper(entry_point, 3);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   580
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   581
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   582
void MacroAssembler::call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3, Register arg_4) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   583
  assert (arg_1 == R0, "fixed register for arg_1");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   584
  assert (arg_2 == R1, "fixed register for arg_2");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   585
  assert (arg_3 == R2, "fixed register for arg_3");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   586
  assert (arg_4 == R3, "fixed register for arg_4");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   587
  call_VM_leaf_helper(entry_point, 4);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   588
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   589
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   590
void MacroAssembler::get_vm_result(Register oop_result, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   591
  assert_different_registers(oop_result, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   592
  ldr(oop_result, Address(Rthread, JavaThread::vm_result_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   593
  str(zero_register(tmp), Address(Rthread, JavaThread::vm_result_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   594
  verify_oop(oop_result);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   595
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   596
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   597
void MacroAssembler::get_vm_result_2(Register metadata_result, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   598
  assert_different_registers(metadata_result, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   599
  ldr(metadata_result, Address(Rthread, JavaThread::vm_result_2_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   600
  str(zero_register(tmp), Address(Rthread, JavaThread::vm_result_2_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   601
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   602
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   603
void MacroAssembler::add_rc(Register dst, Register arg1, RegisterOrConstant arg2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   604
  if (arg2.is_register()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   605
    add(dst, arg1, arg2.as_register());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   606
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   607
    add(dst, arg1, arg2.as_constant());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   608
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   609
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   610
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   611
void MacroAssembler::add_slow(Register rd, Register rn, int c) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   612
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   613
  if (c == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   614
    if (rd != rn) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   615
      mov(rd, rn);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   616
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   617
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   618
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   619
  if (c < 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   620
    sub_slow(rd, rn, -c);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   621
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   622
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   623
  if (c > right_n_bits(24)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   624
    guarantee(rd != rn, "no large add_slow with only one register");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   625
    mov_slow(rd, c);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   626
    add(rd, rn, rd);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   627
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   628
    int lo = c & right_n_bits(12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   629
    int hi = (c >> 12) & right_n_bits(12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   630
    if (lo != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   631
      add(rd, rn, lo, lsl0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   632
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   633
    if (hi != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   634
      add(rd, (lo == 0) ? rn : rd, hi, lsl12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   635
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   636
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   637
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   638
  // This function is used in compiler for handling large frame offsets
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   639
  if ((c < 0) && (((-c) & ~0x3fc) == 0)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   640
    return sub(rd, rn, (-c));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   641
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   642
  int low = c & 0x3fc;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   643
  if (low != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   644
    add(rd, rn, low);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   645
    rn = rd;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   646
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   647
  if (c & ~0x3fc) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   648
    assert(AsmOperand::is_rotated_imm(c & ~0x3fc), "unsupported add_slow offset %d", c);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   649
    add(rd, rn, c & ~0x3fc);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   650
  } else if (rd != rn) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   651
    assert(c == 0, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   652
    mov(rd, rn); // need to generate at least one move!
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   653
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   654
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   655
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   656
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   657
void MacroAssembler::sub_slow(Register rd, Register rn, int c) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   658
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   659
  if (c <= 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   660
    add_slow(rd, rn, -c);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   661
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   662
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   663
  if (c > right_n_bits(24)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   664
    guarantee(rd != rn, "no large sub_slow with only one register");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   665
    mov_slow(rd, c);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   666
    sub(rd, rn, rd);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   667
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   668
    int lo = c & right_n_bits(12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   669
    int hi = (c >> 12) & right_n_bits(12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   670
    if (lo != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   671
      sub(rd, rn, lo, lsl0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   672
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   673
    if (hi != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   674
      sub(rd, (lo == 0) ? rn : rd, hi, lsl12);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   675
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   676
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   677
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   678
  // This function is used in compiler for handling large frame offsets
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   679
  if ((c < 0) && (((-c) & ~0x3fc) == 0)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   680
    return add(rd, rn, (-c));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   681
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   682
  int low = c & 0x3fc;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   683
  if (low != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   684
    sub(rd, rn, low);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   685
    rn = rd;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   686
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   687
  if (c & ~0x3fc) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   688
    assert(AsmOperand::is_rotated_imm(c & ~0x3fc), "unsupported sub_slow offset %d", c);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   689
    sub(rd, rn, c & ~0x3fc);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   690
  } else if (rd != rn) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   691
    assert(c == 0, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   692
    mov(rd, rn); // need to generate at least one move!
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   693
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   694
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   695
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   696
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   697
void MacroAssembler::mov_slow(Register rd, address addr) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   698
  // do *not* call the non relocated mov_related_address
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   699
  mov_slow(rd, (intptr_t)addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   700
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   701
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   702
void MacroAssembler::mov_slow(Register rd, const char *str) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   703
  mov_slow(rd, (intptr_t)str);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   704
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   705
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   706
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   707
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   708
// Common code for mov_slow and instr_count_for_mov_slow.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   709
// Returns number of instructions of mov_slow pattern,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   710
// generating it if non-null MacroAssembler is given.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   711
int MacroAssembler::mov_slow_helper(Register rd, intptr_t c, MacroAssembler* masm) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   712
  // This code pattern is matched in NativeIntruction::is_mov_slow.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   713
  // Update it at modifications.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   714
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   715
  const intx mask = right_n_bits(16);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   716
  // 1 movz instruction
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   717
  for (int base_shift = 0; base_shift < 64; base_shift += 16) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   718
    if ((c & ~(mask << base_shift)) == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   719
      if (masm != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   720
        masm->movz(rd, ((uintx)c) >> base_shift, base_shift);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   721
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   722
      return 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   723
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   724
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   725
  // 1 movn instruction
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   726
  for (int base_shift = 0; base_shift < 64; base_shift += 16) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   727
    if (((~c) & ~(mask << base_shift)) == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   728
      if (masm != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   729
        masm->movn(rd, ((uintx)(~c)) >> base_shift, base_shift);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   730
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   731
      return 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   732
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   733
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   734
  // 1 orr instruction
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   735
  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   736
    LogicalImmediate imm(c, false);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   737
    if (imm.is_encoded()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   738
      if (masm != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   739
        masm->orr(rd, ZR, imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   740
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   741
      return 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   742
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   743
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   744
  // 1 movz/movn + up to 3 movk instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   745
  int zeroes = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   746
  int ones = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   747
  for (int base_shift = 0; base_shift < 64; base_shift += 16) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   748
    int part = (c >> base_shift) & mask;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   749
    if (part == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   750
      ++zeroes;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   751
    } else if (part == mask) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   752
      ++ones;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   753
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   754
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   755
  int def_bits = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   756
  if (ones > zeroes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   757
    def_bits = mask;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   758
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   759
  int inst_count = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   760
  for (int base_shift = 0; base_shift < 64; base_shift += 16) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   761
    int part = (c >> base_shift) & mask;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   762
    if (part != def_bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   763
      if (masm != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   764
        if (inst_count > 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   765
          masm->movk(rd, part, base_shift);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   766
        } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   767
          if (def_bits == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   768
            masm->movz(rd, part, base_shift);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   769
          } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   770
            masm->movn(rd, ~part & mask, base_shift);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   771
          }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   772
        }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   773
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   774
      inst_count++;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   775
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   776
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   777
  assert((1 <= inst_count) && (inst_count <= 4), "incorrect number of instructions");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   778
  return inst_count;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   779
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   780
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   781
void MacroAssembler::mov_slow(Register rd, intptr_t c) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   782
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   783
  int off = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   784
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   785
  (void) mov_slow_helper(rd, c, this);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   786
  assert(offset() - off == instr_count_for_mov_slow(c) * InstructionSize, "size mismatch");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   787
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   788
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   789
// Counts instructions generated by mov_slow(rd, c).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   790
int MacroAssembler::instr_count_for_mov_slow(intptr_t c) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   791
  return mov_slow_helper(noreg, c, NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   792
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   793
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   794
int MacroAssembler::instr_count_for_mov_slow(address c) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   795
  return mov_slow_helper(noreg, (intptr_t)c, NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   796
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   797
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   798
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   799
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   800
void MacroAssembler::mov_slow(Register rd, intptr_t c, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   801
  if (AsmOperand::is_rotated_imm(c)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   802
    mov(rd, c, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   803
  } else if (AsmOperand::is_rotated_imm(~c)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   804
    mvn(rd, ~c, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   805
  } else if (VM_Version::supports_movw()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   806
    movw(rd, c & 0xffff, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   807
    if ((unsigned int)c >> 16) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   808
      movt(rd, (unsigned int)c >> 16, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   809
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   810
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   811
    // Find first non-zero bit
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   812
    int shift = 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   813
    while ((c & (3 << shift)) == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   814
      shift += 2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   815
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   816
    // Put the least significant part of the constant
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   817
    int mask = 0xff << shift;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   818
    mov(rd, c & mask, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   819
    // Add up to 3 other parts of the constant;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   820
    // each of them can be represented as rotated_imm
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   821
    if (c & (mask << 8)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   822
      orr(rd, rd, c & (mask << 8), cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   823
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   824
    if (c & (mask << 16)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   825
      orr(rd, rd, c & (mask << 16), cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   826
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   827
    if (c & (mask << 24)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   828
      orr(rd, rd, c & (mask << 24), cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   829
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   830
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   831
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   832
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   833
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   834
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   835
void MacroAssembler::mov_oop(Register rd, jobject o, int oop_index,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   836
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   837
                             bool patchable
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   838
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   839
                             AsmCondition cond
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   840
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   841
                             ) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   842
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   843
  if (o == NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   844
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   845
    if (patchable) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   846
      nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   847
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   848
    mov(rd, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   849
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   850
    mov(rd, 0, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   851
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   852
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   853
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   854
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   855
  if (oop_index == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   856
    oop_index = oop_recorder()->allocate_oop_index(o);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   857
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   858
  relocate(oop_Relocation::spec(oop_index));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   859
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   860
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   861
  if (patchable) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   862
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   863
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   864
  ldr(rd, pc());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   865
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   866
  if (VM_Version::supports_movw()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   867
    movw(rd, 0, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   868
    movt(rd, 0, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   869
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   870
    ldr(rd, Address(PC), cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   871
    // Extra nop to handle case of large offset of oop placeholder (see NativeMovConstReg::set_data).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   872
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   873
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   874
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   875
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   876
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   877
void MacroAssembler::mov_metadata(Register rd, Metadata* o, int metadata_index AARCH64_ONLY_ARG(bool patchable)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   878
  if (o == NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   879
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   880
    if (patchable) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   881
      nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   882
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   883
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   884
    mov(rd, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   885
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   886
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   887
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   888
  if (metadata_index == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   889
    metadata_index = oop_recorder()->allocate_metadata_index(o);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   890
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   891
  relocate(metadata_Relocation::spec(metadata_index));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   892
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   893
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   894
  if (patchable) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   895
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   896
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   897
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   898
  if (!patchable && VM_Version::prefer_moves_over_load_literal()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   899
    mov_slow(rd, (address)o);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   900
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   901
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   902
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   903
  ldr(rd, pc());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   904
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   905
  if (VM_Version::supports_movw()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   906
    movw(rd, ((int)o) & 0xffff);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   907
    movt(rd, (unsigned int)o >> 16);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   908
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   909
    ldr(rd, Address(PC));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   910
    // Extra nop to handle case of large offset of metadata placeholder (see NativeMovConstReg::set_data).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   911
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   912
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   913
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   914
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   915
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   916
void MacroAssembler::mov_float(FloatRegister fd, jfloat c NOT_AARCH64_ARG(AsmCondition cond)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   917
  Label skip_constant;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   918
  union {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   919
    jfloat f;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   920
    jint i;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   921
  } accessor;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   922
  accessor.f = c;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   923
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   924
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   925
  // TODO-AARCH64 - try to optimize loading of float constants with fmov and/or mov_slow
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   926
  Label L;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   927
  ldr_s(fd, target(L));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   928
  b(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   929
  bind(L);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   930
  emit_int32(accessor.i);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   931
  bind(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   932
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   933
  flds(fd, Address(PC), cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   934
  b(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   935
  emit_int32(accessor.i);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   936
  bind(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   937
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   938
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   939
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   940
void MacroAssembler::mov_double(FloatRegister fd, jdouble c NOT_AARCH64_ARG(AsmCondition cond)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   941
  Label skip_constant;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   942
  union {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   943
    jdouble d;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   944
    jint i[2];
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   945
  } accessor;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   946
  accessor.d = c;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   947
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   948
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   949
  // TODO-AARCH64 - try to optimize loading of double constants with fmov
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   950
  Label L;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   951
  ldr_d(fd, target(L));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   952
  b(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   953
  align(wordSize);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   954
  bind(L);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   955
  emit_int32(accessor.i[0]);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   956
  emit_int32(accessor.i[1]);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   957
  bind(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   958
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   959
  fldd(fd, Address(PC), cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   960
  b(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   961
  emit_int32(accessor.i[0]);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   962
  emit_int32(accessor.i[1]);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   963
  bind(skip_constant);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   964
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   965
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   966
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   967
void MacroAssembler::ldr_global_s32(Register reg, address address_of_global) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   968
  intptr_t addr = (intptr_t) address_of_global;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   969
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   970
  assert((addr & 0x3) == 0, "address should be aligned");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   971
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   972
  // FIXME: TODO
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   973
  if (false && page_reachable_from_cache(address_of_global)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   974
    assert(false,"TODO: relocate");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   975
    //relocate();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   976
    adrp(reg, address_of_global);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   977
    ldrsw(reg, Address(reg, addr & 0xfff));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   978
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   979
    mov_slow(reg, addr & ~0x3fff);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   980
    ldrsw(reg, Address(reg, addr & 0x3fff));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   981
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   982
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   983
  mov_slow(reg, addr & ~0xfff);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   984
  ldr(reg, Address(reg, addr & 0xfff));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   985
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   986
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   987
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   988
void MacroAssembler::ldr_global_ptr(Register reg, address address_of_global) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   989
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   990
  intptr_t addr = (intptr_t) address_of_global;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   991
  assert ((addr & 0x7) == 0, "address should be aligned");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   992
  mov_slow(reg, addr & ~0x7fff);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   993
  ldr(reg, Address(reg, addr & 0x7fff));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   994
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   995
  ldr_global_s32(reg, address_of_global);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   996
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   997
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   998
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
   999
void MacroAssembler::ldrb_global(Register reg, address address_of_global) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1000
  intptr_t addr = (intptr_t) address_of_global;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1001
  mov_slow(reg, addr & ~0xfff);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1002
  ldrb(reg, Address(reg, addr & 0xfff));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1003
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1004
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1005
void MacroAssembler::zero_extend(Register rd, Register rn, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1006
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1007
  switch (bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1008
    case  8: uxtb(rd, rn); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1009
    case 16: uxth(rd, rn); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1010
    case 32: mov_w(rd, rn); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1011
    default: ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1012
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1013
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1014
  if (bits <= 8) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1015
    andr(rd, rn, (1 << bits) - 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1016
  } else if (bits >= 24) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1017
    bic(rd, rn, -1 << bits);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1018
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1019
    mov(rd, AsmOperand(rn, lsl, 32 - bits));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1020
    mov(rd, AsmOperand(rd, lsr, 32 - bits));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1021
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1022
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1023
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1024
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1025
void MacroAssembler::sign_extend(Register rd, Register rn, int bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1026
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1027
  switch (bits) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1028
    case  8: sxtb(rd, rn); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1029
    case 16: sxth(rd, rn); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1030
    case 32: sxtw(rd, rn); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1031
    default: ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1032
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1033
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1034
  mov(rd, AsmOperand(rn, lsl, 32 - bits));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1035
  mov(rd, AsmOperand(rd, asr, 32 - bits));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1036
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1037
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1038
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1039
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1040
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1041
void MacroAssembler::long_move(Register rd_lo, Register rd_hi,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1042
                               Register rn_lo, Register rn_hi,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1043
                               AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1044
  if (rd_lo != rn_hi) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1045
    if (rd_lo != rn_lo) { mov(rd_lo, rn_lo, cond); }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1046
    if (rd_hi != rn_hi) { mov(rd_hi, rn_hi, cond); }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1047
  } else if (rd_hi != rn_lo) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1048
    if (rd_hi != rn_hi) { mov(rd_hi, rn_hi, cond); }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1049
    if (rd_lo != rn_lo) { mov(rd_lo, rn_lo, cond); }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1050
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1051
    eor(rd_lo, rd_hi, rd_lo, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1052
    eor(rd_hi, rd_lo, rd_hi, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1053
    eor(rd_lo, rd_hi, rd_lo, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1054
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1055
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1056
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1057
void MacroAssembler::long_shift(Register rd_lo, Register rd_hi,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1058
                                Register rn_lo, Register rn_hi,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1059
                                AsmShift shift, Register count) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1060
  Register tmp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1061
  if (rd_lo != rn_lo && rd_lo != rn_hi && rd_lo != count) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1062
    tmp = rd_lo;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1063
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1064
    tmp = rd_hi;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1065
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1066
  assert_different_registers(tmp, count, rn_lo, rn_hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1067
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1068
  subs(tmp, count, 32);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1069
  if (shift == lsl) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1070
    assert_different_registers(rd_hi, rn_lo);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1071
    assert_different_registers(count, rd_hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1072
    mov(rd_hi, AsmOperand(rn_lo, shift, tmp), pl);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1073
    rsb(tmp, count, 32, mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1074
    if (rd_hi == rn_hi) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1075
      mov(rd_hi, AsmOperand(rn_hi, lsl, count), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1076
      orr(rd_hi, rd_hi, AsmOperand(rn_lo, lsr, tmp), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1077
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1078
      mov(rd_hi, AsmOperand(rn_lo, lsr, tmp), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1079
      orr(rd_hi, rd_hi, AsmOperand(rn_hi, lsl, count), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1080
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1081
    mov(rd_lo, AsmOperand(rn_lo, shift, count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1082
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1083
    assert_different_registers(rd_lo, rn_hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1084
    assert_different_registers(rd_lo, count);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1085
    mov(rd_lo, AsmOperand(rn_hi, shift, tmp), pl);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1086
    rsb(tmp, count, 32, mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1087
    if (rd_lo == rn_lo) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1088
      mov(rd_lo, AsmOperand(rn_lo, lsr, count), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1089
      orr(rd_lo, rd_lo, AsmOperand(rn_hi, lsl, tmp), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1090
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1091
      mov(rd_lo, AsmOperand(rn_hi, lsl, tmp), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1092
      orr(rd_lo, rd_lo, AsmOperand(rn_lo, lsr, count), mi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1093
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1094
    mov(rd_hi, AsmOperand(rn_hi, shift, count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1095
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1096
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1097
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1098
void MacroAssembler::long_shift(Register rd_lo, Register rd_hi,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1099
                                Register rn_lo, Register rn_hi,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1100
                                AsmShift shift, int count) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1101
  assert(count != 0 && (count & ~63) == 0, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1102
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1103
  if (shift == lsl) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1104
    assert_different_registers(rd_hi, rn_lo);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1105
    if (count >= 32) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1106
      mov(rd_hi, AsmOperand(rn_lo, lsl, count - 32));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1107
      mov(rd_lo, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1108
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1109
      mov(rd_hi, AsmOperand(rn_hi, lsl, count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1110
      orr(rd_hi, rd_hi, AsmOperand(rn_lo, lsr, 32 - count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1111
      mov(rd_lo, AsmOperand(rn_lo, lsl, count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1112
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1113
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1114
    assert_different_registers(rd_lo, rn_hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1115
    if (count >= 32) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1116
      if (count == 32) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1117
        mov(rd_lo, rn_hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1118
      } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1119
        mov(rd_lo, AsmOperand(rn_hi, shift, count - 32));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1120
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1121
      if (shift == asr) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1122
        mov(rd_hi, AsmOperand(rn_hi, asr, 0));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1123
      } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1124
        mov(rd_hi, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1125
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1126
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1127
      mov(rd_lo, AsmOperand(rn_lo, lsr, count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1128
      orr(rd_lo, rd_lo, AsmOperand(rn_hi, lsl, 32 - count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1129
      mov(rd_hi, AsmOperand(rn_hi, shift, count));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1130
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1131
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1132
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1133
#endif // !AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1134
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1135
void MacroAssembler::_verify_oop(Register reg, const char* s, const char* file, int line) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1136
  // This code pattern is matched in NativeIntruction::skip_verify_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1137
  // Update it at modifications.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1138
  if (!VerifyOops) return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1139
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1140
  char buffer[64];
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1141
#ifdef COMPILER1
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1142
  if (CommentedAssembly) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1143
    snprintf(buffer, sizeof(buffer), "verify_oop at %d", offset());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1144
    block_comment(buffer);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1145
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1146
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1147
  const char* msg_buffer = NULL;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1148
  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1149
    ResourceMark rm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1150
    stringStream ss;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1151
    ss.print("%s at offset %d (%s:%d)", s, offset(), file, line);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1152
    msg_buffer = code_string(ss.as_string());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1153
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1154
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1155
  save_all_registers();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1156
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1157
  if (reg != R2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1158
      mov(R2, reg);                              // oop to verify
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1159
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1160
  mov(R1, SP);                                   // register save area
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1161
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1162
  Label done;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1163
  InlinedString Lmsg(msg_buffer);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1164
  ldr_literal(R0, Lmsg);                         // message
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1165
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1166
  // call indirectly to solve generation ordering problem
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1167
  ldr_global_ptr(Rtemp, StubRoutines::verify_oop_subroutine_entry_address());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1168
  call(Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1169
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1170
  restore_all_registers();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1171
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1172
  b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1173
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1174
  int off = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1175
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1176
  bind_literal(Lmsg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1177
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1178
  if (offset() - off == 1 * wordSize) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1179
    // no padding, so insert nop for worst-case sizing
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1180
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1181
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1182
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1183
  bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1184
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1185
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1186
void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* file, int line) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1187
  if (!VerifyOops) return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1188
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1189
  const char* msg_buffer = NULL;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1190
  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1191
    ResourceMark rm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1192
    stringStream ss;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1193
    if ((addr.base() == SP) && (addr.index()==noreg)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1194
      ss.print("verify_oop_addr SP[%d]: %s", (int)addr.disp(), s);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1195
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1196
      ss.print("verify_oop_addr: %s", s);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1197
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1198
    ss.print(" (%s:%d)", file, line);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1199
    msg_buffer = code_string(ss.as_string());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1200
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1201
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1202
  int push_size = save_all_registers();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1203
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1204
  if (addr.base() == SP) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1205
    // computes an addr that takes into account the push
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1206
    if (addr.index() != noreg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1207
      Register new_base = addr.index() == R2 ? R1 : R2; // avoid corrupting the index
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1208
      add(new_base, SP, push_size);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1209
      addr = addr.rebase(new_base);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1210
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1211
      addr = addr.plus_disp(push_size);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1212
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1213
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1214
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1215
  ldr(R2, addr);                                 // oop to verify
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1216
  mov(R1, SP);                                   // register save area
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1217
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1218
  Label done;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1219
  InlinedString Lmsg(msg_buffer);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1220
  ldr_literal(R0, Lmsg);                         // message
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1221
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1222
  // call indirectly to solve generation ordering problem
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1223
  ldr_global_ptr(Rtemp, StubRoutines::verify_oop_subroutine_entry_address());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1224
  call(Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1225
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1226
  restore_all_registers();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1227
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1228
  b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1229
  bind_literal(Lmsg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1230
  bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1231
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1232
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1233
void MacroAssembler::null_check(Register reg, Register tmp, int offset) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1234
  if (needs_explicit_null_check(offset)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1235
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1236
    ldr(ZR, Address(reg));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1237
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1238
    assert_different_registers(reg, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1239
    if (tmp == noreg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1240
      tmp = Rtemp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1241
      assert((! Thread::current()->is_Compiler_thread()) ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1242
             (! (ciEnv::current()->task() == NULL)) ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1243
             (! (ciEnv::current()->comp_level() == CompLevel_full_optimization)),
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1244
             "Rtemp not available in C2"); // explicit tmp register required
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1245
      // XXX: could we mark the code buffer as not compatible with C2 ?
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1246
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1247
    ldr(tmp, Address(reg));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1248
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1249
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1250
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1251
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1252
// Puts address of allocated object into register `obj` and end of allocated object into register `obj_end`.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1253
void MacroAssembler::eden_allocate(Register obj, Register obj_end, Register tmp1, Register tmp2,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1254
                                 RegisterOrConstant size_expression, Label& slow_case) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1255
  if (!Universe::heap()->supports_inline_contig_alloc()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1256
    b(slow_case);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1257
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1258
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1259
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1260
  CollectedHeap* ch = Universe::heap();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1261
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1262
  const Register top_addr = tmp1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1263
  const Register heap_end = tmp2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1264
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1265
  if (size_expression.is_register()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1266
    assert_different_registers(obj, obj_end, top_addr, heap_end, size_expression.as_register());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1267
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1268
    assert_different_registers(obj, obj_end, top_addr, heap_end);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1269
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1270
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1271
  bool load_const = AARCH64_ONLY(false) NOT_AARCH64(VM_Version::supports_movw() ); // TODO-AARCH64 check performance
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1272
  if (load_const) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1273
    mov_address(top_addr, (address)Universe::heap()->top_addr(), symbolic_Relocation::eden_top_reference);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1274
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1275
    ldr(top_addr, Address(Rthread, JavaThread::heap_top_addr_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1276
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1277
  // Calculate new heap_top by adding the size of the object
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1278
  Label retry;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1279
  bind(retry);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1280
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1281
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1282
  ldxr(obj, top_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1283
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1284
  ldr(obj, Address(top_addr));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1285
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1286
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1287
  ldr(heap_end, Address(top_addr, (intptr_t)ch->end_addr() - (intptr_t)ch->top_addr()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1288
  add_rc(obj_end, obj, size_expression);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1289
  // Check if obj_end wrapped around, i.e., obj_end < obj. If yes, jump to the slow case.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1290
  cmp(obj_end, obj);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1291
  b(slow_case, lo);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1292
  // Update heap_top if allocation succeeded
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1293
  cmp(obj_end, heap_end);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1294
  b(slow_case, hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1295
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1296
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1297
  stxr(heap_end/*scratched*/, obj_end, top_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1298
  cbnz_w(heap_end, retry);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1299
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1300
  atomic_cas_bool(obj, obj_end, top_addr, 0, heap_end/*scratched*/);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1301
  b(retry, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1302
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1303
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1304
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1305
// Puts address of allocated object into register `obj` and end of allocated object into register `obj_end`.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1306
void MacroAssembler::tlab_allocate(Register obj, Register obj_end, Register tmp1,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1307
                                 RegisterOrConstant size_expression, Label& slow_case) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1308
  const Register tlab_end = tmp1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1309
  assert_different_registers(obj, obj_end, tlab_end);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1310
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1311
  ldr(obj, Address(Rthread, JavaThread::tlab_top_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1312
  ldr(tlab_end, Address(Rthread, JavaThread::tlab_end_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1313
  add_rc(obj_end, obj, size_expression);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1314
  cmp(obj_end, tlab_end);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1315
  b(slow_case, hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1316
  str(obj_end, Address(Rthread, JavaThread::tlab_top_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1317
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1318
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1319
void MacroAssembler::tlab_refill(Register top, Register tmp1, Register tmp2,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1320
                                 Register tmp3, Register tmp4,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1321
                               Label& try_eden, Label& slow_case) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1322
  if (!Universe::heap()->supports_inline_contig_alloc()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1323
    b(slow_case);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1324
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1325
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1326
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1327
  InlinedAddress intArrayKlass_addr((address)Universe::intArrayKlassObj_addr());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1328
  Label discard_tlab, do_refill;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1329
  ldr(top,  Address(Rthread, JavaThread::tlab_top_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1330
  ldr(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1331
  ldr(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1332
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1333
  // Calculate amount of free space
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1334
  sub(tmp1, tmp1, top);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1335
  // Retain tlab and allocate in shared space
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1336
  // if the amount of free space in tlab is too large to discard
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1337
  cmp(tmp2, AsmOperand(tmp1, lsr, LogHeapWordSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1338
  b(discard_tlab, ge);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1339
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1340
  // Increment waste limit to prevent getting stuck on this slow path
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1341
  mov_slow(tmp3, ThreadLocalAllocBuffer::refill_waste_limit_increment());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1342
  add(tmp2, tmp2, tmp3);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1343
  str(tmp2, Address(Rthread, JavaThread::tlab_refill_waste_limit_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1344
  if (TLABStats) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1345
    ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1346
    add_32(tmp2, tmp2, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1347
    str_32(tmp2, Address(Rthread, JavaThread::tlab_slow_allocations_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1348
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1349
  b(try_eden);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1350
  bind_literal(intArrayKlass_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1351
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1352
  bind(discard_tlab);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1353
  if (TLABStats) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1354
    ldr_u32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1355
    ldr_u32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1356
    add_32(tmp2, tmp2, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1357
    add_32(tmp3, tmp3, AsmOperand(tmp1, lsr, LogHeapWordSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1358
    str_32(tmp2, Address(Rthread, JavaThread::tlab_number_of_refills_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1359
    str_32(tmp3, Address(Rthread, JavaThread::tlab_fast_refill_waste_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1360
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1361
  // If tlab is currently allocated (top or end != null)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1362
  // then fill [top, end + alignment_reserve) with array object
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1363
  cbz(top, do_refill);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1364
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1365
  // Set up the mark word
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1366
  mov_slow(tmp2, (intptr_t)markOopDesc::prototype()->copy_set_hash(0x2));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1367
  str(tmp2, Address(top, oopDesc::mark_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1368
  // Set klass to intArrayKlass and the length to the remaining space
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1369
  ldr_literal(tmp2, intArrayKlass_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1370
  add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes() -
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1371
      typeArrayOopDesc::header_size(T_INT) * HeapWordSize);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1372
  Register klass = tmp2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1373
  ldr(klass, Address(tmp2));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1374
  logical_shift_right(tmp1, tmp1, LogBytesPerInt); // divide by sizeof(jint)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1375
  str_32(tmp1, Address(top, arrayOopDesc::length_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1376
  store_klass(klass, top); // blows klass:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1377
  klass = noreg;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1378
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1379
  ldr(tmp1, Address(Rthread, JavaThread::tlab_start_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1380
  sub(tmp1, top, tmp1); // size of tlab's allocated portion
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1381
  incr_allocated_bytes(tmp1, tmp2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1382
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1383
  bind(do_refill);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1384
  // Refill the tlab with an eden allocation
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1385
  ldr(tmp1, Address(Rthread, JavaThread::tlab_size_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1386
  logical_shift_left(tmp4, tmp1, LogHeapWordSize);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1387
  eden_allocate(top, tmp1, tmp2, tmp3, tmp4, slow_case);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1388
  str(top, Address(Rthread, JavaThread::tlab_start_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1389
  str(top, Address(Rthread, JavaThread::tlab_top_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1390
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1391
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1392
  // Verify that tmp1 contains tlab_end
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1393
  ldr(tmp2, Address(Rthread, JavaThread::tlab_size_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1394
  add(tmp2, top, AsmOperand(tmp2, lsl, LogHeapWordSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1395
  cmp(tmp1, tmp2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1396
  breakpoint(ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1397
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1398
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1399
  sub(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1400
  str(tmp1, Address(Rthread, JavaThread::tlab_end_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1401
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1402
  if (ZeroTLAB) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1403
    // clobbers start and tmp
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1404
    // top must be preserved!
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1405
    add(tmp1, tmp1, ThreadLocalAllocBuffer::alignment_reserve_in_bytes());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1406
    ldr(tmp2, Address(Rthread, JavaThread::tlab_start_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1407
    zero_memory(tmp2, tmp1, tmp3);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1408
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1409
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1410
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1411
// Fills memory regions [start..end] with zeroes. Clobbers `start` and `tmp` registers.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1412
void MacroAssembler::zero_memory(Register start, Register end, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1413
  Label loop;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1414
  const Register ptr = start;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1415
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1416
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1417
  // TODO-AARCH64 - compare performance of 2x word zeroing with simple 1x
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1418
  const Register size = tmp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1419
  Label remaining, done;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1420
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1421
  sub(size, end, start);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1422
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1423
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1424
  { Label L;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1425
    tst(size, wordSize - 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1426
    b(L, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1427
    stop("size is not a multiple of wordSize");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1428
    bind(L);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1429
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1430
#endif // ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1431
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1432
  subs(size, size, wordSize);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1433
  b(remaining, le);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1434
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1435
  // Zero by 2 words per iteration.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1436
  bind(loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1437
  subs(size, size, 2*wordSize);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1438
  stp(ZR, ZR, Address(ptr, 2*wordSize, post_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1439
  b(loop, gt);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1440
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1441
  bind(remaining);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1442
  b(done, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1443
  str(ZR, Address(ptr));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1444
  bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1445
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1446
  mov(tmp, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1447
  bind(loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1448
  cmp(ptr, end);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1449
  str(tmp, Address(ptr, wordSize, post_indexed), lo);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1450
  b(loop, lo);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1451
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1452
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1453
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1454
void MacroAssembler::incr_allocated_bytes(RegisterOrConstant size_in_bytes, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1455
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1456
  ldr(tmp, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1457
  add_rc(tmp, tmp, size_in_bytes);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1458
  str(tmp, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1459
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1460
  // Bump total bytes allocated by this thread
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1461
  Label done;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1462
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1463
  ldr(tmp, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1464
  adds(tmp, tmp, size_in_bytes);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1465
  str(tmp, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())), cc);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1466
  b(done, cc);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1467
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1468
  // Increment the high word and store single-copy atomically (that is an unlikely scenario on typical embedded systems as it means >4GB has been allocated)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1469
  // To do so ldrd/strd instructions used which require an even-odd pair of registers. Such a request could be difficult to satisfy by
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1470
  // allocating those registers on a higher level, therefore the routine is ready to allocate a pair itself.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1471
  Register low, high;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1472
  // Select ether R0/R1 or R2/R3
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1473
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1474
  if (size_in_bytes.is_register() && (size_in_bytes.as_register() == R0 || size_in_bytes.as_register() == R1)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1475
    low = R2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1476
    high  = R3;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1477
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1478
    low = R0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1479
    high  = R1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1480
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1481
  push(RegisterSet(low, high));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1482
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1483
  ldrd(low, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1484
  adds(low, low, size_in_bytes);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1485
  adc(high, high, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1486
  strd(low, Address(Rthread, in_bytes(JavaThread::allocated_bytes_offset())));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1487
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1488
  pop(RegisterSet(low, high));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1489
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1490
  bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1491
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1492
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1493
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1494
void MacroAssembler::arm_stack_overflow_check(int frame_size_in_bytes, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1495
  // Version of AbstractAssembler::generate_stack_overflow_check optimized for ARM
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1496
  if (UseStackBanging) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1497
    const int page_size = os::vm_page_size();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1498
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1499
    sub_slow(tmp, SP, JavaThread::stack_shadow_zone_size());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1500
    strb(R0, Address(tmp));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1501
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1502
    for (; frame_size_in_bytes >= page_size; frame_size_in_bytes -= page_size) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1503
      sub(tmp, tmp, page_size);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1504
      strb(R0, Address(tmp));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1505
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1506
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1507
    for (; frame_size_in_bytes >= page_size; frame_size_in_bytes -= 0xff0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1508
      strb(R0, Address(tmp, -0xff0, pre_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1509
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1510
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1511
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1512
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1513
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1514
void MacroAssembler::arm_stack_overflow_check(Register Rsize, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1515
  if (UseStackBanging) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1516
    Label loop;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1517
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1518
    mov(tmp, SP);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1519
    add_slow(Rsize, Rsize, JavaThread::stack_shadow_zone_size() - os::vm_page_size());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1520
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1521
    sub(tmp, tmp, Rsize);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1522
    bind(loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1523
    subs(Rsize, Rsize, os::vm_page_size());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1524
    strb(ZR, Address(tmp, Rsize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1525
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1526
    bind(loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1527
    subs(Rsize, Rsize, 0xff0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1528
    strb(R0, Address(tmp, -0xff0, pre_indexed));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1529
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1530
    b(loop, hi);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1531
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1532
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1533
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1534
void MacroAssembler::stop(const char* msg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1535
  // This code pattern is matched in NativeIntruction::is_stop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1536
  // Update it at modifications.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1537
#ifdef COMPILER1
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1538
  if (CommentedAssembly) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1539
    block_comment("stop");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1540
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1541
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1542
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1543
  InlinedAddress Ldebug(CAST_FROM_FN_PTR(address, MacroAssembler::debug));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1544
  InlinedString Lmsg(msg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1545
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1546
  // save all registers for further inspection
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1547
  save_all_registers();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1548
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1549
  ldr_literal(R0, Lmsg);                     // message
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1550
  mov(R1, SP);                               // register save area
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1551
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1552
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1553
  ldr_literal(Rtemp, Ldebug);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1554
  br(Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1555
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1556
  ldr_literal(PC, Ldebug);                   // call MacroAssembler::debug
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1557
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1558
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1559
#if defined(COMPILER2) && defined(AARCH64)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1560
  int off = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1561
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1562
  bind_literal(Lmsg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1563
  bind_literal(Ldebug);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1564
#if defined(COMPILER2) && defined(AARCH64)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1565
  if (offset() - off == 2 * wordSize) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1566
    // no padding, so insert nop for worst-case sizing
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1567
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1568
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1569
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1570
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1571
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1572
void MacroAssembler::warn(const char* msg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1573
#ifdef COMPILER1
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1574
  if (CommentedAssembly) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1575
    block_comment("warn");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1576
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1577
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1578
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1579
  InlinedAddress Lwarn(CAST_FROM_FN_PTR(address, warning));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1580
  InlinedString Lmsg(msg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1581
  Label done;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1582
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1583
  int push_size = save_caller_save_registers();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1584
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1585
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1586
  // TODO-AARCH64 - get rid of extra debug parameters
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1587
  mov(R1, LR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1588
  mov(R2, FP);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1589
  add(R3, SP, push_size);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1590
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1591
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1592
  ldr_literal(R0, Lmsg);                    // message
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1593
  ldr_literal(LR, Lwarn);                   // call warning
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1594
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1595
  call(LR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1596
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1597
  restore_caller_save_registers();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1598
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1599
  b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1600
  bind_literal(Lmsg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1601
  bind_literal(Lwarn);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1602
  bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1603
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1604
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1605
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1606
int MacroAssembler::save_all_registers() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1607
  // This code pattern is matched in NativeIntruction::is_save_all_registers.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1608
  // Update it at modifications.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1609
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1610
  const Register tmp = Rtemp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1611
  raw_push(R30, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1612
  for (int i = 28; i >= 0; i -= 2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1613
      raw_push(as_Register(i), as_Register(i+1));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1614
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1615
  mov_pc_to(tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1616
  str(tmp, Address(SP, 31*wordSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1617
  ldr(tmp, Address(SP, tmp->encoding()*wordSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1618
  return 32*wordSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1619
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1620
  push(RegisterSet(R0, R12) | RegisterSet(LR) | RegisterSet(PC));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1621
  return 15*wordSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1622
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1623
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1624
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1625
void MacroAssembler::restore_all_registers() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1626
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1627
  for (int i = 0; i <= 28; i += 2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1628
    raw_pop(as_Register(i), as_Register(i+1));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1629
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1630
  raw_pop(R30, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1631
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1632
  pop(RegisterSet(R0, R12) | RegisterSet(LR));   // restore registers
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1633
  add(SP, SP, wordSize);                         // discard saved PC
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1634
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1635
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1636
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1637
int MacroAssembler::save_caller_save_registers() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1638
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1639
  for (int i = 0; i <= 16; i += 2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1640
    raw_push(as_Register(i), as_Register(i+1));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1641
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1642
  raw_push(R18, LR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1643
  return 20*wordSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1644
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1645
#if R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1646
  // Save also R10 to preserve alignment
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1647
  push(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(LR) | RegisterSet(R9,R10));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1648
  return 8*wordSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1649
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1650
  push(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(LR));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1651
  return 6*wordSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1652
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1653
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1654
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1655
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1656
void MacroAssembler::restore_caller_save_registers() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1657
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1658
  raw_pop(R18, LR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1659
  for (int i = 16; i >= 0; i -= 2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1660
    raw_pop(as_Register(i), as_Register(i+1));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1661
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1662
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1663
#if R9_IS_SCRATCHED
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1664
  pop(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(LR) | RegisterSet(R9,R10));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1665
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1666
  pop(RegisterSet(R0, R3) | RegisterSet(R12) | RegisterSet(LR));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1667
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1668
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1669
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1670
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1671
void MacroAssembler::debug(const char* msg, const intx* registers) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1672
  // In order to get locks to work, we need to fake a in_VM state
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1673
  JavaThread* thread = JavaThread::current();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1674
  thread->set_thread_state(_thread_in_vm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1675
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1676
  if (ShowMessageBoxOnError) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1677
    ttyLocker ttyl;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1678
    if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1679
      BytecodeCounter::print();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1680
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1681
    if (os::message_box(msg, "Execution stopped, print registers?")) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1682
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1683
      // saved registers: R0-R30, PC
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1684
      const int nregs = 32;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1685
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1686
      // saved registers: R0-R12, LR, PC
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1687
      const int nregs = 15;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1688
      const Register regs[nregs] = {R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, PC};
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1689
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1690
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1691
      for (int i = 0; i < nregs AARCH64_ONLY(-1); i++) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1692
        tty->print_cr("%s = " INTPTR_FORMAT, AARCH64_ONLY(as_Register(i)) NOT_AARCH64(regs[i])->name(), registers[i]);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1693
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1694
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1695
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1696
      tty->print_cr("pc = " INTPTR_FORMAT, registers[nregs-1]);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1697
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1698
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1699
      // derive original SP value from the address of register save area
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1700
      tty->print_cr("%s = " INTPTR_FORMAT, SP->name(), p2i(&registers[nregs]));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1701
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1702
    BREAKPOINT;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1703
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1704
    ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n", msg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1705
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1706
  assert(false, "DEBUG MESSAGE: %s", msg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1707
  fatal("%s", msg); // returning from MacroAssembler::debug is not supported
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1708
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1709
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1710
void MacroAssembler::unimplemented(const char* what) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1711
  const char* buf = NULL;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1712
  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1713
    ResourceMark rm;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1714
    stringStream ss;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1715
    ss.print("unimplemented: %s", what);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1716
    buf = code_string(ss.as_string());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1717
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1718
  stop(buf);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1719
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1720
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1721
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1722
// Implementation of FixedSizeCodeBlock
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1723
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1724
FixedSizeCodeBlock::FixedSizeCodeBlock(MacroAssembler* masm, int size_in_instrs, bool enabled) :
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1725
_masm(masm), _start(masm->pc()), _size_in_instrs(size_in_instrs), _enabled(enabled) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1726
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1727
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1728
FixedSizeCodeBlock::~FixedSizeCodeBlock() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1729
  if (_enabled) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1730
    address curr_pc = _masm->pc();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1731
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1732
    assert(_start < curr_pc, "invalid current pc");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1733
    guarantee(curr_pc <= _start + _size_in_instrs * Assembler::InstructionSize, "code block is too long");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1734
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1735
    int nops_count = (_start - curr_pc) / Assembler::InstructionSize + _size_in_instrs;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1736
    for (int i = 0; i < nops_count; i++) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1737
      _masm->nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1738
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1739
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1740
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1741
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1742
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1743
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1744
// Serializes memory.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1745
// tmp register is not used on AArch64, this parameter is provided solely for better compatibility with 32-bit ARM
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1746
void MacroAssembler::membar(Membar_mask_bits order_constraint, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1747
  if (!os::is_MP()) return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1748
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1749
  // TODO-AARCH64 investigate dsb vs dmb effects
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1750
  if (order_constraint == StoreStore) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1751
    dmb(DMB_st);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1752
  } else if ((order_constraint & ~(LoadLoad | LoadStore)) == 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1753
    dmb(DMB_ld);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1754
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1755
    dmb(DMB_all);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1756
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1757
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1758
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1759
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1760
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1761
// Serializes memory. Potentially blows flags and reg.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1762
// tmp is a scratch for v6 co-processor write op (could be noreg for other architecure versions)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1763
// preserve_flags takes a longer path in LoadStore case (dmb rather then control dependency) to preserve status flags. Optional.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1764
// load_tgt is an ordered load target in a LoadStore case only, to create dependency between the load operation and conditional branch. Optional.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1765
void MacroAssembler::membar(Membar_mask_bits order_constraint,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1766
                            Register tmp,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1767
                            bool preserve_flags,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1768
                            Register load_tgt) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1769
  if (!os::is_MP()) return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1770
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1771
  if (order_constraint == StoreStore) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1772
    dmb(DMB_st, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1773
  } else if ((order_constraint & StoreLoad)  ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1774
             (order_constraint & LoadLoad)   ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1775
             (order_constraint & StoreStore) ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1776
             (load_tgt == noreg)             ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1777
             preserve_flags) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1778
    dmb(DMB_all, tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1779
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1780
    // LoadStore: speculative stores reordeing is prohibited
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1781
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1782
    // By providing an ordered load target register, we avoid an extra memory load reference
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1783
    Label not_taken;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1784
    bind(not_taken);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1785
    cmp(load_tgt, load_tgt);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1786
    b(not_taken, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1787
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1788
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1789
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1790
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1791
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1792
// If "allow_fallthrough_on_failure" is false, we always branch to "slow_case"
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1793
// on failure, so fall-through can only mean success.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1794
// "one_shot" controls whether we loop and retry to mitigate spurious failures.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1795
// This is only needed for C2, which for some reason does not rety,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1796
// while C1/interpreter does.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1797
// TODO: measure if it makes a difference
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1798
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1799
void MacroAssembler::cas_for_lock_acquire(Register oldval, Register newval,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1800
  Register base, Register tmp, Label &slow_case,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1801
  bool allow_fallthrough_on_failure, bool one_shot)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1802
{
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1803
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1804
  bool fallthrough_is_success = false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1805
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1806
  // ARM Litmus Test example does prefetching here.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1807
  // TODO: investigate if it helps performance
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1808
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1809
  // The last store was to the displaced header, so to prevent
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1810
  // reordering we must issue a StoreStore or Release barrier before
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1811
  // the CAS store.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1812
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1813
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1814
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1815
  Register Rscratch = tmp;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1816
  Register Roop = base;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1817
  Register mark = oldval;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1818
  Register Rbox = newval;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1819
  Label loop;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1820
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1821
  assert(oopDesc::mark_offset_in_bytes() == 0, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1822
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1823
  // Instead of StoreStore here, we use store-release-exclusive below
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1824
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1825
  bind(loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1826
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1827
  ldaxr(tmp, base);  // acquire
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1828
  cmp(tmp, oldval);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1829
  b(slow_case, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1830
  stlxr(tmp, newval, base); // release
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1831
  if (one_shot) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1832
    cmp_w(tmp, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1833
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1834
    cbnz_w(tmp, loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1835
    fallthrough_is_success = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1836
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1837
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1838
  // MemBarAcquireLock would normally go here, but
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1839
  // we already do ldaxr+stlxr above, which has
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1840
  // Sequential Consistency
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1841
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1842
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1843
  membar(MacroAssembler::StoreStore, noreg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1844
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1845
  if (one_shot) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1846
    ldrex(tmp, Address(base, oopDesc::mark_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1847
    cmp(tmp, oldval);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1848
    strex(tmp, newval, Address(base, oopDesc::mark_offset_in_bytes()), eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1849
    cmp(tmp, 0, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1850
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1851
    atomic_cas_bool(oldval, newval, base, oopDesc::mark_offset_in_bytes(), tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1852
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1853
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1854
  // MemBarAcquireLock barrier
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1855
  // According to JSR-133 Cookbook, this should be LoadLoad | LoadStore,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1856
  // but that doesn't prevent a load or store from floating up between
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1857
  // the load and store in the CAS sequence, so play it safe and
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1858
  // do a full fence.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1859
  membar(Membar_mask_bits(LoadLoad | LoadStore | StoreStore | StoreLoad), noreg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1860
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1861
  if (!fallthrough_is_success && !allow_fallthrough_on_failure) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1862
    b(slow_case, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1863
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1864
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1865
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1866
void MacroAssembler::cas_for_lock_release(Register oldval, Register newval,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1867
  Register base, Register tmp, Label &slow_case,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1868
  bool allow_fallthrough_on_failure, bool one_shot)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1869
{
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1870
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1871
  bool fallthrough_is_success = false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1872
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1873
  assert_different_registers(oldval,newval,base,tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1874
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1875
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1876
  Label loop;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1877
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1878
  assert(oopDesc::mark_offset_in_bytes() == 0, "must be");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1879
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1880
  bind(loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1881
  ldxr(tmp, base);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1882
  cmp(tmp, oldval);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1883
  b(slow_case, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1884
  // MemBarReleaseLock barrier
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1885
  stlxr(tmp, newval, base);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1886
  if (one_shot) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1887
    cmp_w(tmp, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1888
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1889
    cbnz_w(tmp, loop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1890
    fallthrough_is_success = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1891
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1892
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1893
  // MemBarReleaseLock barrier
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1894
  // According to JSR-133 Cookbook, this should be StoreStore | LoadStore,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1895
  // but that doesn't prevent a load or store from floating down between
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1896
  // the load and store in the CAS sequence, so play it safe and
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1897
  // do a full fence.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1898
  membar(Membar_mask_bits(LoadLoad | LoadStore | StoreStore | StoreLoad), tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1899
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1900
  if (one_shot) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1901
    ldrex(tmp, Address(base, oopDesc::mark_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1902
    cmp(tmp, oldval);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1903
    strex(tmp, newval, Address(base, oopDesc::mark_offset_in_bytes()), eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1904
    cmp(tmp, 0, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1905
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1906
    atomic_cas_bool(oldval, newval, base, oopDesc::mark_offset_in_bytes(), tmp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1907
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1908
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1909
  if (!fallthrough_is_success && !allow_fallthrough_on_failure) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1910
    b(slow_case, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1911
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1912
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1913
  // ExitEnter
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1914
  // According to JSR-133 Cookbook, this should be StoreLoad, the same
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1915
  // barrier that follows volatile store.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1916
  // TODO: Should be able to remove on armv8 if volatile loads
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1917
  // use the load-acquire instruction.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1918
  membar(StoreLoad, noreg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1919
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1920
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1921
#ifndef PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1922
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1923
// Preserves flags and all registers.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1924
// On SMP the updated value might not be visible to external observers without a sychronization barrier
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1925
void MacroAssembler::cond_atomic_inc32(AsmCondition cond, int* counter_addr) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1926
  if (counter_addr != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1927
    InlinedAddress counter_addr_literal((address)counter_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1928
    Label done, retry;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1929
    if (cond != al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1930
      b(done, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1931
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1932
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1933
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1934
    raw_push(R0, R1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1935
    raw_push(R2, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1936
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1937
    ldr_literal(R0, counter_addr_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1938
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1939
    bind(retry);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1940
    ldxr_w(R1, R0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1941
    add_w(R1, R1, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1942
    stxr_w(R2, R1, R0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1943
    cbnz_w(R2, retry);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1944
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1945
    raw_pop(R2, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1946
    raw_pop(R0, R1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1947
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1948
    push(RegisterSet(R0, R3) | RegisterSet(Rtemp));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1949
    ldr_literal(R0, counter_addr_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1950
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1951
    mrs(CPSR, Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1952
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1953
    bind(retry);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1954
    ldr_s32(R1, Address(R0));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1955
    add(R2, R1, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1956
    atomic_cas_bool(R1, R2, R0, 0, R3);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1957
    b(retry, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1958
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1959
    msr(CPSR_fsxc, Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1960
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1961
    pop(RegisterSet(R0, R3) | RegisterSet(Rtemp));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1962
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1963
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1964
    b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1965
    bind_literal(counter_addr_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1966
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1967
    bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1968
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1969
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1970
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1971
#endif // !PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1972
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1973
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1974
// Building block for CAS cases of biased locking: makes CAS and records statistics.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1975
// The slow_case label is used to transfer control if CAS fails. Otherwise leaves condition codes set.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1976
void MacroAssembler::biased_locking_enter_with_cas(Register obj_reg, Register old_mark_reg, Register new_mark_reg,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1977
                                                 Register tmp, Label& slow_case, int* counter_addr) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1978
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1979
  cas_for_lock_acquire(old_mark_reg, new_mark_reg, obj_reg, tmp, slow_case);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1980
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1981
  breakpoint(ne); // Fallthrough only on success
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1982
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1983
#ifndef PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1984
  if (counter_addr != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1985
    cond_atomic_inc32(al, counter_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1986
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1987
#endif // !PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1988
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1989
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1990
int MacroAssembler::biased_locking_enter(Register obj_reg, Register swap_reg, Register tmp_reg,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1991
                                         bool swap_reg_contains_mark,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1992
                                         Register tmp2,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1993
                                         Label& done, Label& slow_case,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1994
                                         BiasedLockingCounters* counters) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1995
  // obj_reg must be preserved (at least) if the bias locking fails
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1996
  // tmp_reg is a temporary register
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1997
  // swap_reg was used as a temporary but contained a value
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1998
  //   that was used afterwards in some call pathes. Callers
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  1999
  //   have been fixed so that swap_reg no longer needs to be
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2000
  //   saved.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2001
  // Rtemp in no longer scratched
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2002
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2003
  assert(UseBiasedLocking, "why call this otherwise?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2004
  assert_different_registers(obj_reg, swap_reg, tmp_reg, tmp2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2005
  guarantee(swap_reg!=tmp_reg, "invariant");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2006
  assert(tmp_reg != noreg, "must supply tmp_reg");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2007
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2008
#ifndef PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2009
  if (PrintBiasedLockingStatistics && (counters == NULL)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2010
    counters = BiasedLocking::counters();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2011
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2012
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2013
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2014
  assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2015
  Address mark_addr(obj_reg, oopDesc::mark_offset_in_bytes());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2016
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2017
  // Biased locking
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2018
  // See whether the lock is currently biased toward our thread and
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2019
  // whether the epoch is still valid
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2020
  // Note that the runtime guarantees sufficient alignment of JavaThread
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2021
  // pointers to allow age to be placed into low bits
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2022
  // First check to see whether biasing is even enabled for this object
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2023
  Label cas_label;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2024
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2025
  // The null check applies to the mark loading, if we need to load it.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2026
  // If the mark has already been loaded in swap_reg then it has already
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2027
  // been performed and the offset is irrelevant.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2028
  int null_check_offset = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2029
  if (!swap_reg_contains_mark) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2030
    ldr(swap_reg, mark_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2031
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2032
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2033
  // On MP platform loads could return 'stale' values in some cases.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2034
  // That is acceptable since either CAS or slow case path is taken in the worst case.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2035
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2036
  andr(tmp_reg, swap_reg, (uintx)markOopDesc::biased_lock_mask_in_place);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2037
  cmp(tmp_reg, markOopDesc::biased_lock_pattern);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2038
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2039
  b(cas_label, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2040
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2041
  // The bias pattern is present in the object's header. Need to check
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2042
  // whether the bias owner and the epoch are both still current.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2043
  load_klass(tmp_reg, obj_reg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2044
  ldr(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2045
  orr(tmp_reg, tmp_reg, Rthread);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2046
  eor(tmp_reg, tmp_reg, swap_reg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2047
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2048
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2049
  ands(tmp_reg, tmp_reg, ~((uintx) markOopDesc::age_mask_in_place));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2050
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2051
  bics(tmp_reg, tmp_reg, ((int) markOopDesc::age_mask_in_place));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2052
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2053
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2054
#ifndef PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2055
  if (counters != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2056
    cond_atomic_inc32(eq, counters->biased_lock_entry_count_addr());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2057
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2058
#endif // !PRODUCT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2059
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2060
  b(done, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2061
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2062
  Label try_revoke_bias;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2063
  Label try_rebias;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2064
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2065
  // At this point we know that the header has the bias pattern and
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2066
  // that we are not the bias owner in the current epoch. We need to
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2067
  // figure out more details about the state of the header in order to
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2068
  // know what operations can be legally performed on the object's
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2069
  // header.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2070
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2071
  // If the low three bits in the xor result aren't clear, that means
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2072
  // the prototype header is no longer biased and we have to revoke
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2073
  // the bias on this object.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2074
  tst(tmp_reg, (uintx)markOopDesc::biased_lock_mask_in_place);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2075
  b(try_revoke_bias, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2076
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2077
  // Biasing is still enabled for this data type. See whether the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2078
  // epoch of the current bias is still valid, meaning that the epoch
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2079
  // bits of the mark word are equal to the epoch bits of the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2080
  // prototype header. (Note that the prototype header's epoch bits
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2081
  // only change at a safepoint.) If not, attempt to rebias the object
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2082
  // toward the current thread. Note that we must be absolutely sure
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2083
  // that the current epoch is invalid in order to do this because
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2084
  // otherwise the manipulations it performs on the mark word are
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2085
  // illegal.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2086
  tst(tmp_reg, (uintx)markOopDesc::epoch_mask_in_place);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2087
  b(try_rebias, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2088
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2089
  // tmp_reg has the age, epoch and pattern bits cleared
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2090
  // The remaining (owner) bits are (Thread ^ current_owner)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2091
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2092
  // The epoch of the current bias is still valid but we know nothing
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2093
  // about the owner; it might be set or it might be clear. Try to
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2094
  // acquire the bias of the object using an atomic operation. If this
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2095
  // fails we will go in to the runtime to revoke the object's bias.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2096
  // Note that we first construct the presumed unbiased header so we
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2097
  // don't accidentally blow away another thread's valid bias.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2098
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2099
  // Note that we know the owner is not ourself. Hence, success can
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2100
  // only happen when the owner bits is 0
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2101
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2102
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2103
  // Bit mask biased_lock + age + epoch is not a valid AArch64 logical immediate, as it has
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2104
  // cleared bit in the middle (cms bit). So it is loaded with separate instruction.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2105
  mov(tmp2, (markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2106
  andr(swap_reg, swap_reg, tmp2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2107
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2108
  // until the assembler can be made smarter, we need to make some assumptions about the values
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2109
  // so we can optimize this:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2110
  assert((markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place) == 0x1ff, "biased bitmasks changed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2111
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2112
  mov(swap_reg, AsmOperand(swap_reg, lsl, 23));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2113
  mov(swap_reg, AsmOperand(swap_reg, lsr, 23)); // markOop with thread bits cleared (for CAS)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2114
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2115
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2116
  orr(tmp_reg, swap_reg, Rthread); // new mark
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2117
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2118
  biased_locking_enter_with_cas(obj_reg, swap_reg, tmp_reg, tmp2, slow_case,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2119
        (counters != NULL) ? counters->anonymously_biased_lock_entry_count_addr() : NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2120
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2121
  // If the biasing toward our thread failed, this means that
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2122
  // another thread succeeded in biasing it toward itself and we
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2123
  // need to revoke that bias. The revocation will occur in the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2124
  // interpreter runtime in the slow case.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2125
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2126
  b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2127
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2128
  bind(try_rebias);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2129
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2130
  // At this point we know the epoch has expired, meaning that the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2131
  // current "bias owner", if any, is actually invalid. Under these
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2132
  // circumstances _only_, we are allowed to use the current header's
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2133
  // value as the comparison value when doing the cas to acquire the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2134
  // bias in the current epoch. In other words, we allow transfer of
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2135
  // the bias from one thread to another directly in this situation.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2136
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2137
  // tmp_reg low (not owner) bits are (age: 0 | pattern&epoch: prototype^swap_reg)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2138
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2139
  eor(tmp_reg, tmp_reg, swap_reg); // OK except for owner bits (age preserved !)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2140
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2141
  // owner bits 'random'. Set them to Rthread.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2142
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2143
  mov(tmp2, (markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2144
  andr(tmp_reg, tmp_reg, tmp2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2145
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2146
  mov(tmp_reg, AsmOperand(tmp_reg, lsl, 23));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2147
  mov(tmp_reg, AsmOperand(tmp_reg, lsr, 23));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2148
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2149
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2150
  orr(tmp_reg, tmp_reg, Rthread); // new mark
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2151
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2152
  biased_locking_enter_with_cas(obj_reg, swap_reg, tmp_reg, tmp2, slow_case,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2153
        (counters != NULL) ? counters->rebiased_lock_entry_count_addr() : NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2154
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2155
  // If the biasing toward our thread failed, then another thread
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2156
  // succeeded in biasing it toward itself and we need to revoke that
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2157
  // bias. The revocation will occur in the runtime in the slow case.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2158
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2159
  b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2160
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2161
  bind(try_revoke_bias);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2162
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2163
  // The prototype mark in the klass doesn't have the bias bit set any
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2164
  // more, indicating that objects of this data type are not supposed
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2165
  // to be biased any more. We are going to try to reset the mark of
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2166
  // this object to the prototype value and fall through to the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2167
  // CAS-based locking scheme. Note that if our CAS fails, it means
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2168
  // that another thread raced us for the privilege of revoking the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2169
  // bias of this particular object, so it's okay to continue in the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2170
  // normal locking code.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2171
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2172
  // tmp_reg low (not owner) bits are (age: 0 | pattern&epoch: prototype^swap_reg)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2173
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2174
  eor(tmp_reg, tmp_reg, swap_reg); // OK except for owner bits (age preserved !)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2175
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2176
  // owner bits 'random'. Clear them
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2177
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2178
  mov(tmp2, (markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2179
  andr(tmp_reg, tmp_reg, tmp2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2180
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2181
  mov(tmp_reg, AsmOperand(tmp_reg, lsl, 23));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2182
  mov(tmp_reg, AsmOperand(tmp_reg, lsr, 23));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2183
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2184
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2185
  biased_locking_enter_with_cas(obj_reg, swap_reg, tmp_reg, tmp2, cas_label,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2186
        (counters != NULL) ? counters->revoked_lock_entry_count_addr() : NULL);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2187
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2188
  // Fall through to the normal CAS-based lock, because no matter what
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2189
  // the result of the above CAS, some thread must have succeeded in
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2190
  // removing the bias bit from the object's header.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2191
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2192
  bind(cas_label);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2193
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2194
  return null_check_offset;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2195
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2196
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2197
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2198
void MacroAssembler::biased_locking_exit(Register obj_reg, Register tmp_reg, Label& done) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2199
  assert(UseBiasedLocking, "why call this otherwise?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2200
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2201
  // Check for biased locking unlock case, which is a no-op
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2202
  // Note: we do not have to check the thread ID for two reasons.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2203
  // First, the interpreter checks for IllegalMonitorStateException at
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2204
  // a higher level. Second, if the bias was revoked while we held the
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2205
  // lock, the object could not be rebiased toward another thread, so
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2206
  // the bias bit would be clear.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2207
  ldr(tmp_reg, Address(obj_reg, oopDesc::mark_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2208
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2209
  andr(tmp_reg, tmp_reg, (uintx)markOopDesc::biased_lock_mask_in_place);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2210
  cmp(tmp_reg, markOopDesc::biased_lock_pattern);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2211
  b(done, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2212
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2213
44406
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2214
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2215
void MacroAssembler::resolve_jobject(Register value,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2216
                                     Register tmp1,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2217
                                     Register tmp2) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2218
  assert_different_registers(value, tmp1, tmp2);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2219
  Label done, not_weak;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2220
  cbz(value, done);             // Use NULL as-is.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2221
  STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2222
  tbz(value, 0, not_weak);      // Test for jweak tag.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2223
  // Resolve jweak.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2224
  ldr(value, Address(value, -JNIHandles::weak_tag_value));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2225
  verify_oop(value);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2226
#if INCLUDE_ALL_GCS
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2227
  if (UseG1GC) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2228
    g1_write_barrier_pre(noreg, // store_addr
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2229
                         noreg, // new_val
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2230
                         value, // pre_val
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2231
                         tmp1,  // tmp1
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2232
                         tmp2); // tmp2
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2233
    }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2234
#endif // INCLUDE_ALL_GCS
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2235
  b(done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2236
  bind(not_weak);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2237
  // Resolve (untagged) jobject.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2238
  ldr(value, Address(value));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2239
  verify_oop(value);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2240
  bind(done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2241
}
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2242
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2243
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2244
//////////////////////////////////////////////////////////////////////////////////
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2245
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2246
#if INCLUDE_ALL_GCS
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2247
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2248
// G1 pre-barrier.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2249
// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2250
// If store_addr != noreg, then previous value is loaded from [store_addr];
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2251
// in such case store_addr and new_val registers are preserved;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2252
// otherwise pre_val register is preserved.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2253
void MacroAssembler::g1_write_barrier_pre(Register store_addr,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2254
                                          Register new_val,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2255
                                          Register pre_val,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2256
                                          Register tmp1,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2257
                                          Register tmp2) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2258
  Label done;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2259
  Label runtime;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2260
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2261
  if (store_addr != noreg) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2262
    assert_different_registers(store_addr, new_val, pre_val, tmp1, tmp2, noreg);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2263
  } else {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2264
    assert (new_val == noreg, "should be");
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2265
    assert_different_registers(pre_val, tmp1, tmp2, noreg);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2266
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2267
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2268
  Address in_progress(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2269
                                        SATBMarkQueue::byte_offset_of_active()));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2270
  Address index(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2271
                                  SATBMarkQueue::byte_offset_of_index()));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2272
  Address buffer(Rthread, in_bytes(JavaThread::satb_mark_queue_offset() +
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2273
                                   SATBMarkQueue::byte_offset_of_buf()));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2274
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2275
  // Is marking active?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2276
  assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "adjust this code");
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2277
  ldrb(tmp1, in_progress);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2278
  cbz(tmp1, done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2279
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2280
  // Do we need to load the previous value?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2281
  if (store_addr != noreg) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2282
    load_heap_oop(pre_val, Address(store_addr, 0));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2283
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2284
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2285
  // Is the previous value null?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2286
  cbz(pre_val, done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2287
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2288
  // Can we store original value in the thread's buffer?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2289
  // Is index == 0?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2290
  // (The index field is typed as size_t.)
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2291
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2292
  ldr(tmp1, index);           // tmp1 := *index_adr
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2293
  ldr(tmp2, buffer);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2294
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2295
  subs(tmp1, tmp1, wordSize); // tmp1 := tmp1 - wordSize
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2296
  b(runtime, lt);             // If negative, goto runtime
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2297
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2298
  str(tmp1, index);           // *index_adr := tmp1
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2299
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2300
  // Record the previous value
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2301
  str(pre_val, Address(tmp2, tmp1));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2302
  b(done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2303
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2304
  bind(runtime);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2305
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2306
  // save the live input values
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2307
#ifdef AARCH64
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2308
  if (store_addr != noreg) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2309
    raw_push(store_addr, new_val);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2310
  } else {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2311
    raw_push(pre_val, ZR);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2312
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2313
#else
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2314
  if (store_addr != noreg) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2315
    // avoid raw_push to support any ordering of store_addr and new_val
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2316
    push(RegisterSet(store_addr) | RegisterSet(new_val));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2317
  } else {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2318
    push(pre_val);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2319
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2320
#endif // AARCH64
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2321
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2322
  if (pre_val != R0) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2323
    mov(R0, pre_val);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2324
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2325
  mov(R1, Rthread);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2326
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2327
  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), R0, R1);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2328
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2329
#ifdef AARCH64
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2330
  if (store_addr != noreg) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2331
    raw_pop(store_addr, new_val);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2332
  } else {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2333
    raw_pop(pre_val, ZR);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2334
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2335
#else
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2336
  if (store_addr != noreg) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2337
    pop(RegisterSet(store_addr) | RegisterSet(new_val));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2338
  } else {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2339
    pop(pre_val);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2340
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2341
#endif // AARCH64
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2342
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2343
  bind(done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2344
}
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2345
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2346
// G1 post-barrier.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2347
// Blows all volatile registers (R0-R3 on 32-bit ARM, R0-R18 on AArch64, Rtemp, LR).
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2348
void MacroAssembler::g1_write_barrier_post(Register store_addr,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2349
                                           Register new_val,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2350
                                           Register tmp1,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2351
                                           Register tmp2,
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2352
                                           Register tmp3) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2353
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2354
  Address queue_index(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2355
                                        DirtyCardQueue::byte_offset_of_index()));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2356
  Address buffer(Rthread, in_bytes(JavaThread::dirty_card_queue_offset() +
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2357
                                   DirtyCardQueue::byte_offset_of_buf()));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2358
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2359
  BarrierSet* bs = Universe::heap()->barrier_set();
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2360
  CardTableModRefBS* ct = (CardTableModRefBS*)bs;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2361
  Label done;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2362
  Label runtime;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2363
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2364
  // Does store cross heap regions?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2365
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2366
  eor(tmp1, store_addr, new_val);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2367
#ifdef AARCH64
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2368
  logical_shift_right(tmp1, tmp1, HeapRegion::LogOfHRGrainBytes);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2369
  cbz(tmp1, done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2370
#else
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2371
  movs(tmp1, AsmOperand(tmp1, lsr, HeapRegion::LogOfHRGrainBytes));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2372
  b(done, eq);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2373
#endif
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2374
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2375
  // crosses regions, storing NULL?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2376
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2377
  cbz(new_val, done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2378
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2379
  // storing region crossing non-NULL, is card already dirty?
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2380
  const Register card_addr = tmp1;
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2381
  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2382
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2383
  mov_address(tmp2, (address)ct->byte_map_base, symbolic_Relocation::card_table_reference);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2384
  add(card_addr, tmp2, AsmOperand(store_addr, lsr, CardTableModRefBS::card_shift));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2385
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2386
  ldrb(tmp2, Address(card_addr));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2387
  cmp(tmp2, (int)G1SATBCardTableModRefBS::g1_young_card_val());
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2388
  b(done, eq);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2389
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2390
  membar(MacroAssembler::Membar_mask_bits(MacroAssembler::StoreLoad), tmp2);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2391
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2392
  assert(CardTableModRefBS::dirty_card_val() == 0, "adjust this code");
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2393
  ldrb(tmp2, Address(card_addr));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2394
  cbz(tmp2, done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2395
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2396
  // storing a region crossing, non-NULL oop, card is clean.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2397
  // dirty card and log.
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2398
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2399
  strb(zero_register(tmp2), Address(card_addr));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2400
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2401
  ldr(tmp2, queue_index);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2402
  ldr(tmp3, buffer);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2403
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2404
  subs(tmp2, tmp2, wordSize);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2405
  b(runtime, lt); // go to runtime if now negative
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2406
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2407
  str(tmp2, queue_index);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2408
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2409
  str(card_addr, Address(tmp3, tmp2));
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2410
  b(done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2411
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2412
  bind(runtime);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2413
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2414
  if (card_addr != R0) {
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2415
    mov(R0, card_addr);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2416
  }
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2417
  mov(R1, Rthread);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2418
  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), R0, R1);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2419
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2420
  bind(done);
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2421
}
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2422
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2423
#endif // INCLUDE_ALL_GCS
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2424
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2425
//////////////////////////////////////////////////////////////////////////////////
a46a6c4d1dd9 8176100: [REDO][REDO] G1 Needs pre barrier on dereference of weak JNI handles
mgerdin
parents: 44093
diff changeset
  2426
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2427
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2428
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2429
void MacroAssembler::load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2430
  switch (size_in_bytes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2431
    case  8: ldr(dst, src); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2432
    case  4: is_signed ? ldr_s32(dst, src) : ldr_u32(dst, src); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2433
    case  2: is_signed ? ldrsh(dst, src) : ldrh(dst, src); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2434
    case  1: is_signed ? ldrsb(dst, src) : ldrb(dst, src); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2435
    default: ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2436
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2437
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2438
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2439
void MacroAssembler::store_sized_value(Register src, Address dst, size_t size_in_bytes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2440
  switch (size_in_bytes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2441
    case  8: str(src, dst);    break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2442
    case  4: str_32(src, dst); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2443
    case  2: strh(src, dst);   break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2444
    case  1: strb(src, dst);   break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2445
    default: ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2446
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2447
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2448
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2449
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2450
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2451
void MacroAssembler::load_sized_value(Register dst, Address src,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2452
                                    size_t size_in_bytes, bool is_signed, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2453
  switch (size_in_bytes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2454
    case  4: ldr(dst, src, cond); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2455
    case  2: is_signed ? ldrsh(dst, src, cond) : ldrh(dst, src, cond); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2456
    case  1: is_signed ? ldrsb(dst, src, cond) : ldrb(dst, src, cond); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2457
    default: ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2458
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2459
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2460
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2461
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2462
void MacroAssembler::store_sized_value(Register src, Address dst, size_t size_in_bytes, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2463
  switch (size_in_bytes) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2464
    case  4: str(src, dst, cond); break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2465
    case  2: strh(src, dst, cond);   break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2466
    case  1: strb(src, dst, cond);   break;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2467
    default: ShouldNotReachHere();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2468
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2469
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2470
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2471
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2472
// Look up the method for a megamorphic invokeinterface call.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2473
// The target method is determined by <Rinterf, Rindex>.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2474
// The receiver klass is in Rklass.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2475
// On success, the result will be in method_result, and execution falls through.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2476
// On failure, execution transfers to the given label.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2477
void MacroAssembler::lookup_interface_method(Register Rklass,
48557
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2478
                                             Register Rintf,
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2479
                                             RegisterOrConstant itable_index,
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2480
                                             Register method_result,
48557
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2481
                                             Register Rscan,
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2482
                                             Register Rtmp,
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2483
                                             Label& L_no_such_interface) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2484
48557
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2485
  assert_different_registers(Rklass, Rintf, Rscan, Rtmp);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2486
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2487
  const int entry_size = itableOffsetEntry::size() * HeapWordSize;
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2488
  assert(itableOffsetEntry::interface_offset_in_bytes() == 0, "not added for convenience");
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2489
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2490
  // Compute start of first itableOffsetEntry (which is at the end of the vtable)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2491
  const int base = in_bytes(Klass::vtable_start_offset());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2492
  const int scale = exact_log2(vtableEntry::size_in_bytes());
48557
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2493
  ldr_s32(Rtmp, Address(Rklass, Klass::vtable_length_offset())); // Get length of vtable
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2494
  add(Rscan, Rklass, base);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2495
  add(Rscan, Rscan, AsmOperand(Rtmp, lsl, scale));
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2496
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2497
  // Search through the itable for an interface equal to incoming Rintf
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2498
  // itable looks like [intface][offset][intface][offset][intface][offset]
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2499
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2500
  Label loop;
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2501
  bind(loop);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2502
  ldr(Rtmp, Address(Rscan, entry_size, post_indexed));
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2503
#ifdef AARCH64
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2504
  Label found;
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2505
  cmp(Rtmp, Rintf);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2506
  b(found, eq);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2507
  cbnz(Rtmp, loop);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2508
#else
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2509
  cmp(Rtmp, Rintf);  // set ZF and CF if interface is found
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2510
  cmn(Rtmp, 0, ne);  // check if tmp == 0 and clear CF if it is
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2511
  b(loop, ne);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2512
#endif // AARCH64
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2513
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2514
#ifdef AARCH64
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2515
  b(L_no_such_interface);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2516
  bind(found);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2517
#else
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2518
  // CF == 0 means we reached the end of itable without finding icklass
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2519
  b(L_no_such_interface, cc);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2520
#endif // !AARCH64
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2521
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2522
  if (method_result != noreg) {
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2523
    // Interface found at previous position of Rscan, now load the method
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2524
    ldr_s32(Rtmp, Address(Rscan, itableOffsetEntry::offset_offset_in_bytes() - entry_size));
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2525
    if (itable_index.is_register()) {
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2526
      add(Rtmp, Rtmp, Rklass); // Add offset to Klass*
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2527
      assert(itableMethodEntry::size() * HeapWordSize == wordSize, "adjust the scaling in the code below");
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2528
      assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust the offset in the code below");
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2529
      ldr(method_result, Address::indexed_ptr(Rtmp, itable_index.as_register()));
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2530
    } else {
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2531
      int method_offset = itableMethodEntry::size() * HeapWordSize * itable_index.as_constant() +
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2532
                          itableMethodEntry::method_offset_in_bytes();
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2533
      add_slow(method_result, Rklass, method_offset);
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2534
      ldr(method_result, Address(method_result, Rtmp));
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2535
    }
2e867226b914 8174962: Better interface invocations
vlivanov
parents: 47580
diff changeset
  2536
  }
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2537
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2538
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2539
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2540
// TODO: 8 bytes at a time? pre-fetch?
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2541
// Compare char[] arrays aligned to 4 bytes.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2542
void MacroAssembler::char_arrays_equals(Register ary1, Register ary2,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2543
                                        Register limit, Register result,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2544
                                      Register chr1, Register chr2, Label& Ldone) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2545
  Label Lvector, Lloop;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2546
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2547
  // Note: limit contains number of bytes (2*char_elements) != 0.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2548
  tst(limit, 0x2); // trailing character ?
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2549
  b(Lvector, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2550
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2551
  // compare the trailing char
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2552
  sub(limit, limit, sizeof(jchar));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2553
  ldrh(chr1, Address(ary1, limit));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2554
  ldrh(chr2, Address(ary2, limit));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2555
  cmp(chr1, chr2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2556
  mov(result, 0, ne);     // not equal
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2557
  b(Ldone, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2558
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2559
  // only one char ?
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2560
  tst(limit, limit);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2561
  mov(result, 1, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2562
  b(Ldone, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2563
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2564
  // word by word compare, dont't need alignment check
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2565
  bind(Lvector);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2566
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2567
  // Shift ary1 and ary2 to the end of the arrays, negate limit
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2568
  add(ary1, limit, ary1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2569
  add(ary2, limit, ary2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2570
  neg(limit, limit);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2571
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2572
  bind(Lloop);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2573
  ldr_u32(chr1, Address(ary1, limit));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2574
  ldr_u32(chr2, Address(ary2, limit));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2575
  cmp_32(chr1, chr2);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2576
  mov(result, 0, ne);     // not equal
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2577
  b(Ldone, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2578
  adds(limit, limit, 2*sizeof(jchar));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2579
  b(Lloop, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2580
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2581
  // Caller should set it:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2582
  // mov(result_reg, 1);  //equal
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2583
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2584
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2585
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2586
void MacroAssembler::inc_counter(address counter_addr, Register tmpreg1, Register tmpreg2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2587
  mov_slow(tmpreg1, counter_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2588
  ldr_s32(tmpreg2, tmpreg1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2589
  add_32(tmpreg2, tmpreg2, 1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2590
  str_32(tmpreg2, tmpreg1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2591
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2592
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2593
void MacroAssembler::floating_cmp(Register dst) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2594
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2595
  NOT_TESTED();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2596
  cset(dst, gt);            // 1 if '>', else 0
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2597
  csinv(dst, dst, ZR, ge);  // previous value if '>=', else -1
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2598
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2599
  vmrs(dst, FPSCR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2600
  orr(dst, dst, 0x08000000);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2601
  eor(dst, dst, AsmOperand(dst, lsl, 3));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2602
  mov(dst, AsmOperand(dst, asr, 30));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2603
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2604
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2605
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2606
void MacroAssembler::restore_default_fp_mode() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2607
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2608
  msr(SysReg_FPCR, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2609
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2610
#ifndef __SOFTFP__
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2611
  // Round to Near mode, IEEE compatible, masked exceptions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2612
  mov(Rtemp, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2613
  vmsr(FPSCR, Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2614
#endif // !__SOFTFP__
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2615
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2616
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2617
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2618
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2619
// 24-bit word range == 26-bit byte range
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2620
bool check26(int offset) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2621
  // this could be simplified, but it mimics encoding and decoding
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2622
  // an actual branch insrtuction
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2623
  int off1 = offset << 6 >> 8;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2624
  int encoded = off1 & ((1<<24)-1);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2625
  int decoded = encoded << 8 >> 6;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2626
  return offset == decoded;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2627
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2628
#endif // !AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2629
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2630
// Perform some slight adjustments so the default 32MB code cache
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2631
// is fully reachable.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2632
static inline address first_cache_address() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2633
  return CodeCache::low_bound() + sizeof(HeapBlock::Header);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2634
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2635
static inline address last_cache_address() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2636
  return CodeCache::high_bound() - Assembler::InstructionSize;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2637
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2638
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2639
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2640
// Can we reach target using ADRP?
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2641
bool MacroAssembler::page_reachable_from_cache(address target) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2642
  intptr_t cl = (intptr_t)first_cache_address() & ~0xfff;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2643
  intptr_t ch = (intptr_t)last_cache_address() & ~0xfff;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2644
  intptr_t addr = (intptr_t)target & ~0xfff;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2645
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2646
  intptr_t loffset = addr - cl;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2647
  intptr_t hoffset = addr - ch;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2648
  return is_imm_in_range(loffset >> 12, 21, 0) && is_imm_in_range(hoffset >> 12, 21, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2649
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2650
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2651
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2652
// Can we reach target using unconditional branch or call from anywhere
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2653
// in the code cache (because code can be relocated)?
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2654
bool MacroAssembler::_reachable_from_cache(address target) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2655
#ifdef __thumb__
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2656
  if ((1 & (intptr_t)target) != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2657
    // Return false to avoid 'b' if we need switching to THUMB mode.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2658
    return false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2659
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2660
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2661
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2662
  address cl = first_cache_address();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2663
  address ch = last_cache_address();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2665
  if (ForceUnreachable) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2666
    // Only addresses from CodeCache can be treated as reachable.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2667
    if (target < CodeCache::low_bound() || CodeCache::high_bound() < target) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2668
      return false;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2669
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2670
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2671
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2672
  intptr_t loffset = (intptr_t)target - (intptr_t)cl;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2673
  intptr_t hoffset = (intptr_t)target - (intptr_t)ch;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2674
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2675
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2676
  return is_offset_in_range(loffset, 26) && is_offset_in_range(hoffset, 26);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2677
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2678
  return check26(loffset - 8) && check26(hoffset - 8);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2679
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2680
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2681
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2682
bool MacroAssembler::reachable_from_cache(address target) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2683
  assert(CodeCache::contains(pc()), "not supported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2684
  return _reachable_from_cache(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2685
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2686
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2687
// Can we reach the entire code cache from anywhere else in the code cache?
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2688
bool MacroAssembler::_cache_fully_reachable() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2689
  address cl = first_cache_address();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2690
  address ch = last_cache_address();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2691
  return _reachable_from_cache(cl) && _reachable_from_cache(ch);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2692
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2693
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2694
bool MacroAssembler::cache_fully_reachable() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2695
  assert(CodeCache::contains(pc()), "not supported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2696
  return _cache_fully_reachable();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2697
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2698
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2699
void MacroAssembler::jump(address target, relocInfo::relocType rtype, Register scratch NOT_AARCH64_ARG(AsmCondition cond)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2700
  assert((rtype == relocInfo::runtime_call_type) || (rtype == relocInfo::none), "not supported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2701
  if (reachable_from_cache(target)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2702
    relocate(rtype);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2703
    b(target NOT_AARCH64_ARG(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2704
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2705
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2706
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2707
  // Note: relocate is not needed for the code below,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2708
  // encoding targets in absolute format.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2709
  if (ignore_non_patchable_relocations()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2710
    rtype = relocInfo::none;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2711
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2712
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2713
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2714
  assert (scratch != noreg, "should be specified");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2715
  InlinedAddress address_literal(target, rtype);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2716
  ldr_literal(scratch, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2717
  br(scratch);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2718
  int off = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2719
  bind_literal(address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2720
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2721
  if (offset() - off == wordSize) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2722
    // no padding, so insert nop for worst-case sizing
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2723
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2724
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2725
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2726
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2727
  if (VM_Version::supports_movw() && (scratch != noreg) && (rtype == relocInfo::none)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2728
    // Note: this version cannot be (atomically) patched
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2729
    mov_slow(scratch, (intptr_t)target, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2730
    bx(scratch, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2731
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2732
    Label skip;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2733
    InlinedAddress address_literal(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2734
    if (cond != al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2735
      b(skip, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2736
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2737
    relocate(rtype);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2738
    ldr_literal(PC, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2739
    bind_literal(address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2740
    bind(skip);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2741
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2742
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2743
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2744
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2745
// Similar to jump except that:
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2746
// - near calls are valid only if any destination in the cache is near
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2747
// - no movt/movw (not atomically patchable)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2748
void MacroAssembler::patchable_jump(address target, relocInfo::relocType rtype, Register scratch NOT_AARCH64_ARG(AsmCondition cond)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2749
  assert((rtype == relocInfo::runtime_call_type) || (rtype == relocInfo::none), "not supported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2750
  if (cache_fully_reachable()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2751
    // Note: this assumes that all possible targets (the initial one
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2752
    // and the addressed patched to) are all in the code cache.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2753
    assert(CodeCache::contains(target), "target might be too far");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2754
    relocate(rtype);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2755
    b(target NOT_AARCH64_ARG(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2756
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2757
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2758
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2759
  // Discard the relocation information if not needed for CacheCompiledCode
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2760
  // since the next encodings are all in absolute format.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2761
  if (ignore_non_patchable_relocations()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2762
    rtype = relocInfo::none;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2763
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2764
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2765
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2766
  assert (scratch != noreg, "should be specified");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2767
  InlinedAddress address_literal(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2768
  relocate(rtype);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2769
  ldr_literal(scratch, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2770
  br(scratch);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2771
  int off = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2772
  bind_literal(address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2773
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2774
  if (offset() - off == wordSize) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2775
    // no padding, so insert nop for worst-case sizing
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2776
    nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2777
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2778
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2779
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2780
  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2781
    Label skip;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2782
    InlinedAddress address_literal(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2783
    if (cond != al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2784
      b(skip, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2785
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2786
    relocate(rtype);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2787
    ldr_literal(PC, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2788
    bind_literal(address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2789
    bind(skip);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2790
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2791
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2792
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2793
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2794
void MacroAssembler::call(address target, RelocationHolder rspec NOT_AARCH64_ARG(AsmCondition cond)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2795
  Register scratch = LR;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2796
  assert(rspec.type() == relocInfo::runtime_call_type || rspec.type() == relocInfo::none, "not supported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2797
  if (reachable_from_cache(target)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2798
    relocate(rspec);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2799
    bl(target NOT_AARCH64_ARG(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2800
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2801
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2802
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2803
  // Note: relocate is not needed for the code below,
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2804
  // encoding targets in absolute format.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2805
  if (ignore_non_patchable_relocations()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2806
    // This assumes the information was needed only for relocating the code.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2807
    rspec = RelocationHolder::none;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2808
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2809
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2810
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2811
  if (VM_Version::supports_movw() && (rspec.type() == relocInfo::none)) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2812
    // Note: this version cannot be (atomically) patched
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2813
    mov_slow(scratch, (intptr_t)target, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2814
    blx(scratch, cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2815
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2816
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2817
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2818
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2819
  {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2820
    Label ret_addr;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2821
#ifndef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2822
    if (cond != al) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2823
      b(ret_addr, inverse(cond));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2824
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2825
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2826
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2827
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2828
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2829
    // TODO-AARCH64: make more optimal implementation
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2830
    // [ Keep in sync with MacroAssembler::call_size ]
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2831
    assert(rspec.type() == relocInfo::none, "call reloc not implemented");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2832
    mov_slow(scratch, target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2833
    blr(scratch);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2834
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2835
    InlinedAddress address_literal(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2836
    relocate(rspec);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2837
    adr(LR, ret_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2838
    ldr_literal(PC, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2839
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2840
    bind_literal(address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2841
    bind(ret_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2842
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2843
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2844
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2845
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2846
#if defined(AARCH64) && defined(COMPILER2)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2847
int MacroAssembler::call_size(address target, bool far, bool patchable) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2848
  // FIXME: mov_slow is variable-length
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2849
  if (!far) return 1; // bl
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2850
  if (patchable) return 2;  // ldr; blr
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2851
  return instr_count_for_mov_slow((intptr_t)target) + 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2852
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2853
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2854
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2855
int MacroAssembler::patchable_call(address target, RelocationHolder const& rspec, bool c2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2856
  assert(rspec.type() == relocInfo::static_call_type ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2857
         rspec.type() == relocInfo::none ||
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2858
         rspec.type() == relocInfo::opt_virtual_call_type, "not supported");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2859
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2860
  // Always generate the relocation information, needed for patching
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2861
  relocate(rspec); // used by NativeCall::is_call_before()
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2862
  if (cache_fully_reachable()) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2863
    // Note: this assumes that all possible targets (the initial one
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2864
    // and the addresses patched to) are all in the code cache.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2865
    assert(CodeCache::contains(target), "target might be too far");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2866
    bl(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2867
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2868
#if defined(AARCH64) && defined(COMPILER2)
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2869
    if (c2) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2870
      // return address needs to match call_size().
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2871
      // no need to trash Rtemp
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2872
      int off = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2873
      Label skip_literal;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2874
      InlinedAddress address_literal(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2875
      ldr_literal(LR, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2876
      blr(LR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2877
      int ret_addr_offset = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2878
      assert(offset() - off == call_size(target, true, true) * InstructionSize, "need to fix call_size()");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2879
      b(skip_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2880
      int off2 = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2881
      bind_literal(address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2882
      if (offset() - off2 == wordSize) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2883
        // no padding, so insert nop for worst-case sizing
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2884
        nop();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2885
      }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2886
      bind(skip_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2887
      return ret_addr_offset;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2888
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2889
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2890
    Label ret_addr;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2891
    InlinedAddress address_literal(target);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2892
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2893
    ldr_literal(Rtemp, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2894
    adr(LR, ret_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2895
    br(Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2896
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2897
    adr(LR, ret_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2898
    ldr_literal(PC, address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2899
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2900
    bind_literal(address_literal);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2901
    bind(ret_addr);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2902
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2903
  return offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2904
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2905
46961
c9094b1e5f87 8186088: ConstantPoolCache::_resolved_references is not a JNIHandle
coleenp
parents: 44406
diff changeset
  2906
// ((OopHandle)result).resolve();
c9094b1e5f87 8186088: ConstantPoolCache::_resolved_references is not a JNIHandle
coleenp
parents: 44406
diff changeset
  2907
void MacroAssembler::resolve_oop_handle(Register result) {
c9094b1e5f87 8186088: ConstantPoolCache::_resolved_references is not a JNIHandle
coleenp
parents: 44406
diff changeset
  2908
  // OopHandle::resolve is an indirection.
c9094b1e5f87 8186088: ConstantPoolCache::_resolved_references is not a JNIHandle
coleenp
parents: 44406
diff changeset
  2909
  ldr(result, Address(result, 0));
c9094b1e5f87 8186088: ConstantPoolCache::_resolved_references is not a JNIHandle
coleenp
parents: 44406
diff changeset
  2910
}
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2911
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2912
void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2913
  const int mirror_offset = in_bytes(Klass::java_mirror_offset());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2914
  ldr(tmp, Address(method, Method::const_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2915
  ldr(tmp, Address(tmp,  ConstMethod::constants_offset()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2916
  ldr(tmp, Address(tmp, ConstantPool::pool_holder_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2917
  ldr(mirror, Address(tmp, mirror_offset));
47580
96392e113a0a 8186777: Make Klass::_java_mirror an OopHandle
coleenp
parents: 47216
diff changeset
  2918
  resolve_oop_handle(mirror);
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2919
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2920
46961
c9094b1e5f87 8186088: ConstantPoolCache::_resolved_references is not a JNIHandle
coleenp
parents: 44406
diff changeset
  2921
42664
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2922
///////////////////////////////////////////////////////////////////////////////
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2923
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2924
// Compressed pointers
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2925
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2926
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2927
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2928
void MacroAssembler::load_klass(Register dst_klass, Register src_oop) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2929
  if (UseCompressedClassPointers) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2930
    ldr_w(dst_klass, Address(src_oop, oopDesc::klass_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2931
    decode_klass_not_null(dst_klass);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2932
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2933
    ldr(dst_klass, Address(src_oop, oopDesc::klass_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2934
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2935
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2936
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2937
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2938
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2939
void MacroAssembler::load_klass(Register dst_klass, Register src_oop, AsmCondition cond) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2940
  ldr(dst_klass, Address(src_oop, oopDesc::klass_offset_in_bytes()), cond);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2941
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2942
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2943
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2944
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2945
// Blows src_klass.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2946
void MacroAssembler::store_klass(Register src_klass, Register dst_oop) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2947
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2948
  if (UseCompressedClassPointers) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2949
    assert(src_klass != dst_oop, "not enough registers");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2950
    encode_klass_not_null(src_klass);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2951
    str_w(src_klass, Address(dst_oop, oopDesc::klass_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2952
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2953
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2954
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2955
  str(src_klass, Address(dst_oop, oopDesc::klass_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2956
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2957
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2958
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2959
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2960
void MacroAssembler::store_klass_gap(Register dst) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2961
  if (UseCompressedClassPointers) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2962
    str_w(ZR, Address(dst, oopDesc::klass_gap_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2963
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2964
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2965
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2966
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2967
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2968
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2969
void MacroAssembler::load_heap_oop(Register dst, Address src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2970
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2971
  if (UseCompressedOops) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2972
    ldr_w(dst, src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2973
    decode_heap_oop(dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2974
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2975
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2976
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2977
  ldr(dst, src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2978
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2979
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2980
// Blows src and flags.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2981
void MacroAssembler::store_heap_oop(Register src, Address dst) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2982
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2983
  if (UseCompressedOops) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2984
    assert(!dst.uses(src), "not enough registers");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2985
    encode_heap_oop(src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2986
    str_w(src, dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2987
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2988
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2989
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2990
  str(src, dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2991
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2992
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2993
void MacroAssembler::store_heap_oop_null(Register src, Address dst) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2994
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2995
  if (UseCompressedOops) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2996
    str_w(src, dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2997
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2998
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  2999
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3000
  str(src, dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3001
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3002
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3003
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3004
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3005
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3006
// Algorithm must match oop.inline.hpp encode_heap_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3007
void MacroAssembler::encode_heap_oop(Register dst, Register src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3008
  // This code pattern is matched in NativeIntruction::skip_encode_heap_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3009
  // Update it at modifications.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3010
  assert (UseCompressedOops, "must be compressed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3011
  assert (Universe::heap() != NULL, "java heap should be initialized");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3012
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3013
  verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3014
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3015
  verify_oop(src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3016
  if (Universe::narrow_oop_base() == NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3017
    if (Universe::narrow_oop_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3018
      assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3019
      _lsr(dst, src, Universe::narrow_oop_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3020
    } else if (dst != src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3021
      mov(dst, src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3022
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3023
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3024
    tst(src, src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3025
    csel(dst, Rheap_base, src, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3026
    sub(dst, dst, Rheap_base);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3027
    if (Universe::narrow_oop_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3028
      assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3029
      _lsr(dst, dst, Universe::narrow_oop_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3030
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3031
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3032
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3033
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3034
// Same algorithm as oop.inline.hpp decode_heap_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3035
void MacroAssembler::decode_heap_oop(Register dst, Register src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3036
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3037
  verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3038
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3039
  assert(Universe::narrow_oop_shift() == 0 || LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3040
  if (Universe::narrow_oop_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3041
    tst(src, src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3042
    add(dst, Rheap_base, AsmOperand(src, lsl, Universe::narrow_oop_shift()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3043
    csel(dst, dst, ZR, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3044
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3045
    _lsl(dst, src, Universe::narrow_oop_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3046
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3047
  verify_oop(dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3048
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3049
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3050
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3051
// Algorithm must match oop.inline.hpp encode_heap_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3052
// Must preserve condition codes, or C2 encodeHeapOop_not_null rule
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3053
// must be changed.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3054
void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3055
  assert (UseCompressedOops, "must be compressed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3056
  assert (Universe::heap() != NULL, "java heap should be initialized");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3057
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3058
  verify_heapbase("MacroAssembler::encode_heap_oop: heap base corrupted?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3059
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3060
  verify_oop(src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3061
  if (Universe::narrow_oop_base() == NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3062
    if (Universe::narrow_oop_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3063
      assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3064
      _lsr(dst, src, Universe::narrow_oop_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3065
    } else if (dst != src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3066
          mov(dst, src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3067
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3068
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3069
    sub(dst, src, Rheap_base);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3070
    if (Universe::narrow_oop_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3071
      assert (LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3072
      _lsr(dst, dst, Universe::narrow_oop_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3073
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3074
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3075
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3076
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3077
// Same algorithm as oops.inline.hpp decode_heap_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3078
// Must preserve condition codes, or C2 decodeHeapOop_not_null rule
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3079
// must be changed.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3080
void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3081
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3082
  verify_heapbase("MacroAssembler::decode_heap_oop: heap base corrupted?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3083
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3084
  assert(Universe::narrow_oop_shift() == 0 || LogMinObjAlignmentInBytes == Universe::narrow_oop_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3085
  if (Universe::narrow_oop_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3086
    add(dst, Rheap_base, AsmOperand(src, lsl, Universe::narrow_oop_shift()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3087
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3088
    _lsl(dst, src, Universe::narrow_oop_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3089
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3090
  verify_oop(dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3091
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3092
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3093
void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3094
  assert(UseCompressedClassPointers, "should only be used for compressed header");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3095
  assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3096
  int klass_index = oop_recorder()->find_index(k);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3097
  RelocationHolder rspec = metadata_Relocation::spec(klass_index);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3098
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3099
  // Relocation with special format (see relocInfo_arm.hpp).
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3100
  relocate(rspec);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3101
  narrowKlass encoded_k = Klass::encode_klass(k);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3102
  movz(dst, encoded_k & 0xffff, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3103
  movk(dst, (encoded_k >> 16) & 0xffff, 16);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3104
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3105
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3106
void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3107
  assert(UseCompressedOops, "should only be used for compressed header");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3108
  assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3109
  int oop_index = oop_recorder()->find_index(obj);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3110
  RelocationHolder rspec = oop_Relocation::spec(oop_index);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3111
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3112
  relocate(rspec);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3113
  movz(dst, 0xffff, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3114
  movk(dst, 0xffff, 16);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3115
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3116
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3117
#endif // COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3118
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3119
// Must preserve condition codes, or C2 encodeKlass_not_null rule
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3120
// must be changed.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3121
void MacroAssembler::encode_klass_not_null(Register r) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3122
  if (Universe::narrow_klass_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3123
    // Use Rheap_base as a scratch register in which to temporarily load the narrow_klass_base.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3124
    assert(r != Rheap_base, "Encoding a klass in Rheap_base");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3125
    mov_slow(Rheap_base, Universe::narrow_klass_base());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3126
    sub(r, r, Rheap_base);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3127
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3128
  if (Universe::narrow_klass_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3129
    assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3130
    _lsr(r, r, Universe::narrow_klass_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3131
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3132
  if (Universe::narrow_klass_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3133
    reinit_heapbase();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3134
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3135
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3136
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3137
// Must preserve condition codes, or C2 encodeKlass_not_null rule
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3138
// must be changed.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3139
void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3140
  if (dst == src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3141
    encode_klass_not_null(src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3142
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3143
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3144
  if (Universe::narrow_klass_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3145
    mov_slow(dst, (int64_t)Universe::narrow_klass_base());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3146
    sub(dst, src, dst);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3147
    if (Universe::narrow_klass_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3148
      assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3149
      _lsr(dst, dst, Universe::narrow_klass_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3150
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3151
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3152
    if (Universe::narrow_klass_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3153
      assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3154
      _lsr(dst, src, Universe::narrow_klass_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3155
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3156
      mov(dst, src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3157
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3158
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3159
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3160
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3161
// Function instr_count_for_decode_klass_not_null() counts the instructions
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3162
// generated by decode_klass_not_null(register r) and reinit_heapbase(),
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3163
// when (Universe::heap() != NULL).  Hence, if the instructions they
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3164
// generate change, then this method needs to be updated.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3165
int MacroAssembler::instr_count_for_decode_klass_not_null() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3166
  assert(UseCompressedClassPointers, "only for compressed klass ptrs");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3167
  assert(Universe::heap() != NULL, "java heap should be initialized");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3168
  if (Universe::narrow_klass_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3169
    return instr_count_for_mov_slow(Universe::narrow_klass_base()) + // mov_slow
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3170
      1 +                                                                 // add
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3171
      instr_count_for_mov_slow(Universe::narrow_ptrs_base());   // reinit_heapbase() = mov_slow
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3172
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3173
    if (Universe::narrow_klass_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3174
      return 1;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3175
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3176
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3177
  return 0;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3178
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3179
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3180
// Must preserve condition codes, or C2 decodeKlass_not_null rule
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3181
// must be changed.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3182
void MacroAssembler::decode_klass_not_null(Register r) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3183
  int off = offset();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3184
  assert(UseCompressedClassPointers, "should only be used for compressed headers");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3185
  assert(Universe::heap() != NULL, "java heap should be initialized");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3186
  assert(r != Rheap_base, "Decoding a klass in Rheap_base");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3187
  // Cannot assert, instr_count_for_decode_klass_not_null() counts instructions.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3188
  // Also do not verify_oop as this is called by verify_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3189
  if (Universe::narrow_klass_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3190
    // Use Rheap_base as a scratch register in which to temporarily load the narrow_klass_base.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3191
    mov_slow(Rheap_base, Universe::narrow_klass_base());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3192
    add(r, Rheap_base, AsmOperand(r, lsl, Universe::narrow_klass_shift()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3193
    reinit_heapbase();
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3194
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3195
    if (Universe::narrow_klass_shift() != 0) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3196
      assert (LogKlassAlignmentInBytes == Universe::narrow_klass_shift(), "decode alg wrong");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3197
      _lsl(r, r, Universe::narrow_klass_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3198
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3199
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3200
  assert((offset() - off) == (instr_count_for_decode_klass_not_null() * InstructionSize), "need to fix instr_count_for_decode_klass_not_null");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3201
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3202
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3203
// Must preserve condition codes, or C2 decodeKlass_not_null rule
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3204
// must be changed.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3205
void MacroAssembler::decode_klass_not_null(Register dst, Register src) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3206
  if (src == dst) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3207
    decode_klass_not_null(src);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3208
    return;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3209
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3210
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3211
  assert(UseCompressedClassPointers, "should only be used for compressed headers");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3212
  assert(Universe::heap() != NULL, "java heap should be initialized");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3213
  assert(src != Rheap_base, "Decoding a klass in Rheap_base");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3214
  assert(dst != Rheap_base, "Decoding a klass into Rheap_base");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3215
  // Also do not verify_oop as this is called by verify_oop.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3216
  if (Universe::narrow_klass_base() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3217
    mov_slow(dst, Universe::narrow_klass_base());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3218
    add(dst, dst, AsmOperand(src, lsl, Universe::narrow_klass_shift()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3219
  } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3220
    _lsl(dst, src, Universe::narrow_klass_shift());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3221
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3222
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3223
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3224
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3225
void MacroAssembler::reinit_heapbase() {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3226
  if (UseCompressedOops || UseCompressedClassPointers) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3227
    if (Universe::heap() != NULL) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3228
      mov_slow(Rheap_base, Universe::narrow_ptrs_base());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3229
    } else {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3230
      ldr_global_ptr(Rheap_base, (address)Universe::narrow_ptrs_base_addr());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3231
    }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3232
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3233
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3234
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3235
#ifdef ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3236
void MacroAssembler::verify_heapbase(const char* msg) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3237
  // This code pattern is matched in NativeIntruction::skip_verify_heapbase.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3238
  // Update it at modifications.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3239
  assert (UseCompressedOops, "should be compressed");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3240
  assert (Universe::heap() != NULL, "java heap should be initialized");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3241
  if (CheckCompressedOops) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3242
    Label ok;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3243
    str(Rthread, Address(Rthread, in_bytes(JavaThread::in_top_frame_unsafe_section_offset())));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3244
    raw_push(Rtemp, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3245
    mrs(Rtemp, Assembler::SysReg_NZCV);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3246
    str(Rtemp, Address(SP, 1 * wordSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3247
    mov_slow(Rtemp, Universe::narrow_ptrs_base());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3248
    cmp(Rheap_base, Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3249
    b(ok, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3250
    stop(msg);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3251
    bind(ok);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3252
    ldr(Rtemp, Address(SP, 1 * wordSize));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3253
    msr(Assembler::SysReg_NZCV, Rtemp);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3254
    raw_pop(Rtemp, ZR);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3255
    str(ZR, Address(Rthread, in_bytes(JavaThread::in_top_frame_unsafe_section_offset())));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3256
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3257
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3258
#endif // ASSERT
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3259
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3260
#endif // AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3261
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3262
#ifdef COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3263
void MacroAssembler::fast_lock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2 AARCH64_ONLY_ARG(Register Rscratch3))
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3264
{
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3265
  assert(VM_Version::supports_ldrex(), "unsupported, yet?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3266
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3267
  Register Rmark      = Rscratch2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3268
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3269
  assert(Roop != Rscratch, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3270
  assert(Roop != Rmark, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3271
  assert(Rbox != Rscratch, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3272
  assert(Rbox != Rmark, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3273
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3274
  Label fast_lock, done;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3275
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3276
  if (UseBiasedLocking && !UseOptoBiasInlining) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3277
    Label failed;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3278
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3279
    biased_locking_enter(Roop, Rmark, Rscratch, false, Rscratch3, done, failed);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3280
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3281
    biased_locking_enter(Roop, Rmark, Rscratch, false, noreg, done, failed);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3282
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3283
    bind(failed);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3284
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3285
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3286
  ldr(Rmark, Address(Roop, oopDesc::mark_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3287
  tst(Rmark, markOopDesc::unlocked_value);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3288
  b(fast_lock, ne);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3289
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3290
  // Check for recursive lock
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3291
  // See comments in InterpreterMacroAssembler::lock_object for
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3292
  // explanations on the fast recursive locking check.
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3293
#ifdef AARCH64
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3294
  intptr_t mask = ((intptr_t)3) - ((intptr_t)os::vm_page_size());
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3295
  Assembler::LogicalImmediate imm(mask, false);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3296
  mov(Rscratch, SP);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3297
  sub(Rscratch, Rmark, Rscratch);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3298
  ands(Rscratch, Rscratch, imm);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3299
  b(done, ne); // exit with failure
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3300
  str(Rscratch, Address(Rbox, BasicLock::displaced_header_offset_in_bytes())); // set to zero
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3301
  b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3302
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3303
#else
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3304
  // -1- test low 2 bits
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3305
  movs(Rscratch, AsmOperand(Rmark, lsl, 30));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3306
  // -2- test (hdr - SP) if the low two bits are 0
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3307
  sub(Rscratch, Rmark, SP, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3308
  movs(Rscratch, AsmOperand(Rscratch, lsr, exact_log2(os::vm_page_size())), eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3309
  // If still 'eq' then recursive locking OK
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3310
  str(Rscratch, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()), eq); // set to zero
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3311
  b(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3312
#endif
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3313
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3314
  bind(fast_lock);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3315
  str(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3316
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3317
  bool allow_fallthrough_on_failure = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3318
  bool one_shot = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3319
  cas_for_lock_acquire(Rmark, Rbox, Roop, Rscratch, done, allow_fallthrough_on_failure, one_shot);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3320
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3321
  bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3322
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3323
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3324
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3325
void MacroAssembler::fast_unlock(Register Roop, Register Rbox, Register Rscratch, Register Rscratch2  AARCH64_ONLY_ARG(Register Rscratch3))
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3326
{
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3327
  assert(VM_Version::supports_ldrex(), "unsupported, yet?");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3328
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3329
  Register Rmark      = Rscratch2;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3330
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3331
  assert(Roop != Rscratch, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3332
  assert(Roop != Rmark, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3333
  assert(Rbox != Rscratch, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3334
  assert(Rbox != Rmark, "");
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3335
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3336
  Label done;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3337
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3338
  if (UseBiasedLocking && !UseOptoBiasInlining) {
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3339
    biased_locking_exit(Roop, Rscratch, done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3340
  }
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3341
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3342
  ldr(Rmark, Address(Rbox, BasicLock::displaced_header_offset_in_bytes()));
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3343
  // If hdr is NULL, we've got recursive locking and there's nothing more to do
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3344
  cmp(Rmark, 0);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3345
  b(done, eq);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3346
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3347
  // Restore the object header
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3348
  bool allow_fallthrough_on_failure = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3349
  bool one_shot = true;
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3350
  cas_for_lock_release(Rmark, Rbox, Roop, Rscratch, done, allow_fallthrough_on_failure, one_shot);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3351
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3352
  bind(done);
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3353
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3354
}
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3355
#endif // COMPILER2
29142a56c193 8168503: JEP 297: Unified arm32/arm64 Port
bobv
parents:
diff changeset
  3356