src/hotspot/share/gc/shared/barrierSetNMethod.cpp
author tschatzl
Thu, 06 Dec 2018 15:44:40 +0100
changeset 52877 9e041366c764
parent 52142 ca0c25e01c5b
child 59284 88502b1cf76f
permissions -rw-r--r--
8214850: Rename vm_operations.?pp files to vmOperations.?pp files Reviewed-by: dholmes, coleenp
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
52142
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     1
/*
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     4
 *
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     7
 * published by the Free Software Foundation.
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     8
 *
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    13
 * accompanied this code).
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    14
 *
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    18
 *
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    21
 * questions.
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    22
 *
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    23
 */
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    24
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    25
#include "precompiled.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    26
#include "code/codeCache.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    27
#include "code/nmethod.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    28
#include "gc/shared/barrierSet.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    29
#include "gc/shared/barrierSetNMethod.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    30
#include "logging/log.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    31
#include "runtime/thread.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    32
#include "utilities/debug.hpp"
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    33
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    34
int BarrierSetNMethod::disarmed_value() const {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    35
  char* disarmed_addr = reinterpret_cast<char*>(Thread::current());
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    36
  disarmed_addr += in_bytes(thread_disarmed_offset());
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    37
  return *reinterpret_cast<int*>(disarmed_addr);
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    38
}
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    39
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    40
bool BarrierSetNMethod::supports_entry_barrier(nmethod* nm) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    41
  if (nm->method()->is_method_handle_intrinsic()) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    42
    return false;
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    43
  }
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    44
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    45
  if (!nm->is_native_method() && !nm->is_compiled_by_c2() && !nm->is_compiled_by_c1()) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    46
    return false;
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    47
  }
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    48
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    49
  return true;
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    50
}
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    51
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    52
int BarrierSetNMethod::nmethod_stub_entry_barrier(address* return_address_ptr) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    53
  address return_address = *return_address_ptr;
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    54
  CodeBlob* cb = CodeCache::find_blob(return_address);
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    55
  assert(cb != NULL, "invariant");
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    56
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    57
  nmethod* nm = cb->as_nmethod();
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    58
  BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    59
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    60
  if (!bs_nm->is_armed(nm)) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    61
    return 0;
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    62
  }
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    63
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    64
  assert(!nm->is_osr_method(), "Should not reach here");
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    65
  // Called upon first entry after being armed
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    66
  bool may_enter = bs_nm->nmethod_entry_barrier(nm);
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    67
  if (!may_enter) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    68
    log_trace(nmethod, barrier)("Deoptimizing nmethod: " PTR_FORMAT, p2i(nm));
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    69
    bs_nm->deoptimize(nm, return_address_ptr);
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    70
  }
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    71
  return may_enter ? 0 : 1;
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    72
}
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    73
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    74
bool BarrierSetNMethod::nmethod_osr_entry_barrier(nmethod* nm) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    75
  // This check depends on the invariant that all nmethods that are deoptimized / made not entrant
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    76
  // are NOT disarmed.
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    77
  // This invariant is important because a method can be deoptimized after the method have been
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    78
  // resolved / looked up by OSR by another thread. By not deoptimizing them we guarantee that
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    79
  // a deoptimized method will always hit the barrier and come to the same conclusion - deoptimize
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    80
  if (!is_armed(nm)) {
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    81
    return true;
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    82
  }
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    83
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    84
  assert(nm->is_osr_method(), "Should not reach here");
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    85
  log_trace(nmethod, barrier)("Running osr nmethod entry barrier: " PTR_FORMAT, p2i(nm));
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    86
  return nmethod_entry_barrier(nm);
ca0c25e01c5b 8210498: nmethod entry barriers
eosterlund
parents:
diff changeset
    87
}