1 /*
   2  * Copyright (c) 2015, 2020, 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/z/zList.inline.hpp"
  26 #include "gc/z/zPage.inline.hpp"
  27 #include "gc/z/zPhysicalMemory.inline.hpp"
  28 #include "gc/z/zVirtualMemory.inline.hpp"
  29 #include "utilities/align.hpp"
  30 #include "utilities/debug.hpp"
  31 
  32 ZPage::ZPage(const ZVirtualMemory& vmem, const ZPhysicalMemory& pmem) :
  33     _type(type_from_size(vmem.size())),
  34     _numa_id((uint8_t)-1),
  35     _seqnum(0),
  36     _virtual(vmem),
  37     _top(start()),
  38     _livemap(object_max_count()),
  39     _last_used(0),
  40     _physical(pmem) {
  41   assert_initialized();
  42 }
  43 
  44 ZPage::ZPage(uint8_t type, const ZVirtualMemory& vmem, const ZPhysicalMemory& pmem) :
  45     _type(type),
  46     _numa_id((uint8_t)-1),
  47     _seqnum(0),
  48     _virtual(vmem),
  49     _top(start()),
  50     _livemap(object_max_count()),
  51     _last_used(0),
  52     _physical(pmem) {
  53   assert_initialized();
  54 }
  55 
  56 ZPage::~ZPage() {}
  57 
  58 void ZPage::assert_initialized() const {
  59   assert(!_virtual.is_null(), "Should not be null");
  60   assert(!_physical.is_null(), "Should not be null");
  61   assert(_virtual.size() == _physical.size(), "Virtual/Physical size mismatch");
  62   assert((_type == ZPageTypeSmall && size() == ZPageSizeSmall) ||
  63          (_type == ZPageTypeMedium && size() == ZPageSizeMedium) ||
  64          (_type == ZPageTypeLarge && is_aligned(size(), ZGranuleSize)),
  65          "Page type/size mismatch");
  66 }
  67 
  68 void ZPage::reset() {
  69   _seqnum = ZGlobalSeqNum;
  70   _top = start();
  71   _livemap.reset();
  72   _last_used = 0;
  73 }
  74 
  75 ZPage* ZPage::retype(uint8_t type) {
  76   assert(_type != type, "Invalid retype");
  77   _type = type;
  78   _livemap.resize(object_max_count());
  79   return this;
  80 }
  81 
  82 ZPage* ZPage::split(size_t size) {
  83   return split(type_from_size(size), size);
  84 }
  85 
  86 ZPage* ZPage::split(uint8_t type, size_t size) {
  87   assert(_virtual.size() > size, "Invalid split");
  88 
  89   // Resize this page, keep _numa_id, _seqnum, and _last_used
  90   const ZVirtualMemory vmem = _virtual.split(size);
  91   const ZPhysicalMemory pmem = _physical.split(size);
  92   _type = type_from_size(_virtual.size());
  93   _top = start();
  94   _livemap.resize(object_max_count());
  95 
  96   // Create new page, inherit _seqnum and _last_used
  97   ZPage* const page = new ZPage(type, vmem, pmem);
  98   page->_seqnum = _seqnum;
  99   page->_last_used = _last_used;
 100   return page;
 101 }
 102 
 103 ZPage* ZPage::split_committed() {
 104   // Split any committed part of this page into a separate page,
 105   // leaving this page with only uncommitted physical memory.
 106   const ZPhysicalMemory pmem = _physical.split_committed();
 107   if (pmem.is_null()) {
 108     // Nothing committed
 109     return NULL;
 110   }
 111 
 112   assert(!_physical.is_null(), "Should not be null");
 113 
 114   // Resize this page
 115   const ZVirtualMemory vmem = _virtual.split(pmem.size());
 116   _type = type_from_size(_virtual.size());
 117   _top = start();
 118   _livemap.resize(object_max_count());
 119 
 120   // Create new page
 121   return new ZPage(vmem, pmem);
 122 }
 123 
 124 void ZPage::print_on(outputStream* out) const {
 125   out->print_cr(" %-6s  " PTR_FORMAT " " PTR_FORMAT " " PTR_FORMAT " %s%s",
 126                 type_to_string(), start(), top(), end(),
 127                 is_allocating()  ? " Allocating"  : "",
 128                 is_relocatable() ? " Relocatable" : "");
 129 }
 130 
 131 void ZPage::print() const {
 132   print_on(tty);
 133 }