JDK14/Java14源码在线阅读

JDK14/Java14源码在线阅读 / hotspot / os / windows / gc / z / zVirtualMemory_windows.cpp
/*
 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "precompiled.hpp"
#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zGlobals.hpp"
#include "gc/z/zMapper_windows.hpp"
#include "gc/z/zVirtualMemory.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"

static void split_placeholder(uintptr_t start, size_t size) {
  ZMapper::split_placeholder(ZAddress::marked0(start), size);
  ZMapper::split_placeholder(ZAddress::marked1(start), size);
  ZMapper::split_placeholder(ZAddress::remapped(start), size);
}

static void coalesce_placeholders(uintptr_t start, size_t size) {
  ZMapper::coalesce_placeholders(ZAddress::marked0(start), size);
  ZMapper::coalesce_placeholders(ZAddress::marked1(start), size);
  ZMapper::coalesce_placeholders(ZAddress::remapped(start), size);
}

static void split_into_placeholder_granules(uintptr_t start, size_t size) {
  for (uintptr_t addr = start; addr < start + size; addr += ZGranuleSize) {
    split_placeholder(addr, ZGranuleSize);
  }
}

static void coalesce_into_one_placeholder(uintptr_t start, size_t size) {
  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");

  if (size > ZGranuleSize) {
    coalesce_placeholders(start, size);
  }
}

static void create_callback(const ZMemory* area) {
  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
  coalesce_into_one_placeholder(area->start(), area->size());
}

static void destroy_callback(const ZMemory* area) {
  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
  // Don't try split the last granule - VirtualFree will fail
  split_into_placeholder_granules(area->start(), area->size() - ZGranuleSize);
}

static void shrink_from_front_callback(const ZMemory* area, size_t size) {
  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
  split_into_placeholder_granules(area->start(), size);
}

static void shrink_from_back_callback(const ZMemory* area, size_t size) {
  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");
  // Don't try split the last granule - VirtualFree will fail
  split_into_placeholder_granules(area->end() - size, size - ZGranuleSize);
}

static void grow_from_front_callback(const ZMemory* area, size_t size) {
  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
  coalesce_into_one_placeholder(area->start() - size, area->size() + size);
}

static void grow_from_back_callback(const ZMemory* area, size_t size) {
  assert(is_aligned(area->size(), ZGranuleSize), "Must be granule aligned");
  coalesce_into_one_placeholder(area->start(), area->size() + size);
}

void ZVirtualMemoryManager::initialize_os() {
  // Each reserved virtual memory address area registered in _manager is
  // exactly covered by a single placeholder. Callbacks are installed so
  // that whenever a memory area changes, the corresponding placeholder
  // is adjusted.
  //
  // The create and grow callbacks are called when virtual memory is
  // returned to the memory manager. The new memory area is then covered
  // by a new single placeholder.
  //
  // The destroy and shrink callbacks are called when virtual memory is
  // allocated from the memory manager. The memory area is then is split
  // into granule-sized placeholders.
  //
  // See comment in zMapper_windows.cpp explaining why placeholders are
  // split into ZGranuleSize sized placeholders.

  ZMemoryManager::Callbacks callbacks;

  callbacks._create = &create_callback;
  callbacks._destroy = &destroy_callback;
  callbacks._shrink_from_front = &shrink_from_front_callback;
  callbacks._shrink_from_back = &shrink_from_back_callback;
  callbacks._grow_from_front = &grow_from_front_callback;
  callbacks._grow_from_back = &grow_from_back_callback;

  _manager.register_callbacks(callbacks);
}

bool ZVirtualMemoryManager::reserve_contiguous_platform(uintptr_t start, size_t size) {
  assert(is_aligned(size, ZGranuleSize), "Must be granule aligned");

  // Reserve address views
  const uintptr_t marked0 = ZAddress::marked0(start);
  const uintptr_t marked1 = ZAddress::marked1(start);

/**代码未完, 请加载全部代码(NowJava.com).**/
展开阅读全文

关注时代Java

关注时代Java