/*
 * Copyright (c) 2015, 2023, 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/shared/barrierSet.hpp"
#include "gc/shared/gc_globals.hpp"
#include "gc/z/zAddress.inline.hpp"
#include "gc/z/zVerify.hpp"
#include "oops/oopsHierarchy.hpp"
#include "runtime/java.hpp"
#include "utilities/formatBuffer.hpp"

size_t     ZAddressHeapBaseShift;
size_t     ZAddressHeapBase;

size_t     ZAddressOffsetBits;
uintptr_t  ZAddressOffsetMask;
size_t     ZAddressOffsetMax;

uintptr_t  ZPointerRemapped;
uintptr_t  ZPointerRemappedYoungMask;
uintptr_t  ZPointerRemappedOldMask;
uintptr_t  ZPointerMarkedYoung;
uintptr_t  ZPointerMarkedOld;
uintptr_t  ZPointerFinalizable;
uintptr_t  ZPointerRemembered;

uintptr_t  ZPointerLoadGoodMask;
uintptr_t  ZPointerLoadBadMask;

uintptr_t  ZPointerMarkGoodMask;
uintptr_t  ZPointerMarkBadMask;

uintptr_t  ZPointerStoreGoodMask;
uintptr_t  ZPointerStoreBadMask;

uintptr_t  ZPointerVectorLoadBadMask[8];
uintptr_t  ZPointerVectorStoreBadMask[8];
uintptr_t  ZPointerVectorStoreGoodMask[8];

static uint32_t* ZPointerCalculateStoreGoodMaskLowOrderBitsAddr() {
  const uintptr_t addr = reinterpret_cast<uintptr_t>(&ZPointerStoreGoodMask);
  return reinterpret_cast<uint32_t*>(addr + ZPointerStoreGoodMaskLowOrderBitsOffset);
}

uint32_t*  ZPointerStoreGoodMaskLowOrderBitsAddr = ZPointerCalculateStoreGoodMaskLowOrderBitsAddr();

static void set_vector_mask(uintptr_t vector_mask[], uintptr_t mask) {
  for (int i = 0; i < 8; ++i) {
    vector_mask[i] = mask;
  }
}

void ZGlobalsPointers::set_good_masks() {
  ZPointerRemapped = ZPointerRemappedOldMask & ZPointerRemappedYoungMask;

  ZPointerLoadGoodMask  = ZPointer::remap_bits(ZPointerRemapped);
  ZPointerMarkGoodMask  = ZPointerLoadGoodMask | ZPointerMarkedYoung | ZPointerMarkedOld;
  ZPointerStoreGoodMask = ZPointerMarkGoodMask | ZPointerRemembered;

  ZPointerLoadBadMask  = ZPointerLoadGoodMask  ^ ZPointerLoadMetadataMask;
  ZPointerMarkBadMask  = ZPointerMarkGoodMask  ^ ZPointerMarkMetadataMask;
  ZPointerStoreBadMask = ZPointerStoreGoodMask ^ ZPointerStoreMetadataMask;

  set_vector_mask(ZPointerVectorLoadBadMask, ZPointerLoadBadMask);
  set_vector_mask(ZPointerVectorStoreBadMask, ZPointerStoreBadMask);
  set_vector_mask(ZPointerVectorStoreGoodMask, ZPointerStoreGoodMask);

  pd_set_good_masks();
}

static void initialize_check_oop_function() {
#ifdef CHECK_UNHANDLED_OOPS
  if (ZVerifyOops) {
    // Enable extra verification of usages of oops in oopsHierarchy.hpp
    check_oop_function = [](oopDesc* obj) {
      (void)to_zaddress(obj);
    };
  }
#endif
}

void ZGlobalsPointers::initialize() {
  ZAddressOffsetBits = ZPlatformAddressOffsetBits();
  ZAddressOffsetMask = (((uintptr_t)1 << ZAddressOffsetBits) - 1) << ZAddressOffsetShift;
  ZAddressOffsetMax = (uintptr_t)1 << ZAddressOffsetBits;

  // Check max supported heap size
  if (MaxHeapSize > ZAddressOffsetMax) {
    vm_exit_during_initialization(
        err_msg("Java heap too large (max supported heap size is " SIZE_FORMAT "G)",
                ZAddressOffsetMax / G));
  }

  ZAddressHeapBaseShift = ZPlatformAddressHeapBaseShift();
  ZAddressHeapBase = (uintptr_t)1 << ZAddressHeapBaseShift;

  ZPointerRemappedYoungMask = ZPointerRemapped10 | ZPointerRemapped00;
  ZPointerRemappedOldMask = ZPointerRemapped01 | ZPointerRemapped00;
  ZPointerMarkedYoung = ZPointerMarkedYoung0;
  ZPointerMarkedOld = ZPointerMarkedOld0;
  ZPointerFinalizable = ZPointerFinalizable0;
  ZPointerRemembered = ZPointerRemembered0;

  set_good_masks();

  initialize_check_oop_function();
}

void ZGlobalsPointers::flip_young_mark_start() {
  ZPointerMarkedYoung ^= (ZPointerMarkedYoung0 | ZPointerMarkedYoung1);
  ZPointerRemembered ^= (ZPointerRemembered0 | ZPointerRemembered1);
  set_good_masks();
}

void ZGlobalsPointers::flip_young_relocate_start() {
  ZPointerRemappedYoungMask ^= ZPointerRemappedMask;
  set_good_masks();
}

void ZGlobalsPointers::flip_old_mark_start() {
  ZPointerMarkedOld ^= (ZPointerMarkedOld0 | ZPointerMarkedOld1);
  ZPointerFinalizable ^= (ZPointerFinalizable0 | ZPointerFinalizable1);
  set_good_masks();
}

void ZGlobalsPointers::flip_old_relocate_start() {
  ZPointerRemappedOldMask ^= ZPointerRemappedMask;
  set_good_masks();
}
