src/hotspot/share/oops/accessBackend.cpp
changeset 47998 fb0275c320a0
child 48824 e48c4461a8bb
equal deleted inserted replaced
47997:55c43e677ded 47998:fb0275c320a0
       
     1 /*
       
     2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "accessBackend.inline.hpp"
       
    27 #include "gc/shared/collectedHeap.hpp"
       
    28 #include "oops/oop.inline.hpp"
       
    29 #include "runtime/mutexLocker.hpp"
       
    30 #include "runtime/vm_version.hpp"
       
    31 #include "utilities/copy.hpp"
       
    32 
       
    33 namespace AccessInternal {
       
    34   // VM_Version::supports_cx8() is a surrogate for 'supports atomic long memory ops'.
       
    35   //
       
    36   // On platforms which do not support atomic compare-and-swap of jlong (8 byte)
       
    37   // values we have to use a lock-based scheme to enforce atomicity. This has to be
       
    38   // applied to all Unsafe operations that set the value of a jlong field. Even so
       
    39   // the compareAndSwapLong operation will not be atomic with respect to direct stores
       
    40   // to the field from Java code. It is important therefore that any Java code that
       
    41   // utilizes these Unsafe jlong operations does not perform direct stores. To permit
       
    42   // direct loads of the field from Java code we must also use Atomic::store within the
       
    43   // locked regions. And for good measure, in case there are direct stores, we also
       
    44   // employ Atomic::load within those regions. Note that the field in question must be
       
    45   // volatile and so must have atomic load/store accesses applied at the Java level.
       
    46   //
       
    47   // The locking scheme could utilize a range of strategies for controlling the locking
       
    48   // granularity: from a lock per-field through to a single global lock. The latter is
       
    49   // the simplest and is used for the current implementation. Note that the Java object
       
    50   // that contains the field, can not, in general, be used for locking. To do so can lead
       
    51   // to deadlocks as we may introduce locking into what appears to the Java code to be a
       
    52   // lock-free path.
       
    53   //
       
    54   // As all the locked-regions are very short and themselves non-blocking we can treat
       
    55   // them as leaf routines and elide safepoint checks (ie we don't perform any thread
       
    56   // state transitions even when blocking for the lock). Note that if we do choose to
       
    57   // add safepoint checks and thread state transitions, we must ensure that we calculate
       
    58   // the address of the field _after_ we have acquired the lock, else the object may have
       
    59   // been moved by the GC
       
    60 
       
    61 #ifndef SUPPORTS_NATIVE_CX8
       
    62 
       
    63   // This is intentionally in the cpp file rather than the .inline.hpp file. It seems
       
    64   // desirable to trade faster JDK build times (not propagating vm_version.hpp)
       
    65   // for slightly worse runtime atomic jlong performance on 32 bit machines with
       
    66   // support for 64 bit atomics.
       
    67   bool wide_atomic_needs_locking() {
       
    68     return !VM_Version::supports_cx8();
       
    69   }
       
    70 
       
    71   AccessLocker::AccessLocker() {
       
    72     assert(!VM_Version::supports_cx8(), "why else?");
       
    73     UnsafeJlong_lock->lock_without_safepoint_check();
       
    74   }
       
    75 
       
    76   AccessLocker::~AccessLocker() {
       
    77     UnsafeJlong_lock->unlock();
       
    78   }
       
    79 
       
    80 #endif
       
    81 
       
    82 // These forward copying calls to Copy without exposing the Copy type in headers unnecessarily
       
    83 
       
    84   void arraycopy_arrayof_conjoint_oops(void* src, void* dst, size_t length) {
       
    85     Copy::arrayof_conjoint_oops(reinterpret_cast<HeapWord*>(src),
       
    86                                 reinterpret_cast<HeapWord*>(dst), length);
       
    87   }
       
    88 
       
    89   void arraycopy_conjoint_oops(oop* src, oop* dst, size_t length) {
       
    90     Copy::conjoint_oops_atomic(src, dst, length);
       
    91   }
       
    92 
       
    93   void arraycopy_conjoint_oops(narrowOop* src, narrowOop* dst, size_t length) {
       
    94     Copy::conjoint_oops_atomic(src, dst, length);
       
    95   }
       
    96 
       
    97   void arraycopy_disjoint_words(void* src, void* dst, size_t length) {
       
    98     Copy::disjoint_words(reinterpret_cast<HeapWord*>(src),
       
    99                          reinterpret_cast<HeapWord*>(dst), length);
       
   100   }
       
   101 
       
   102   void arraycopy_disjoint_words_atomic(void* src, void* dst, size_t length) {
       
   103     Copy::disjoint_words_atomic(reinterpret_cast<HeapWord*>(src),
       
   104                                 reinterpret_cast<HeapWord*>(dst), length);
       
   105   }
       
   106 
       
   107   template<>
       
   108   void arraycopy_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length) {
       
   109     Copy::conjoint_jbytes(src, dst, length);
       
   110   }
       
   111 
       
   112   template<>
       
   113   void arraycopy_conjoint<jshort>(jshort* src, jshort* dst, size_t length) {
       
   114     Copy::conjoint_jshorts_atomic(src, dst, length);
       
   115   }
       
   116 
       
   117   template<>
       
   118   void arraycopy_conjoint<jint>(jint* src, jint* dst, size_t length) {
       
   119     Copy::conjoint_jints_atomic(src, dst, length);
       
   120   }
       
   121 
       
   122   template<>
       
   123   void arraycopy_conjoint<jlong>(jlong* src, jlong* dst, size_t length) {
       
   124     Copy::conjoint_jlongs_atomic(src, dst, length);
       
   125   }
       
   126 
       
   127   template<>
       
   128   void arraycopy_arrayof_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length) {
       
   129     Copy::arrayof_conjoint_jbytes(reinterpret_cast<HeapWord*>(src),
       
   130                                   reinterpret_cast<HeapWord*>(dst),
       
   131                                   length);
       
   132   }
       
   133 
       
   134   template<>
       
   135   void arraycopy_arrayof_conjoint<jshort>(jshort* src, jshort* dst, size_t length) {
       
   136     Copy::arrayof_conjoint_jshorts(reinterpret_cast<HeapWord*>(src),
       
   137                                    reinterpret_cast<HeapWord*>(dst),
       
   138                                    length);
       
   139   }
       
   140 
       
   141   template<>
       
   142   void arraycopy_arrayof_conjoint<jint>(jint* src, jint* dst, size_t length) {
       
   143     Copy::arrayof_conjoint_jints(reinterpret_cast<HeapWord*>(src),
       
   144                                  reinterpret_cast<HeapWord*>(dst),
       
   145                                  length);
       
   146   }
       
   147 
       
   148   template<>
       
   149   void arraycopy_arrayof_conjoint<jlong>(jlong* src, jlong* dst, size_t length) {
       
   150     Copy::arrayof_conjoint_jlongs(reinterpret_cast<HeapWord*>(src),
       
   151                                   reinterpret_cast<HeapWord*>(dst),
       
   152                                   length);
       
   153   }
       
   154 
       
   155   template<>
       
   156   void arraycopy_conjoint_atomic<jbyte>(jbyte* src, jbyte* dst, size_t length) {
       
   157     Copy::conjoint_jbytes_atomic(src, dst, length);
       
   158   }
       
   159 
       
   160   template<>
       
   161   void arraycopy_conjoint_atomic<jshort>(jshort* src, jshort* dst, size_t length) {
       
   162     Copy::conjoint_jshorts_atomic(src, dst, length);
       
   163   }
       
   164 
       
   165   template<>
       
   166   void arraycopy_conjoint_atomic<jint>(jint* src, jint* dst, size_t length) {
       
   167     Copy::conjoint_jints_atomic(src, dst, length);
       
   168   }
       
   169 
       
   170   template<>
       
   171   void arraycopy_conjoint_atomic<jlong>(jlong* src, jlong* dst, size_t length) {
       
   172     Copy::conjoint_jlongs_atomic(src, dst, length);
       
   173   }
       
   174 }
       
   175 
       
   176 template void AccessInternal::arraycopy_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length);
       
   177 template void AccessInternal::arraycopy_conjoint<jshort>(jshort* src, jshort* dst, size_t length);
       
   178 template void AccessInternal::arraycopy_conjoint<jint>(jint* src, jint* dst, size_t length);
       
   179 template void AccessInternal::arraycopy_conjoint<jlong>(jlong* src, jlong* dst, size_t length);
       
   180 
       
   181 template void AccessInternal::arraycopy_arrayof_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length);
       
   182 template void AccessInternal::arraycopy_arrayof_conjoint<jshort>(jshort* src, jshort* dst, size_t length);
       
   183 template void AccessInternal::arraycopy_arrayof_conjoint<jint>(jint* src, jint* dst, size_t length);
       
   184 template void AccessInternal::arraycopy_arrayof_conjoint<jlong>(jlong* src, jlong* dst, size_t length);
       
   185 
       
   186 template void AccessInternal::arraycopy_conjoint_atomic<jbyte>(jbyte* src, jbyte* dst, size_t length);
       
   187 template void AccessInternal::arraycopy_conjoint_atomic<jshort>(jshort* src, jshort* dst, size_t length);
       
   188 template void AccessInternal::arraycopy_conjoint_atomic<jint>(jint* src, jint* dst, size_t length);
       
   189 template void AccessInternal::arraycopy_conjoint_atomic<jlong>(jlong* src, jlong* dst, size_t length);