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 #ifndef SHARE_GC_Z_ZFORWARDINGTABLEENTRY_HPP
  25 #define SHARE_GC_Z_ZFORWARDINGTABLEENTRY_HPP
  26 
  27 #include "gc/z/zBitField.hpp"
  28 #include "memory/allocation.hpp"
  29 #include "metaprogramming/primitiveConversions.hpp"
  30 
  31 //
  32 // Forwarding table entry layout
  33 // -----------------------------
  34 //
  35 //   6                      4 4                                             0
  36 //   3                      2 1                                             0
  37 //  +------------------------+-----------------------------------------------+
  38 //  |11111111 11111111 111111|11 11111111 11111111 11111111 11111111 11111111|
  39 //  +------------------------+-----------------------------------------------+
  40 //  |                        |
  41 //  |                        * 41-0 To Object Offset (42-bits)
  42 //  |
  43 //  * 63-42 From Object Index (22-bits)
  44 //
  45 
  46 class ZForwardingTableEntry {
  47   friend struct PrimitiveConversions;
  48 
  49 private:
  50   typedef ZBitField<uint64_t, size_t, 0,  42> field_to_offset;
  51   typedef ZBitField<uint64_t, size_t, 42, 22> field_from_index;
  52 
  53   uint64_t _entry;
  54 
  55 public:
  56   ZForwardingTableEntry() :
  57       _entry(empty()) {}
  58 
  59   ZForwardingTableEntry(size_t from_index, size_t to_offset) :
  60       _entry(field_from_index::encode(from_index) |
  61              field_to_offset::encode(to_offset)) {}
  62 
  63   static uintptr_t empty() {
  64     return (uintptr_t)-1;
  65   }
  66 
  67   bool is_empty() const {
  68     return _entry == empty();
  69   }
  70 
  71   size_t to_offset() const {
  72     return field_to_offset::decode(_entry);
  73   }
  74 
  75   size_t from_index() const {
  76     return field_from_index::decode(_entry);
  77   }
  78 };
  79 
  80 // Needed to allow atomic operations on ZForwardingTableEntry
  81 template <>
  82 struct PrimitiveConversions::Translate<ZForwardingTableEntry> : public TrueType {
  83   typedef ZForwardingTableEntry Value;
  84   typedef uint64_t              Decayed;
  85 
  86   static Decayed decay(Value v) {
  87     return v._entry;
  88   }
  89 
  90   static Value recover(Decayed d) {
  91     ZForwardingTableEntry entry;
  92     entry._entry = d;
  93     return entry;
  94   }
  95 };
  96 
  97 #endif // SHARE_GC_Z_ZFORWARDINGTABLEENTRY_HPP