src/hotspot/share/gc/z/zForwardingTable.inline.hpp
changeset 50525 767cdb97f103
child 50875 2217b2fc29ea
equal deleted inserted replaced
50524:04f4e983c2f7 50525:767cdb97f103
       
     1 /*
       
     2  * Copyright (c) 2015, 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 #ifndef SHARE_GC_Z_ZFORWARDING_INLINE_HPP
       
    25 #define SHARE_GC_Z_ZFORWARDING_INLINE_HPP
       
    26 
       
    27 #include "gc/z/zForwardingTable.hpp"
       
    28 #include "gc/z/zGlobals.hpp"
       
    29 #include "gc/z/zHash.inline.hpp"
       
    30 #include "runtime/atomic.hpp"
       
    31 #include "utilities/debug.hpp"
       
    32 
       
    33 inline ZForwardingTable::ZForwardingTable() :
       
    34     _table(NULL),
       
    35     _size(0) {}
       
    36 
       
    37 inline ZForwardingTable::~ZForwardingTable() {
       
    38   assert(is_null(), "Should be empty");
       
    39 }
       
    40 
       
    41 inline ZForwardingTableEntry ZForwardingTable::at(ZForwardingTableCursor* cursor) const {
       
    42   return _table[*cursor];
       
    43 }
       
    44 
       
    45 inline ZForwardingTableEntry ZForwardingTable::first(uintptr_t from_index, ZForwardingTableCursor* cursor) const {
       
    46   const size_t mask = _size - 1;
       
    47   const size_t hash = ZHash::uint32_to_uint32((uint32_t)from_index);
       
    48   *cursor = hash & mask;
       
    49   return at(cursor);
       
    50 }
       
    51 
       
    52 inline ZForwardingTableEntry ZForwardingTable::next(ZForwardingTableCursor* cursor) const {
       
    53   const size_t mask = _size - 1;
       
    54   *cursor = (*cursor + 1) & mask;
       
    55   return at(cursor);
       
    56 }
       
    57 
       
    58 inline bool ZForwardingTable::is_null() const {
       
    59   return _table == NULL;
       
    60 }
       
    61 
       
    62 inline ZForwardingTableEntry ZForwardingTable::find(uintptr_t from_index) const {
       
    63   ZForwardingTableCursor dummy;
       
    64   return find(from_index, &dummy);
       
    65 }
       
    66 
       
    67 inline ZForwardingTableEntry ZForwardingTable::find(uintptr_t from_index, ZForwardingTableCursor* cursor) const {
       
    68   // Reading entries in the table races with the atomic cas done for
       
    69   // insertion into the table. This is safe because each entry is at
       
    70   // most updated once (from -1 to something else).
       
    71   ZForwardingTableEntry entry = first(from_index, cursor);
       
    72   while (!entry.is_empty()) {
       
    73     if (entry.from_index() == from_index) {
       
    74       // Match found, return matching entry
       
    75       return entry;
       
    76     }
       
    77 
       
    78     entry = next(cursor);
       
    79   }
       
    80 
       
    81   // Match not found, return empty entry
       
    82   return entry;
       
    83 }
       
    84 
       
    85 inline uintptr_t ZForwardingTable::insert(uintptr_t from_index, uintptr_t to_offset, ZForwardingTableCursor* cursor) {
       
    86   const ZForwardingTableEntry new_entry(from_index, to_offset);
       
    87   const ZForwardingTableEntry old_entry; // empty
       
    88 
       
    89   for (;;) {
       
    90     const ZForwardingTableEntry prev_entry = Atomic::cmpxchg(new_entry, _table + *cursor, old_entry);
       
    91     if (prev_entry.is_empty()) {
       
    92       // Success
       
    93       return to_offset;
       
    94     }
       
    95 
       
    96     // Find next empty or matching entry
       
    97     ZForwardingTableEntry entry = at(cursor);
       
    98     while (!entry.is_empty()) {
       
    99       if (entry.from_index() == from_index) {
       
   100         // Match found, return already inserted address
       
   101         return entry.to_offset();
       
   102       }
       
   103 
       
   104       entry = next(cursor);
       
   105     }
       
   106   }
       
   107 }
       
   108 
       
   109 #endif // SHARE_GC_Z_ZFORWARDING_INLINE_HPP