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 #include "precompiled.hpp"
  25 #include "gc/shared/gcLogPrecious.hpp"
  26 #include "gc/z/zGlobals.hpp"
  27 #include "runtime/globals.hpp"
  28 #include "utilities/globalDefinitions.hpp"
  29 #include "utilities/powerOfTwo.hpp"
  30 
  31 #include <sys/mman.h>
  32 
  33 //
  34 // The heap can have three different layouts, depending on the max heap size.
  35 //
  36 // Address Space & Pointer Layout 1
  37 // --------------------------------
  38 //
  39 //  +--------------------------------+ 0x00007FFFFFFFFFFF (127TB)
  40 //  .                                .
  41 //  .                                .
  42 //  .                                .
  43 //  +--------------------------------+ 0x0000014000000000 (20TB)
  44 //  |         Remapped View          |
  45 //  +--------------------------------+ 0x0000010000000000 (16TB)
  46 //  .                                .
  47 //  +--------------------------------+ 0x00000c0000000000 (12TB)
  48 //  |         Marked1 View           |
  49 //  +--------------------------------+ 0x0000080000000000 (8TB)
  50 //  |         Marked0 View           |
  51 //  +--------------------------------+ 0x0000040000000000 (4TB)
  52 //  .                                .
  53 //  +--------------------------------+ 0x0000000000000000
  54 //
  55 //   6                  4 4  4 4
  56 //   3                  6 5  2 1                                             0
  57 //  +--------------------+----+-----------------------------------------------+
  58 //  |00000000 00000000 00|1111|11 11111111 11111111 11111111 11111111 11111111|
  59 //  +--------------------+----+-----------------------------------------------+
  60 //  |                    |    |
  61 //  |                    |    * 41-0 Object Offset (42-bits, 4TB address space)
  62 //  |                    |
  63 //  |                    * 45-42 Metadata Bits (4-bits)  0001 = Marked0      (Address view 4-8TB)
  64 //  |                                                    0010 = Marked1      (Address view 8-12TB)
  65 //  |                                                    0100 = Remapped     (Address view 16-20TB)
  66 //  |                                                    1000 = Finalizable  (Address view N/A)
  67 //  |
  68 //  * 63-46 Fixed (18-bits, always zero)
  69 //
  70 //
  71 // Address Space & Pointer Layout 2
  72 // --------------------------------
  73 //
  74 //  +--------------------------------+ 0x00007FFFFFFFFFFF (127TB)
  75 //  .                                .
  76 //  .                                .
  77 //  .                                .
  78 //  +--------------------------------+ 0x0000280000000000 (40TB)
  79 //  |         Remapped View          |
  80 //  +--------------------------------+ 0x0000200000000000 (32TB)
  81 //  .                                .
  82 //  +--------------------------------+ 0x0000180000000000 (24TB)
  83 //  |         Marked1 View           |
  84 //  +--------------------------------+ 0x0000100000000000 (16TB)
  85 //  |         Marked0 View           |
  86 //  +--------------------------------+ 0x0000080000000000 (8TB)
  87 //  .                                .
  88 //  +--------------------------------+ 0x0000000000000000
  89 //
  90 //   6                 4 4  4 4
  91 //   3                 7 6  3 2                                              0
  92 //  +------------------+-----+------------------------------------------------+
  93 //  |00000000 00000000 0|1111|111 11111111 11111111 11111111 11111111 11111111|
  94 //  +-------------------+----+------------------------------------------------+
  95 //  |                   |    |
  96 //  |                   |    * 42-0 Object Offset (43-bits, 8TB address space)
  97 //  |                   |
  98 //  |                   * 46-43 Metadata Bits (4-bits)  0001 = Marked0      (Address view 8-16TB)
  99 //  |                                                   0010 = Marked1      (Address view 16-24TB)
 100 //  |                                                   0100 = Remapped     (Address view 32-40TB)
 101 //  |                                                   1000 = Finalizable  (Address view N/A)
 102 //  |
 103 //  * 63-47 Fixed (17-bits, always zero)
 104 //
 105 //
 106 // Address Space & Pointer Layout 3
 107 // --------------------------------
 108 //
 109 //  +--------------------------------+ 0x00007FFFFFFFFFFF (127TB)
 110 //  .                                .
 111 //  .                                .
 112 //  .                                .
 113 //  +--------------------------------+ 0x0000500000000000 (80TB)
 114 //  |         Remapped View          |
 115 //  +--------------------------------+ 0x0000400000000000 (64TB)
 116 //  .                                .
 117 //  +--------------------------------+ 0x0000300000000000 (48TB)
 118 //  |         Marked1 View           |
 119 //  +--------------------------------+ 0x0000200000000000 (32TB)
 120 //  |         Marked0 View           |
 121 //  +--------------------------------+ 0x0000100000000000 (16TB)
 122 //  .                                .
 123 //  +--------------------------------+ 0x0000000000000000
 124 //
 125 //   6               4  4  4 4
 126 //   3               8  7  4 3                                               0
 127 //  +------------------+----+-------------------------------------------------+
 128 //  |00000000 00000000 |1111|1111 11111111 11111111 11111111 11111111 11111111|
 129 //  +------------------+----+-------------------------------------------------+
 130 //  |                  |    |
 131 //  |                  |    * 43-0 Object Offset (44-bits, 16TB address space)
 132 //  |                  |
 133 //  |                  * 47-44 Metadata Bits (4-bits)  0001 = Marked0      (Address view 16-32TB)
 134 //  |                                                  0010 = Marked1      (Address view 32-48TB)
 135 //  |                                                  0100 = Remapped     (Address view 64-80TB)
 136 //  |                                                  1000 = Finalizable  (Address view N/A)
 137 //  |
 138 //  * 63-48 Fixed (16-bits, always zero)
 139 //
 140 
 141 static size_t probe_valid_max_address_bit() {
 142   const size_t page_size = (size_t) sysconf(_SC_PAGE_SIZE);
 143   size_t max_address_bits = 0;
 144   // TODO: Iterate from high to low addresses and stop at the first valid one, should be faster.
 145   for (size_t i = 1; i <= sizeof(uintptr_t) * CHAR_BIT; ++i) {
 146     const uintptr_t base_addr = ((uintptr_t) 1U) << i;
 147     if (msync((void*)base_addr, page_size, MS_ASYNC) == 0) {
 148       // msync suceeded, the address is valid, and maybe even already mapped.
 149       max_address_bits = i;
 150       continue;
 151     }
 152     if (errno != ENOMEM) {
 153       // Some error occured. This should never happen, but msync
 154       // has some undefined behavior, hence ignore this bit.
 155       continue;
 156     }
 157     // Since msync failed with ENOMEM, the page might not be mapped.
 158     // Try to map it, to see if the address is valid.
 159     void* result_addr = mmap((void*) base_addr, page_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 160     if ((uintptr_t) result_addr == base_addr) {
 161       // address is valid
 162       max_address_bits = i;
 163     }
 164     if (result_addr != MAP_FAILED) {
 165       munmap(result_addr, page_size);
 166     }
 167   }
 168   max_address_bits += 1;
 169   log_info_p(gc, init)("Probing address space for the number of valid bits: %zu", max_address_bits);
 170   return max_address_bits;
 171 }
 172 
 173 size_t ZPlatformAddressOffsetBits() {
 174   const static size_t ZAddressBits = probe_valid_max_address_bit();
 175   const size_t max_address_offset_bits = ZAddressBits - 3;
 176   const size_t min_address_offset_bits = max_address_offset_bits - 2;
 177   const size_t address_offset = round_up_power_of_2(MaxHeapSize * ZVirtualToPhysicalRatio);
 178   const size_t address_offset_bits = log2_intptr(address_offset);
 179   return clamp(address_offset_bits, min_address_offset_bits, max_address_offset_bits);
 180 }
 181 
 182 size_t ZPlatformAddressMetadataShift() {
 183   return ZPlatformAddressOffsetBits();
 184 }