hotspot/src/share/vm/runtime/atomic.cpp
author ccheung
Thu, 07 Apr 2016 22:03:04 -0700
changeset 37439 e8970711113b
parent 27691 733f189ad1f7
permissions -rw-r--r--
8145221: Use trampolines for i2i and i2c entries in Methods that are stored in CDS archive Summary: This optimization reduces the size of the RW region of the CDS archive. It also reduces the amount of pages in the RW region that are actually written into during runtime. Reviewed-by: dlong, iklam, jiangli Contributed-by: ioi.lam@oracle.com, calvin.cheung@oracle.com, goetz.lindenmaier@sap.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
25468
5331df506290 8048241: Introduce umbrella header os.inline.hpp and clean up includes
goetz
parents: 22872
diff changeset
     2
 * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 670
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 670
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 670
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
14626
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 10565
diff changeset
    26
#include "runtime/atomic.inline.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
27691
733f189ad1f7 8058255: Native jbyte Atomic::cmpxchg for supported x86 platforms
jwilhelm
parents: 25468
diff changeset
    28
/*
733f189ad1f7 8058255: Native jbyte Atomic::cmpxchg for supported x86 platforms
jwilhelm
parents: 25468
diff changeset
    29
 * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg
733f189ad1f7 8058255: Native jbyte Atomic::cmpxchg for supported x86 platforms
jwilhelm
parents: 25468
diff changeset
    30
 * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition
733f189ad1f7 8058255: Native jbyte Atomic::cmpxchg for supported x86 platforms
jwilhelm
parents: 25468
diff changeset
    31
 * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific
733f189ad1f7 8058255: Native jbyte Atomic::cmpxchg for supported x86 platforms
jwilhelm
parents: 25468
diff changeset
    32
 * implementation to be used instead.
733f189ad1f7 8058255: Native jbyte Atomic::cmpxchg for supported x86 platforms
jwilhelm
parents: 25468
diff changeset
    33
 */
733f189ad1f7 8058255: Native jbyte Atomic::cmpxchg for supported x86 platforms
jwilhelm
parents: 25468
diff changeset
    34
jbyte Atomic::cmpxchg_general(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  assert(sizeof(jbyte) == 1, "assumption.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  uintptr_t dest_addr = (uintptr_t)dest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  uintptr_t offset = dest_addr % sizeof(jint);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  volatile jint* dest_int = (volatile jint*)(dest_addr - offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  jint cur = *dest_int;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  jbyte* cur_as_bytes = (jbyte*)(&cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  jint new_val = cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  jbyte* new_val_as_bytes = (jbyte*)(&new_val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  new_val_as_bytes[offset] = exchange_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  while (cur_as_bytes[offset] == compare_value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    jint res = cmpxchg(new_val, dest_int, cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
    if (res == cur) break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
    cur = res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
    new_val = cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
    new_val_as_bytes[offset] = exchange_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  return cur_as_bytes[offset];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
}
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    53
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    54
unsigned Atomic::xchg(unsigned int exchange_value, volatile unsigned int* dest) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    55
  assert(sizeof(unsigned int) == sizeof(jint), "more work to do");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    56
  return (unsigned int)Atomic::xchg((jint)exchange_value, (volatile jint*)dest);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    57
}
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    58
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    59
unsigned Atomic::cmpxchg(unsigned int exchange_value,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    60
                         volatile unsigned int* dest, unsigned int compare_value) {
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    61
  assert(sizeof(unsigned int) == sizeof(jint), "more work to do");
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    62
  return (unsigned int)Atomic::cmpxchg((jint)exchange_value, (volatile jint*)dest,
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    63
                                       (jint)compare_value);
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
    64
}
9990
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    65
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    66
jlong Atomic::add(jlong    add_value, volatile jlong*    dest) {
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    67
  jlong old = load(dest);
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    68
  jlong new_value = old + add_value;
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    69
  while (old != cmpxchg(new_value, dest, old)) {
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    70
    old = load(dest);
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    71
    new_value = old + add_value;
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    72
  }
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    73
  return old;
c8683968c01b 6941923: RFE: Handling large log files produced by long running Java Applications
minqi
parents: 7397
diff changeset
    74
}
18438
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    75
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    76
void Atomic::inc(volatile short* dest) {
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    77
  // Most platforms do not support atomic increment on a 2-byte value. However,
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    78
  // if the value occupies the most significant 16 bits of an aligned 32-bit
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    79
  // word, then we can do this with an atomic add of 0x10000 to the 32-bit word.
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    80
  //
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    81
  // The least significant parts of this 32-bit word will never be affected, even
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    82
  // in case of overflow/underflow.
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    83
  //
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    84
  // Use the ATOMIC_SHORT_PAIR macro to get the desired alignment.
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    85
#ifdef VM_LITTLE_ENDIAN
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    86
  assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    87
  (void)Atomic::add(0x10000, (volatile int*)(dest-1));
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    88
#else
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    89
  assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    90
  (void)Atomic::add(0x10000, (volatile int*)(dest));
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    91
#endif
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    92
}
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    93
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    94
void Atomic::dec(volatile short* dest) {
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    95
#ifdef VM_LITTLE_ENDIAN
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    96
  assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    97
  (void)Atomic::add(-0x10000, (volatile int*)(dest-1));
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    98
#else
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
    99
  assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
   100
  (void)Atomic::add(-0x10000, (volatile int*)(dest));
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
   101
#endif
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
   102
}
9ea6bbfe0b83 8009575: Reduce Symbol::_refcount from 4 bytes to 2 bytes
iklam
parents: 14626
diff changeset
   103