1 /*
   2  * Copyright (c) 2017, 2019, 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_ZFORWARDINGENTRY_HPP
  25 #define SHARE_GC_Z_ZFORWARDINGENTRY_HPP
  26 
  27 #include "gc/z/zBitField.hpp"
  28 #include "memory/allocation.hpp"
  29 #include "metaprogramming/primitiveConversions.hpp"
  30 
  31 //
  32 // Forwarding entry layout
  33 // -----------------------
  34 //
  35 //   6                  4 4
  36 //   3                  6 5                                                1 0
  37 //  +--------------------+--------------------------------------------------+-+
  38 //  |11111111 11111111 11|111111 11111111 11111111 11111111 11111111 1111111|1|
  39 //  +--------------------+--------------------------------------------------+-+
  40 //  |                    |                                                  |
  41 //  |                    |                      0-0 Populated Flag (1-bits) *
  42 //  |                    |
  43 //  |                    * 45-1 To Object Offset (45-bits)
  44 //  |
  45 //  * 63-46 From Object Index (18-bits)
  46 //
  47 
  48 class ZForwardingEntry {
  49   friend class PrimitiveConversions;
  50 
  51 private:
  52   typedef ZBitField<uint64_t, bool,   0,   1> field_populated;
  53   typedef ZBitField<uint64_t, size_t, 1,  45> field_to_offset;
  54   typedef ZBitField<uint64_t, size_t, 46, 18> field_from_index;
  55 
  56   uint64_t _entry;
  57 
  58 public:
  59   ZForwardingEntry() :
  60       _entry(0) {}
  61 
  62   ZForwardingEntry(size_t from_index, size_t to_offset) :
  63       _entry(field_populated::encode(true) |
  64              field_to_offset::encode(to_offset) |
  65              field_from_index::encode(from_index)) {}
  66 
  67   bool populated() const {
  68     return field_populated::decode(_entry);
  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 ZForwardingEntry
  81 template <>
  82 struct PrimitiveConversions::Translate<ZForwardingEntry> : public TrueType {
  83   typedef ZForwardingEntry 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     ZForwardingEntry entry;
  92     entry._entry = d;
  93     return entry;
  94   }
  95 };
  96 
  97 #endif // SHARE_GC_Z_ZFORWARDINGENTRY_HPP