diff --git a/java/openjdk8/Makefile b/java/openjdk8/Makefile
index 5ba2c028fb93..ff74e827e875 100644
--- a/java/openjdk8/Makefile
+++ b/java/openjdk8/Makefile
@@ -191,7 +191,7 @@ CONFIGURE_ARGS+=	--disable-jfr
 MAKE_ENV+=	LFLAGS="-Wl,-z,notext"
 .endif
 
-.if ${ARCH} == amd64 || ${ARCH} == i386 || ${ARCH:Mpowerpc64*}
+.if ${ARCH} == aarch64 || ${ARCH} == amd64 || ${ARCH} == i386 || ${ARCH:Mpowerpc64*}
 JDK_BUILD_JVM=	server
 .else
 JDK_BUILD_JVM=	zero
diff --git a/java/openjdk8/files/patch-aarch64 b/java/openjdk8/files/patch-aarch64
new file mode 100644
index 000000000000..f43f3709c1a3
--- /dev/null
+++ b/java/openjdk8/files/patch-aarch64
@@ -0,0 +1,4895 @@
+From 4a567563bfb999146b94d21bb472f924797f633b Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 14:54:28 +0200
+Subject: [PATCH 01/18] Copy/paste some files from linux to bsd and rename them
+ to *bsd*
+
+mkdir hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64
+cp hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64CFrame.java \
+   hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
+cp hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/aarch64/LinuxAARCH64ThreadContext.java \
+   hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
+
+mkdir hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64
+cp hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/linux_aarch64/LinuxAARCH64JavaThreadPDAccess.java \
+   hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+
+cd hotspot/src/os_cpu
+mkdir -p bsd_aarch64/vm
+for file in $(ls linux_aarch64/*)
+do
+  bsd=$(echo $file | sed 's/linux/bsd/g')
+  cp linux_aarch64/vm/${file} bsd_aarch64/vm/${bsd}
+done
+---
+ .../bsd/aarch64/BsdAARCH64CFrame.java         |  86 +++
+ .../bsd/aarch64/BsdAARCH64ThreadContext.java  |  47 ++
+ .../BsdAARCH64JavaThreadPDAccess.java         | 132 ++++
+ .../bsd_aarch64/vm/assembler_bsd_aarch64.cpp  |  53 ++
+ .../vm/atomic_bsd_aarch64.inline.hpp          | 143 ++++
+ .../src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad  |  68 ++
+ .../vm/bytes_bsd_aarch64.inline.hpp           |  44 ++
+ .../vm/copy_bsd_aarch64.inline.hpp            | 248 +++++++
+ .../os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s  | 411 +++++++++++
+ .../bsd_aarch64/vm/globals_bsd_aarch64.hpp    |  44 ++
+ .../vm/orderAccess_bsd_aarch64.inline.hpp     | 144 ++++
+ .../os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp  | 657 ++++++++++++++++++
+ .../os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp  |  58 ++
+ .../bsd_aarch64/vm/os_bsd_aarch64.inline.hpp  |  39 ++
+ .../vm/prefetch_bsd_aarch64.inline.hpp        |  41 ++
+ .../bsd_aarch64/vm/threadLS_bsd_aarch64.cpp   |  41 ++
+ .../bsd_aarch64/vm/threadLS_bsd_aarch64.hpp   |  36 +
+ .../bsd_aarch64/vm/thread_bsd_aarch64.cpp     |  92 +++
+ .../bsd_aarch64/vm/thread_bsd_aarch64.hpp     |  80 +++
+ .../bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp  |  54 ++
+ .../bsd_aarch64/vm/vm_version_bsd_aarch64.cpp |  28 +
+ 21 files changed, 2546 insertions(+)
+ create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
+ create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
+ create mode 100644 hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/assembler_bsd_aarch64.cpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.cpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
+ create mode 100644 hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
+
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
+new file mode 100644
+index 0000000000..28e36759a5
+--- /dev/null
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2015, Red Hat Inc.
++ * 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.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.linux.aarch64;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.aarch64.*;
++import sun.jvm.hotspot.debugger.linux.*;
++import sun.jvm.hotspot.debugger.cdbg.*;
++import sun.jvm.hotspot.debugger.cdbg.basic.*;
++
++final public class LinuxAARCH64CFrame extends BasicCFrame {
++   public LinuxAARCH64CFrame(LinuxDebugger dbg, Address fp, Address pc) {
++      super(dbg.getCDebugger());
++      this.fp = fp;
++      this.pc = pc;
++      this.dbg = dbg;
++   }
++
++   // override base class impl to avoid ELF parsing
++   public ClosestSymbol closestSymbolToPC() {
++      // try native lookup in debugger.
++      return dbg.lookup(dbg.getAddressValue(pc()));
++   }
++
++   public Address pc() {
++      return pc;
++   }
++
++   public Address localVariableBase() {
++      return fp;
++   }
++
++   public CFrame sender(ThreadProxy thread) {
++      AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext();
++      Address rsp = context.getRegisterAsAddress(AARCH64ThreadContext.SP);
++
++      if ((fp == null) || fp.lessThan(rsp)) {
++        return null;
++      }
++
++      // Check alignment of fp
++      if (dbg.getAddressValue(fp) % (2 * ADDRESS_SIZE) != 0) {
++        return null;
++      }
++
++      Address nextFP = fp.getAddressAt(0 * ADDRESS_SIZE);
++      if (nextFP == null || nextFP.lessThanOrEqual(fp)) {
++        return null;
++      }
++      Address nextPC  = fp.getAddressAt(1 * ADDRESS_SIZE);
++      if (nextPC == null) {
++        return null;
++      }
++      return new LinuxAARCH64CFrame(dbg, nextFP, nextPC);
++   }
++
++   // package/class internals only
++   private static final int ADDRESS_SIZE = 8;
++   private Address pc;
++   private Address sp;
++   private Address fp;
++   private LinuxDebugger dbg;
++}
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
+new file mode 100644
+index 0000000000..7700316867
+--- /dev/null
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
+@@ -0,0 +1,47 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2015, Red Hat Inc.
++ * 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.
++ *
++ */
++
++package sun.jvm.hotspot.debugger.linux.aarch64;
++
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.aarch64.*;
++import sun.jvm.hotspot.debugger.linux.*;
++
++public class LinuxAARCH64ThreadContext extends AARCH64ThreadContext {
++  private LinuxDebugger debugger;
++
++  public LinuxAARCH64ThreadContext(LinuxDebugger debugger) {
++    super();
++    this.debugger = debugger;
++  }
++
++  public void setRegisterAsAddress(int index, Address value) {
++    setRegister(index, debugger.getAddressValue(value));
++  }
++
++  public Address getRegisterAsAddress(int index) {
++    return debugger.newAddress(getRegister(index));
++  }
++}
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+new file mode 100644
+index 0000000000..bf40afe005
+--- /dev/null
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+@@ -0,0 +1,132 @@
++/*
++ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2015, Red Hat Inc.
++ * 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.
++ *
++ */
++
++package sun.jvm.hotspot.runtime.linux_aarch64;
++
++import java.io.*;
++import java.util.*;
++import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.aarch64.*;
++import sun.jvm.hotspot.runtime.*;
++import sun.jvm.hotspot.runtime.aarch64.*;
++import sun.jvm.hotspot.types.*;
++import sun.jvm.hotspot.utilities.*;
++
++public class LinuxAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
++  private static AddressField  lastJavaFPField;
++  private static AddressField  osThreadField;
++
++  // Field from OSThread
++  private static CIntegerField osThreadThreadIDField;
++
++  // This is currently unneeded but is being kept in case we change
++  // the currentFrameGuess algorithm
++  private static final long GUESS_SCAN_RANGE = 128 * 1024;
++
++  static {
++    VM.registerVMInitializedObserver(new Observer() {
++        public void update(Observable o, Object data) {
++          initialize(VM.getVM().getTypeDataBase());
++        }
++      });
++  }
++
++  private static synchronized void initialize(TypeDataBase db) {
++    Type type = db.lookupType("JavaThread");
++    osThreadField           = type.getAddressField("_osthread");
++
++    Type anchorType = db.lookupType("JavaFrameAnchor");
++    lastJavaFPField         = anchorType.getAddressField("_last_Java_fp");
++
++    Type osThreadType = db.lookupType("OSThread");
++    osThreadThreadIDField   = osThreadType.getCIntegerField("_thread_id");
++  }
++
++  public Address getLastJavaFP(Address addr) {
++    return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset()));
++  }
++
++  public Address getLastJavaPC(Address addr) {
++    return null;
++  }
++
++  public Address getBaseOfStackPointer(Address addr) {
++    return null;
++  }
++
++  public Frame getLastFramePD(JavaThread thread, Address addr) {
++    Address fp = thread.getLastJavaFP();
++    if (fp == null) {
++      return null; // no information
++    }
++    return new AARCH64Frame(thread.getLastJavaSP(), fp);
++  }
++
++  public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) {
++    return new AARCH64RegisterMap(thread, updateMap);
++  }
++
++  public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
++    ThreadProxy t = getThreadProxy(addr);
++    AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
++    AARCH64CurrentFrameGuess guesser = new AARCH64CurrentFrameGuess(context, thread);
++    if (!guesser.run(GUESS_SCAN_RANGE)) {
++      return null;
++    }
++    if (guesser.getPC() == null) {
++      return new AARCH64Frame(guesser.getSP(), guesser.getFP());
++    } else {
++      return new AARCH64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC());
++    }
++  }
++
++  public void printThreadIDOn(Address addr, PrintStream tty) {
++    tty.print(getThreadProxy(addr));
++  }
++
++  public void printInfoOn(Address threadAddr, PrintStream tty) {
++    tty.print("Thread id: ");
++    printThreadIDOn(threadAddr, tty);
++//    tty.println("\nPostJavaState: " + getPostJavaState(threadAddr));
++  }
++
++  public Address getLastSP(Address addr) {
++    ThreadProxy t = getThreadProxy(addr);
++    AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext();
++    return context.getRegisterAsAddress(AARCH64ThreadContext.SP);
++  }
++
++  public ThreadProxy getThreadProxy(Address addr) {
++    // Addr is the address of the JavaThread.
++    // Fetch the OSThread (for now and for simplicity, not making a
++    // separate "OSThread" class in this package)
++    Address osThreadAddr = osThreadField.getValue(addr);
++    // Get the address of the _thread_id from the OSThread
++    Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
++
++    JVMDebugger debugger = VM.getVM().getDebugger();
++    return debugger.getThreadForIdentifierAddress(threadIdAddr);
++  }
++}
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/assembler_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/assembler_bsd_aarch64.cpp
+new file mode 100644
+index 0000000000..9bda6ecd64
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/assembler_bsd_aarch64.cpp
+@@ -0,0 +1,53 @@
++/*
++ * Copyright (c) 1999, 2010, 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 "asm/macroAssembler.hpp"
++#include "asm/macroAssembler.inline.hpp"
++#include "runtime/os.hpp"
++#include "runtime/threadLocalStorage.hpp"
++
++
++// get_thread can be called anywhere inside generated code so we need
++// to save whatever non-callee save context might get clobbered by the
++// call to the C thread_local lookup call or, indeed, the call setup
++// code. x86 appears to save C arg registers.
++
++void MacroAssembler::get_thread(Register dst) {
++  // call pthread_getspecific
++  // void * pthread_getspecific(pthread_key_t key);
++
++  // Save all call-clobbered regs except dst, plus r19 and r20.
++  RegSet saved_regs = RegSet::range(r0, r20) + lr - dst;
++  push(saved_regs, sp);
++  mov(c_rarg0, ThreadLocalStorage::thread_index());
++  mov(r19, CAST_FROM_FN_PTR(address, pthread_getspecific));
++  blr(r19);
++  if (dst != c_rarg0) {
++    mov(dst, c_rarg0);
++  }
++  // restore pushed registers
++  pop(saved_regs, sp);
++}
++
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp
+new file mode 100644
+index 0000000000..fba64e15f8
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp
+@@ -0,0 +1,143 @@
++/*
++ * Copyright (c) 1999, 2011, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP
++#define OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP
++
++#include "runtime/atomic.hpp"
++#include "runtime/os.hpp"
++#include "vm_version_aarch64.hpp"
++
++// Implementation of class atomic
++
++#define FULL_MEM_BARRIER  __sync_synchronize()
++#define READ_MEM_BARRIER  __atomic_thread_fence(__ATOMIC_ACQUIRE);
++#define WRITE_MEM_BARRIER __atomic_thread_fence(__ATOMIC_RELEASE);
++
++inline void Atomic::store    (jbyte    store_value, jbyte*    dest) { *dest = store_value; }
++inline void Atomic::store    (jshort   store_value, jshort*   dest) { *dest = store_value; }
++inline void Atomic::store    (jint     store_value, jint*     dest) { *dest = store_value; }
++inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; }
++inline void Atomic::store_ptr(void*    store_value, void*     dest) { *(void**)dest = store_value; }
++
++inline void Atomic::store    (jbyte    store_value, volatile jbyte*    dest) { *dest = store_value; }
++inline void Atomic::store    (jshort   store_value, volatile jshort*   dest) { *dest = store_value; }
++inline void Atomic::store    (jint     store_value, volatile jint*     dest) { *dest = store_value; }
++inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
++inline void Atomic::store_ptr(void*    store_value, volatile void*     dest) { *(void* volatile *)dest = store_value; }
++
++
++inline jint Atomic::add(jint add_value, volatile jint* dest)
++{
++ return __sync_add_and_fetch(dest, add_value);
++}
++
++inline void Atomic::inc(volatile jint* dest)
++{
++ add(1, dest);
++}
++
++inline void Atomic::inc_ptr(volatile void* dest)
++{
++ add_ptr(1, dest);
++}
++
++inline void Atomic::dec (volatile jint* dest)
++{
++ add(-1, dest);
++}
++
++inline void Atomic::dec_ptr(volatile void* dest)
++{
++ add_ptr(-1, dest);
++}
++
++inline jint Atomic::xchg (jint exchange_value, volatile jint* dest)
++{
++  jint res = __sync_lock_test_and_set (dest, exchange_value);
++  FULL_MEM_BARRIER;
++  return res;
++}
++
++inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest)
++{
++  return (void *) xchg_ptr((intptr_t) exchange_value,
++                           (volatile intptr_t*) dest);
++}
++
++inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value)
++{
++ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
++}
++
++inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
++inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
++
++inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
++{
++ return __sync_add_and_fetch(dest, add_value);
++}
++
++inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest)
++{
++  return (void *) add_ptr(add_value, (volatile intptr_t *) dest);
++}
++
++inline void Atomic::inc_ptr(volatile intptr_t* dest)
++{
++ add_ptr(1, dest);
++}
++
++inline void Atomic::dec_ptr(volatile intptr_t* dest)
++{
++ add_ptr(-1, dest);
++}
++
++inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest)
++{
++  intptr_t res = __sync_lock_test_and_set (dest, exchange_value);
++  FULL_MEM_BARRIER;
++  return res;
++}
++
++inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value)
++{
++ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
++}
++
++inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value)
++{
++ return __sync_val_compare_and_swap(dest, compare_value, exchange_value);
++}
++
++inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value)
++{
++  return (void *) cmpxchg_ptr((intptr_t) exchange_value,
++                              (volatile intptr_t*) dest,
++                              (intptr_t) compare_value);
++}
++
++inline jlong Atomic::load(volatile jlong* src) { return *src; }
++
++#endif // OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad b/hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad
+new file mode 100644
+index 0000000000..a71f7d16c1
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad
+@@ -0,0 +1,68 @@
++//
++// Copyright (c) 2003, 2012, 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.
++//
++//
++
++// AMD64 Linux Architecture Description File
++
++//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------
++// This block specifies the encoding classes used by the compiler to
++// output byte streams.  Encoding classes generate functions which are
++// called by Machine Instruction Nodes in order to generate the bit
++// encoding of the instruction.  Operands specify their base encoding
++// interface with the interface keyword.  There are currently
++// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
++// COND_INTER.  REG_INTER causes an operand to generate a function
++// which returns its register number when queried.  CONST_INTER causes
++// an operand to generate a function which returns the value of the
++// constant when queried.  MEMORY_INTER causes an operand to generate
++// four functions which return the Base Register, the Index Register,
++// the Scale Value, and the Offset Value of the operand when queried.
++// COND_INTER causes an operand to generate six functions which return
++// the encoding code (ie - encoding bits for the instruction)
++// associated with each basic boolean condition for a conditional
++// instruction.  Instructions specify two basic values for encoding.
++// They use the ins_encode keyword to specify their encoding class
++// (which must be one of the class names specified in the encoding
++// block), and they use the opcode keyword to specify, in order, their
++// primary, secondary, and tertiary opcode.  Only the opcode sections
++// which a particular instruction needs for encoding need to be
++// specified.
++encode %{
++  // Build emit functions for each basic byte or larger field in the intel
++  // encoding scheme (opcode, rm, sib, immediate), and call them from C++
++  // code in the enc_class source block.  Emit functions will live in the
++  // main source block for now.  In future, we can generalize this by
++  // adding a syntax that specifies the sizes of fields in an order,
++  // so that the adlc can build the emit functions automagically
++
++  enc_class Java_To_Runtime(method meth) %{
++  %}
++
++%}
++
++
++// Platform dependent source
++
++source %{
++
++%}
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
+new file mode 100644
+index 0000000000..beb33f8afd
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 1999, 2010, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_BYTES_LINUX_AARCH64_INLINE_HPP
++#define OS_CPU_LINUX_AARCH64_VM_BYTES_LINUX_AARCH64_INLINE_HPP
++
++#include <byteswap.h>
++
++// Efficient swapping of data bytes from Java byte
++// ordering to native byte ordering and vice versa.
++inline u2   Bytes::swap_u2(u2 x) {
++  return bswap_16(x);
++}
++
++inline u4   Bytes::swap_u4(u4 x) {
++  return bswap_32(x);
++}
++
++inline u8 Bytes::swap_u8(u8 x) {
++  return bswap_64(x);
++}
++
++#endif // OS_CPU_LINUX_AARCH64_VM_BYTES_LINUX_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp
+new file mode 100644
+index 0000000000..c47e866f0a
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp
+@@ -0,0 +1,248 @@
++/*
++ * Copyright (c) 2003, 2010, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_COPY_LINUX_AARCH64_INLINE_HPP
++#define OS_CPU_LINUX_AARCH64_VM_COPY_LINUX_AARCH64_INLINE_HPP
++
++#define COPY_SMALL(from, to, count)                                     \
++{                                                                       \
++        long tmp0, tmp1, tmp2, tmp3;                                    \
++        long tmp4, tmp5, tmp6, tmp7;                                    \
++  __asm volatile(                                                       \
++"       adr     %[t0], 0f;"                                             \
++"       add     %[t0], %[t0], %[cnt], lsl #6;"                          \
++"       br      %[t0];"                                                 \
++"       .align  6;"                                                     \
++"0:"                                                                    \
++"       b       1f;"                                                    \
++"8:"                                                                    \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       ldp     %[t1], %[t2], [%[s], #8];"                              \
++"       ldp     %[t3], %[t4], [%[s], #24];"                             \
++"       ldr     %[t5], [%[s], #40];"                                    \
++"       tbz     %[d], #3, 10f;"                                         \
++"9:"                                                                    \
++"       str     %[t0], [%[d], #0];"                                     \
++"       stp     %[t1], %[t2], [%[d], #8];"                              \
++"       stp     %[t3], %[t4], [%[d], #24];"                             \
++"       str     %[t5], [%[d], #40];"                                    \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       str     %[t0], [%[d], #0];"                                     \
++"       b       1f;"                                                    \
++"2:"                                                                    \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       ldp     %[t1], %[t2], [%[s], #8];"                              \
++"       ldp     %[t3], %[t4], [%[s], #24];"                             \
++"       ldp     %[t5], %[t6], [%[s], #40];"                             \
++"       ldr     %[t7], [%[s], #56];"                                    \
++"       tbz     %[d], #3, 4f;"                                          \
++"3:"                                                                    \
++"       str     %[t0], [%[d], #0];"                                     \
++"       stp     %[t1], %[t2], [%[d], #8];"                              \
++"       stp     %[t3], %[t4], [%[d], #24];"                             \
++"       stp     %[t5], %[t6], [%[d], #40];"                             \
++"       str     %[t7], [%[d], #56];"                                    \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       ldr     %[t1], [%[s], #8];"                                     \
++"       str     %[t0], [%[d], #0];"                                     \
++"       str     %[t1], [%[d], #8];"                                     \
++"       b       1f;"                                                    \
++"5:"                                                                    \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       ldp     %[t1], %[t2], [%[s], #8];"                              \
++"       ldp     %[t3], %[t4], [%[s], #24];"                             \
++"       ldp     %[t5], %[t6], [%[s], #40];"                             \
++"       tbz     %[d], #3, 7f;"                                          \
++"6:"                                                                    \
++"       str     %[t0], [%[d], #0];"                                     \
++"       stp     %[t1], %[t2], [%[d], #8];"                              \
++"       stp     %[t3], %[t4], [%[d], #24];"                             \
++"       stp     %[t5], %[t6], [%[d], #40];"                             \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       ldr     %[t1], [%[s], #8];"                                     \
++"       ldr     %[t2], [%[s], #16];"                                    \
++"       str     %[t0], [%[d], #0];"                                     \
++"       str     %[t1], [%[d], #8];"                                     \
++"       str     %[t2], [%[d], #16];"                                    \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       ldr     %[t1], [%[s], #8];"                                     \
++"       ldr     %[t2], [%[s], #16];"                                    \
++"       ldr     %[t3], [%[s], #24];"                                    \
++"       str     %[t0], [%[d], #0];"                                     \
++"       str     %[t1], [%[d], #8];"                                     \
++"       str     %[t2], [%[d], #16];"                                    \
++"       str     %[t3], [%[d], #24];"                                    \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       ldr     %[t0], [%[s], #0];"                                     \
++"       ldr     %[t1], [%[s], #8];"                                     \
++"       ldr     %[t2], [%[s], #16];"                                    \
++"       ldr     %[t3], [%[s], #24];"                                    \
++"       ldr     %[t4], [%[s], #32];"                                    \
++"       str     %[t0], [%[d], #0];"                                     \
++"       str     %[t1], [%[d], #8];"                                     \
++"       str     %[t2], [%[d], #16];"                                    \
++"       str     %[t3], [%[d], #24];"                                    \
++"       str     %[t4], [%[d], #32];"                                    \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       tbnz    %[s], #3, 8b;"                                          \
++"       ldp     %[t0], %[t1], [%[s], #0];"                              \
++"       ldp     %[t2], %[t3], [%[s], #16];"                             \
++"       ldp     %[t4], %[t5], [%[s], #32];"                             \
++"       tbnz    %[d], #3, 9b;"                                          \
++"10:"                                                                   \
++"       stp     %[t0], %[t1], [%[d], #0];"                              \
++"       stp     %[t2], %[t3], [%[d], #16];"                             \
++"       stp     %[t4], %[t5], [%[d], #32];"                             \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       tbnz    %[s], #3, 5b;"                                          \
++"       ldp     %[t0], %[t1], [%[s], #0];"                              \
++"       ldp     %[t2], %[t3], [%[s], #16];"                             \
++"       ldp     %[t4], %[t5], [%[s], #32];"                             \
++"       ldr     %[t6], [%[s], #48];"                                    \
++"       tbnz    %[d], #3, 6b;"                                          \
++"7:"                                                                    \
++"       stp     %[t0], %[t1], [%[d], #0];"                              \
++"       stp     %[t2], %[t3], [%[d], #16];"                             \
++"       stp     %[t4], %[t5], [%[d], #32];"                             \
++"       str     %[t6], [%[d], #48];"                                    \
++"       b       1f;"                                                    \
++"       .align  6;"                                                     \
++"       tbnz    %[s], #3, 2b;"                                          \
++"       ldp     %[t0], %[t1], [%[s], #0];"                              \
++"       ldp     %[t2], %[t3], [%[s], #16];"                             \
++"       ldp     %[t4], %[t5], [%[s], #32];"                             \
++"       ldp     %[t6], %[t7], [%[s], #48];"                             \
++"       tbnz    %[d], #3, 3b;"                                          \
++"4:"                                                                    \
++"       stp     %[t0], %[t1], [%[d], #0];"                              \
++"       stp     %[t2], %[t3], [%[d], #16];"                             \
++"       stp     %[t4], %[t5], [%[d], #32];"                             \
++"       stp     %[t6], %[t7], [%[d], #48];"                             \
++"1:"                                                                    \
++  : [s]"+r"(from), [d]"+r"(to), [cnt]"+r"(count),                       \
++    [t0]"=&r"(tmp0), [t1]"=&r"(tmp1), [t2]"=&r"(tmp2), [t3]"=&r"(tmp3), \
++    [t4]"=&r"(tmp4), [t5]"=&r"(tmp5), [t6]"=&r"(tmp6), [t7]"=&r"(tmp7)  \
++  :                                                                     \
++  : "memory", "cc");                                                    \
++}
++
++static void pd_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++  __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory");
++  if (__builtin_expect(count <= 8, 1)) {
++    COPY_SMALL(from, to, count);
++    return;
++  }
++  _Copy_conjoint_words(from, to, count);
++}
++
++static void pd_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++  if (__builtin_constant_p(count)) {
++    memcpy(to, from, count * sizeof(HeapWord));
++    return;
++  }
++  __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory");
++  if (__builtin_expect(count <= 8, 1)) {
++    COPY_SMALL(from, to, count);
++    return;
++  }
++  _Copy_disjoint_words(from, to, count);
++}
++
++static void pd_disjoint_words_atomic(HeapWord* from, HeapWord* to, size_t count) {
++  __asm volatile( "prfm pldl1strm, [%[s], #0];" :: [s]"r"(from) : "memory");
++  if (__builtin_expect(count <= 8, 1)) {
++    COPY_SMALL(from, to, count);
++    return;
++  }
++  _Copy_disjoint_words(from, to, count);
++}
++
++static void pd_aligned_conjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++  pd_conjoint_words(from, to, count);
++}
++
++static void pd_aligned_disjoint_words(HeapWord* from, HeapWord* to, size_t count) {
++  pd_disjoint_words(from, to, count);
++}
++
++static void pd_conjoint_bytes(void* from, void* to, size_t count) {
++  (void)memmove(to, from, count);
++}
++
++static void pd_conjoint_bytes_atomic(void* from, void* to, size_t count) {
++  pd_conjoint_bytes(from, to, count);
++}
++
++static void pd_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
++  _Copy_conjoint_jshorts_atomic(from, to, count);
++}
++
++static void pd_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
++  _Copy_conjoint_jints_atomic(from, to, count);
++}
++
++static void pd_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
++  _Copy_conjoint_jlongs_atomic(from, to, count);
++}
++
++static void pd_conjoint_oops_atomic(oop* from, oop* to, size_t count) {
++  assert(!UseCompressedOops, "foo!");
++  assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
++  _Copy_conjoint_jlongs_atomic((jlong*)from, (jlong*)to, count);
++}
++
++static void pd_arrayof_conjoint_bytes(HeapWord* from, HeapWord* to, size_t count) {
++  _Copy_arrayof_conjoint_bytes(from, to, count);
++}
++
++static void pd_arrayof_conjoint_jshorts(HeapWord* from, HeapWord* to, size_t count) {
++  _Copy_arrayof_conjoint_jshorts(from, to, count);
++}
++
++static void pd_arrayof_conjoint_jints(HeapWord* from, HeapWord* to, size_t count) {
++   _Copy_arrayof_conjoint_jints(from, to, count);
++}
++
++static void pd_arrayof_conjoint_jlongs(HeapWord* from, HeapWord* to, size_t count) {
++  _Copy_arrayof_conjoint_jlongs(from, to, count);
++}
++
++static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count) {
++  assert(!UseCompressedOops, "foo!");
++  assert(BytesPerLong == BytesPerOop, "jlongs and oops must be the same size");
++  _Copy_arrayof_conjoint_jlongs(from, to, count);
++}
++
++#endif // OS_CPU_LINUX_AARCH64_VM_COPY_LINUX_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s b/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s
+new file mode 100644
+index 0000000000..6d00d9f74e
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s
+@@ -0,0 +1,411 @@
++/*
++ * Copyright (c) 2016, Linaro Ltd. 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.
++ *
++ */
++        .global _Copy_conjoint_words
++        .global _Copy_disjoint_words
++
++s       .req    x0
++d       .req    x1
++count   .req    x2
++t0      .req    x3
++t1      .req    x4
++t2      .req    x5
++t3      .req    x6
++t4      .req    x7
++t5      .req    x8
++t6      .req    x9
++t7      .req    x10
++
++        .align  6
++_Copy_disjoint_words:
++        // Ensure 2 word aligned
++        tbz     s, #3, fwd_copy_aligned
++        ldr     t0, [s], #8
++        str     t0, [d], #8
++        sub     count, count, #1
++
++fwd_copy_aligned:
++        ldp     t0, t1, [s, #0]
++        ldp     t2, t3, [s, #16]
++        ldp     t4, t5, [s, #32]
++        ldp     t6, t7, [s, #48]!       // Source now biased by -16
++
++        tbnz    d, #3, unal_fwd_copy
++        sub     d, d, #16               // and bias dest
++
++        subs    count, count, #16
++        blo     fwd_copy_drain
++
++fwd_copy_again:
++        prfm    pldl1keep, [s, #256]
++        stp     t0, t1, [d, #16]
++        ldp     t0, t1, [s, #16]
++        stp     t2, t3, [d, #32]
++        ldp     t2, t3, [s, #32]
++        stp     t4, t5, [d, #48]
++        ldp     t4, t5, [s, #48]
++        stp     t6, t7, [d, #64]!
++        ldp     t6, t7, [s, #64]!
++        subs    count, count, #8
++        bhs     fwd_copy_again
++
++fwd_copy_drain:
++        stp     t0, t1, [d, #16]
++        stp     t2, t3, [d, #32]
++        stp     t4, t5, [d, #48]
++        stp     t6, t7, [d, #64]!
++
++        // count is now -8..-1 for 0..7 words to copy
++        adr     t0, 0f
++        add     t0, t0, count, lsl #5
++        br      t0
++
++        .align  5
++        ret                             // -8 == 0 words
++        .align  5
++        ldr     t0, [s, #16]            // -7 == 1 word
++        str     t0, [d, #16]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -6 = 2 words
++        stp     t0, t1, [d, #16]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -5 = 3 words
++        ldr     t2, [s, #32]
++        stp     t0, t1, [d, #16]
++        str     t2, [d, #32]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -4 = 4 words
++        ldp     t2, t3, [s, #32]
++        stp     t0, t1, [d, #16]
++        stp     t2, t3, [d, #32]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -3 = 5 words
++        ldp     t2, t3, [s, #32]
++        ldr     t4, [s, #48]
++        stp     t0, t1, [d, #16]
++        stp     t2, t3, [d, #32]
++        str     t4, [d, #48]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -2 = 6 words
++        ldp     t2, t3, [s, #32]
++        ldp     t4, t5, [s, #48]
++        stp     t0, t1, [d, #16]
++        stp     t2, t3, [d, #32]
++        stp     t4, t5, [d, #48]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -1 = 7 words
++        ldp     t2, t3, [s, #32]
++        ldp     t4, t5, [s, #48]
++        ldr     t6, [s, #64]
++        stp     t0, t1, [d, #16]
++        stp     t2, t3, [d, #32]
++        stp     t4, t5, [d, #48]
++        str     t6, [d, #64]
++        // Is always aligned here, code for 7 words is one instruction
++        // too large so it just falls through.
++        .align  5
++0:
++        ret
++
++unal_fwd_copy:
++        // Bias dest so we only pre index on the last copy
++        sub     d, d, #8
++        subs    count, count, #16
++        blo     unal_fwd_copy_drain
++
++unal_fwd_copy_again:
++        prfm    pldl1keep, [s, #256]
++        str     t0, [d, #8]
++        stp     t1, t2, [d, #16]
++        ldp     t0, t1, [s, #16]
++        stp     t3, t4, [d, #32]
++        ldp     t2, t3, [s, #32]
++        stp     t5, t6, [d, #48]
++        ldp     t4, t5, [s, #48]
++        str     t7, [d, #64]!
++        ldp     t6, t7, [s, #64]!
++        subs    count, count, #8
++        bhs     unal_fwd_copy_again
++
++unal_fwd_copy_drain:
++        str     t0, [d, #8]
++        stp     t1, t2, [d, #16]
++        stp     t3, t4, [d, #32]
++        stp     t5, t6, [d, #48]
++        str     t7, [d, #64]!
++
++        // count is now -8..-1 for 0..7 words to copy
++        adr     t0, 0f
++        add     t0, t0, count, lsl #5
++        br      t0
++
++        .align  5
++        ret                             // -8 == 0 words
++        .align  5
++        ldr     t0, [s, #16]            // -7 == 1 word
++        str     t0, [d, #8]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -6 = 2 words
++        str     t0, [d, #8]
++        str     t1, [d, #16]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -5 = 3 words
++        ldr     t2, [s, #32]
++        str     t0, [d, #8]
++        stp     t1, t2, [d, #16]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -4 = 4 words
++        ldp     t2, t3, [s, #32]
++        str     t0, [d, #8]
++        stp     t1, t2, [d, #16]
++        str     t3, [d, #32]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -3 = 5 words
++        ldp     t2, t3, [s, #32]
++        ldr     t4, [s, #48]
++        str     t0, [d, #8]
++        stp     t1, t2, [d, #16]
++        stp     t3, t4, [d, #32]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -2 = 6 words
++        ldp     t2, t3, [s, #32]
++        ldp     t4, t5, [s, #48]
++        str     t0, [d, #8]
++        stp     t1, t2, [d, #16]
++        stp     t3, t4, [d, #32]
++        str     t5, [d, #48]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #16]        // -1 = 7 words
++        ldp     t2, t3, [s, #32]
++        ldp     t4, t5, [s, #48]
++        ldr     t6, [s, #64]
++        str     t0, [d, #8]
++        stp     t1, t2, [d, #16]
++        stp     t3, t4, [d, #32]
++        stp     t5, t6, [d, #48]
++        // Is always aligned here, code for 7 words is one instruction
++        // too large so it just falls through.
++        .align  5
++0:
++        ret
++
++        .align  6
++_Copy_conjoint_words:
++        sub     t0, d, s
++        cmp     t0, count, lsl #3
++        bhs     _Copy_disjoint_words
++
++        add     s, s, count, lsl #3
++        add     d, d, count, lsl #3
++
++        // Ensure 2 word aligned
++        tbz     s, #3, bwd_copy_aligned
++        ldr     t0, [s, #-8]!
++        str     t0, [d, #-8]!
++        sub     count, count, #1
++
++bwd_copy_aligned:
++        ldp     t0, t1, [s, #-16]
++        ldp     t2, t3, [s, #-32]
++        ldp     t4, t5, [s, #-48]
++        ldp     t6, t7, [s, #-64]!
++
++        tbnz    d, #3, unal_bwd_copy
++
++        subs    count, count, #16
++        blo     bwd_copy_drain
++
++bwd_copy_again:
++        prfum   pldl1keep, [s, #-256]
++        stp     t0, t1, [d, #-16]
++        ldp     t0, t1, [s, #-16]
++        stp     t2, t3, [d, #-32]
++        ldp     t2, t3, [s, #-32]
++        stp     t4, t5, [d, #-48]
++        ldp     t4, t5, [s, #-48]
++        stp     t6, t7, [d, #-64]!
++        ldp     t6, t7, [s, #-64]!
++        subs    count, count, #8
++        bhs     bwd_copy_again
++
++bwd_copy_drain:
++        stp     t0, t1, [d, #-16]
++        stp     t2, t3, [d, #-32]
++        stp     t4, t5, [d, #-48]
++        stp     t6, t7, [d, #-64]!
++
++        // count is now -8..-1 for 0..7 words to copy
++        adr     t0, 0f
++        add     t0, t0, count, lsl #5
++        br      t0
++
++        .align  5
++        ret                             // -8 == 0 words
++        .align  5
++        ldr     t0, [s, #-8]            // -7 == 1 word
++        str     t0, [d, #-8]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -6 = 2 words
++        stp     t0, t1, [d, #-16]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -5 = 3 words
++        ldr     t2, [s, #-24]
++        stp     t0, t1, [d, #-16]
++        str     t2, [d, #-24]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -4 = 4 words
++        ldp     t2, t3, [s, #-32]
++        stp     t0, t1, [d, #-16]
++        stp     t2, t3, [d, #-32]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -3 = 5 words
++        ldp     t2, t3, [s, #-32]
++        ldr     t4, [s, #-40]
++        stp     t0, t1, [d, #-16]
++        stp     t2, t3, [d, #-32]
++        str     t4, [d, #-40]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -2 = 6 words
++        ldp     t2, t3, [s, #-32]
++        ldp     t4, t5, [s, #-48]
++        stp     t0, t1, [d, #-16]
++        stp     t2, t3, [d, #-32]
++        stp     t4, t5, [d, #-48]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -1 = 7 words
++        ldp     t2, t3, [s, #-32]
++        ldp     t4, t5, [s, #-48]
++        ldr     t6, [s, #-56]
++        stp     t0, t1, [d, #-16]
++        stp     t2, t3, [d, #-32]
++        stp     t4, t5, [d, #-48]
++        str     t6, [d, #-56]
++        // Is always aligned here, code for 7 words is one instruction
++        // too large so it just falls through.
++        .align  5
++0:
++        ret
++
++unal_bwd_copy:
++        subs    count, count, #16
++        blo     unal_bwd_copy_drain
++
++unal_bwd_copy_again:
++        prfm    pldl1keep, [s, #-256]
++        str     t1, [d, #-8]
++        stp     t3, t0, [d, #-24]
++        ldp     t0, t1, [s, #-16]
++        stp     t5, t2, [d, #-40]
++        ldp     t2, t3, [s, #-32]
++        stp     t7, t4, [d, #-56]
++        ldp     t4, t5, [s, #-48]
++        str     t6, [d, #-64]!
++        ldp     t6, t7, [s, #-64]!
++        subs    count, count, #8
++        bhs     unal_bwd_copy_again
++
++unal_bwd_copy_drain:
++        str     t1, [d, #-8]
++        stp     t3, t0, [d, #-24]
++        stp     t5, t2, [d, #-40]
++        stp     t7, t4, [d, #-56]
++        str     t6, [d, #-64]!
++
++        // count is now -8..-1 for 0..7 words to copy
++        adr     t0, 0f
++        add     t0, t0, count, lsl #5
++        br      t0
++
++        .align  5
++        ret                             // -8 == 0 words
++        .align  5
++        ldr     t0, [s, #-8]            // -7 == 1 word
++        str     t0, [d, #-8]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -6 = 2 words
++        str     t1, [d, #-8]
++        str     t0, [d, #-16]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -5 = 3 words
++        ldr     t2, [s, #-24]
++        str     t1, [d, #-8]
++        stp     t2, t0, [d, #-24]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -4 = 4 words
++        ldp     t2, t3, [s, #-32]
++        str     t1, [d, #-8]
++        stp     t3, t0, [d, #-24]
++        str     t2, [d, #-32]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -3 = 5 words
++        ldp     t2, t3, [s, #-32]
++        ldr     t4, [s, #-40]
++        str     t1, [d, #-8]
++        stp     t3, t0, [d, #-24]
++        stp     t4, t2, [d, #-40]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -2 = 6 words
++        ldp     t2, t3, [s, #-32]
++        ldp     t4, t5, [s, #-48]
++        str     t1, [d, #-8]
++        stp     t3, t0, [d, #-24]
++        stp     t5, t2, [d, #-40]
++        str     t4, [d, #-48]
++        ret
++        .align  5
++        ldp     t0, t1, [s, #-16]       // -1 = 7 words
++        ldp     t2, t3, [s, #-32]
++        ldp     t4, t5, [s, #-48]
++        ldr     t6, [s, #-56]
++        str     t1, [d, #-8]
++        stp     t3, t0, [d, #-24]
++        stp     t5, t2, [d, #-40]
++        stp     t6, t4, [d, #-56]
++        // Is always aligned here, code for 7 words is one instruction
++        // too large so it just falls through.
++        .align  5
++0:
++        ret
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp
+new file mode 100644
+index 0000000000..2733b47278
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2000, 2010, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_GLOBALS_LINUX_AARCH64_HPP
++#define OS_CPU_LINUX_AARCH64_VM_GLOBALS_LINUX_AARCH64_HPP
++
++// Sets the default values for platform dependent flags used by the runtime system.
++// (see globals.hpp)
++
++define_pd_global(bool, DontYieldALot,            false);
++define_pd_global(intx, ThreadStackSize,          2048); // 0 => use system default
++define_pd_global(intx, VMThreadStackSize,        2048);
++
++define_pd_global(intx, CompilerThreadStackSize,  0);
++
++define_pd_global(uintx,JVMInvokeMethodSlack,     8192);
++
++// Used on 64 bit platforms for UseCompressedOops base address
++define_pd_global(uintx,HeapBaseMinAddress,       2*G);
++
++extern __thread Thread *aarch64_currentThread;
++
++#endif // OS_CPU_LINUX_AARCH64_VM_GLOBALS_LINUX_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp
+new file mode 100644
+index 0000000000..c54c0469fa
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp
+@@ -0,0 +1,144 @@
++/*
++ * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright 2007, 2008, 2009 Red Hat, Inc.
++ * 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP
++#define OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP
++
++#include "runtime/atomic.inline.hpp"
++#include "runtime/orderAccess.hpp"
++#include "runtime/os.hpp"
++#include "vm_version_aarch64.hpp"
++
++// Implementation of class OrderAccess.
++
++inline void OrderAccess::loadload()   { acquire(); }
++inline void OrderAccess::storestore() { release(); }
++inline void OrderAccess::loadstore()  { acquire(); }
++inline void OrderAccess::storeload()  { fence(); }
++
++inline void OrderAccess::acquire() {
++  READ_MEM_BARRIER;
++}
++
++inline void OrderAccess::release() {
++  WRITE_MEM_BARRIER;
++}
++
++inline void OrderAccess::fence() {
++  FULL_MEM_BARRIER;
++}
++
++inline jbyte    OrderAccess::load_acquire(volatile jbyte*   p)
++{ jbyte data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline jshort   OrderAccess::load_acquire(volatile jshort*  p)
++{ jshort data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline jint     OrderAccess::load_acquire(volatile jint*    p)
++{ jint data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline jlong    OrderAccess::load_acquire(volatile jlong*   p)
++{ jlong data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline jubyte    OrderAccess::load_acquire(volatile jubyte*   p)
++{ jubyte data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline jushort   OrderAccess::load_acquire(volatile jushort*  p)
++{ jushort data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline juint     OrderAccess::load_acquire(volatile juint*    p)
++{ juint data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline julong   OrderAccess::load_acquire(volatile julong*  p)
++{ julong data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline jfloat   OrderAccess::load_acquire(volatile jfloat*  p)
++{ jfloat data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline jdouble  OrderAccess::load_acquire(volatile jdouble* p)
++{ jdouble data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline intptr_t OrderAccess::load_ptr_acquire(volatile intptr_t*   p)
++{ intptr_t data; __atomic_load(p, &data, __ATOMIC_ACQUIRE); return data; }
++inline void*    OrderAccess::load_ptr_acquire(volatile void*       p)
++{ void* data; __atomic_load((void* volatile *)p, &data, __ATOMIC_ACQUIRE); return data; }
++inline void*    OrderAccess::load_ptr_acquire(const volatile void* p)
++{ void* data; __atomic_load((void* const volatile *)p, &data, __ATOMIC_ACQUIRE); return data; }
++
++inline void     OrderAccess::release_store(volatile jbyte*   p, jbyte   v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile jshort*  p, jshort  v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile jint*    p, jint    v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile jlong*   p, jlong   v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile jubyte*  p, jubyte  v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile jushort* p, jushort v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile juint*   p, juint   v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile julong*  p, julong  v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile jfloat*  p, jfloat  v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store(volatile jdouble* p, jdouble v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store_ptr(volatile intptr_t* p, intptr_t v)
++{ __atomic_store(p, &v, __ATOMIC_RELEASE); }
++inline void     OrderAccess::release_store_ptr(volatile void*     p, void*    v)
++{ __atomic_store((void* volatile *)p, &v, __ATOMIC_RELEASE); }
++
++inline void     OrderAccess::store_fence(jbyte*   p, jbyte   v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(jshort*  p, jshort  v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(jint*    p, jint    v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(jlong*   p, jlong   v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(jubyte*  p, jubyte  v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(jushort* p, jushort v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(juint*   p, juint   v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(julong*  p, julong  v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(jfloat*  p, jfloat  v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_fence(jdouble* p, jdouble v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_ptr_fence(intptr_t* p, intptr_t v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++inline void     OrderAccess::store_ptr_fence(void**    p, void*    v)
++{ __atomic_store(p, &v, __ATOMIC_RELAXED); fence(); }
++
++inline void     OrderAccess::release_store_fence(volatile jbyte*   p, jbyte   v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile jshort*  p, jshort  v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile jint*    p, jint    v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile jlong*   p, jlong   v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile jubyte*  p, jubyte  v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile jushort* p, jushort v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile juint*   p, juint   v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile julong*  p, julong  v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile jfloat*  p, jfloat  v) { release_store(p, v); fence(); }
++inline void     OrderAccess::release_store_fence(volatile jdouble* p, jdouble v) { release_store(p, v); fence(); }
++
++inline void     OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); }
++inline void     OrderAccess::release_store_ptr_fence(volatile void*     p, void*    v) { release_store_ptr(p, v); fence(); }
++
++#endif // OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
+new file mode 100644
+index 0000000000..82e36d27f8
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
+@@ -0,0 +1,657 @@
++/*
++ * Copyright (c) 1999, 2018, 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.
++ *
++ */
++
++// no precompiled headers
++#include "asm/macroAssembler.hpp"
++#include "classfile/classLoader.hpp"
++#include "classfile/systemDictionary.hpp"
++#include "classfile/vmSymbols.hpp"
++#include "code/icBuffer.hpp"
++#include "code/vtableStubs.hpp"
++#include "interpreter/interpreter.hpp"
++#include "jvm_linux.h"
++#include "memory/allocation.inline.hpp"
++#include "mutex_linux.inline.hpp"
++#include "os_share_linux.hpp"
++#include "prims/jniFastGetField.hpp"
++#include "prims/jvm.h"
++#include "prims/jvm_misc.hpp"
++#include "runtime/arguments.hpp"
++#include "runtime/extendedPC.hpp"
++#include "runtime/frame.inline.hpp"
++#include "runtime/interfaceSupport.hpp"
++#include "runtime/java.hpp"
++#include "runtime/javaCalls.hpp"
++#include "runtime/mutexLocker.hpp"
++#include "runtime/osThread.hpp"
++#include "runtime/sharedRuntime.hpp"
++#include "runtime/stubRoutines.hpp"
++#include "runtime/thread.inline.hpp"
++#include "runtime/timer.hpp"
++#include "utilities/events.hpp"
++#include "utilities/vmError.hpp"
++
++// put OS-includes here
++# include <sys/types.h>
++# include <sys/mman.h>
++# include <pthread.h>
++# include <signal.h>
++# include <errno.h>
++# include <dlfcn.h>
++# include <stdlib.h>
++# include <stdio.h>
++# include <unistd.h>
++# include <sys/resource.h>
++# include <pthread.h>
++# include <sys/stat.h>
++# include <sys/time.h>
++# include <sys/utsname.h>
++# include <sys/socket.h>
++# include <sys/wait.h>
++# include <pwd.h>
++# include <poll.h>
++# include <ucontext.h>
++# include <fpu_control.h>
++
++#define REG_FP 29
++
++#define NOINLINE __attribute__ ((noinline))
++
++NOINLINE address os::current_stack_pointer() {
++  return (address)__builtin_frame_address(0);
++}
++
++char* os::non_memory_address_word() {
++  // Must never look like an address returned by reserve_memory,
++  // even in its subfields (as defined by the CPU immediate fields,
++  // if the CPU splits constants across multiple instructions).
++
++  return (char*) 0xffffffffffff;
++}
++
++void os::initialize_thread(Thread *thr) {
++}
++
++address os::Linux::ucontext_get_pc(ucontext_t * uc) {
++  return (address)uc->uc_mcontext.pc;
++}
++
++intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
++  return (intptr_t*)uc->uc_mcontext.sp;
++}
++
++intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
++  return (intptr_t*)uc->uc_mcontext.regs[REG_FP];
++}
++
++// For Forte Analyzer AsyncGetCallTrace profiling support - thread
++// is currently interrupted by SIGPROF.
++// os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal
++// frames. Currently we don't do that on Linux, so it's the same as
++// os::fetch_frame_from_context().
++ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
++  ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
++
++  assert(thread != NULL, "just checking");
++  assert(ret_sp != NULL, "just checking");
++  assert(ret_fp != NULL, "just checking");
++
++  return os::fetch_frame_from_context(uc, ret_sp, ret_fp);
++}
++
++ExtendedPC os::fetch_frame_from_context(void* ucVoid,
++                    intptr_t** ret_sp, intptr_t** ret_fp) {
++
++  ExtendedPC  epc;
++  ucontext_t* uc = (ucontext_t*)ucVoid;
++
++  if (uc != NULL) {
++    epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
++    if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc);
++    if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc);
++  } else {
++    // construct empty ExtendedPC for return value checking
++    epc = ExtendedPC(NULL);
++    if (ret_sp) *ret_sp = (intptr_t *)NULL;
++    if (ret_fp) *ret_fp = (intptr_t *)NULL;
++  }
++
++  return epc;
++}
++
++frame os::fetch_frame_from_context(void* ucVoid) {
++  intptr_t* sp;
++  intptr_t* fp;
++  ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
++  return frame(sp, fp, epc.pc());
++}
++
++// By default, gcc always saves frame pointer rfp on this stack. This
++// may get turned off by -fomit-frame-pointer.
++frame os::get_sender_for_C_frame(frame* fr) {
++  return frame(fr->link(), fr->link(), fr->sender_pc());
++}
++
++NOINLINE frame os::current_frame() {
++  intptr_t *fp = *(intptr_t **)__builtin_frame_address(0);
++  frame myframe((intptr_t*)os::current_stack_pointer(),
++                (intptr_t*)fp,
++                CAST_FROM_FN_PTR(address, os::current_frame));
++  if (os::is_first_C_frame(&myframe)) {
++    // stack is not walkable
++    return frame();
++  } else {
++    return os::get_sender_for_C_frame(&myframe);
++  }
++}
++
++// Utility functions
++
++// An operation in Unsafe has faulted.  We're going to return to the
++// instruction after the faulting load or store.  We also set
++// pending_unsafe_access_error so that at some point in the future our
++// user will get a helpful message.
++static address handle_unsafe_access(JavaThread* thread, address pc) {
++  // pc is the instruction which we must emulate
++  // doing a no-op is fine:  return garbage from the load
++  // therefore, compute npc
++  address npc = pc + NativeCall::instruction_size;
++
++  // request an async exception
++  thread->set_pending_unsafe_access_error();
++
++  // return address of next instruction to execute
++  return npc;
++}
++
++extern "C" JNIEXPORT int
++JVM_handle_linux_signal(int sig,
++                        siginfo_t* info,
++                        void* ucVoid,
++                        int abort_if_unrecognized) {
++  ucontext_t* uc = (ucontext_t*) ucVoid;
++
++  Thread* t = ThreadLocalStorage::get_thread_slow();
++
++  // Must do this before SignalHandlerMark, if crash protection installed we will longjmp away
++  // (no destructors can be run)
++  os::ThreadCrashProtection::check_crash_protection(sig, t);
++
++  SignalHandlerMark shm(t);
++
++  // Note: it's not uncommon that JNI code uses signal/sigset to install
++  // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
++  // or have a SIGILL handler when detecting CPU type). When that happens,
++  // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
++  // avoid unnecessary crash when libjsig is not preloaded, try handle signals
++  // that do not require siginfo/ucontext first.
++
++  if (sig == SIGPIPE || sig == SIGXFSZ) {
++    // allow chained handler to go first
++    if (os::Linux::chained_handler(sig, info, ucVoid)) {
++      return true;
++    } else {
++      if (PrintMiscellaneous && (WizardMode || Verbose)) {
++        char buf[64];
++        warning("Ignoring %s - see bugs 4229104 or 646499219",
++                os::exception_name(sig, buf, sizeof(buf)));
++      }
++      return true;
++    }
++  }
++
++  JavaThread* thread = NULL;
++  VMThread* vmthread = NULL;
++  if (os::Linux::signal_handlers_are_installed) {
++    if (t != NULL ){
++      if(t->is_Java_thread()) {
++        thread = (JavaThread*)t;
++      }
++      else if(t->is_VM_thread()){
++        vmthread = (VMThread *)t;
++      }
++    }
++  }
++/*
++  NOTE: does not seem to work on linux.
++  if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
++    // can't decode this kind of signal
++    info = NULL;
++  } else {
++    assert(sig == info->si_signo, "bad siginfo");
++  }
++*/
++  // decide if this trap can be handled by a stub
++  address stub = NULL;
++
++  address pc          = NULL;
++
++  //%note os_trap_1
++  if (info != NULL && uc != NULL && thread != NULL) {
++    pc = (address) os::Linux::ucontext_get_pc(uc);
++
++    if (StubRoutines::is_safefetch_fault(pc)) {
++      uc->uc_mcontext.pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
++      return 1;
++    }
++
++#ifndef AMD64
++    // Halt if SI_KERNEL before more crashes get misdiagnosed as Java bugs
++    // This can happen in any running code (currently more frequently in
++    // interpreter code but has been seen in compiled code)
++    if (sig == SIGSEGV && info->si_addr == 0 && info->si_code == SI_KERNEL) {
++      fatal("An irrecoverable SI_KERNEL SIGSEGV has occurred due "
++            "to unstable signal handling in this distribution.");
++    }
++#endif // AMD64
++
++    // Handle ALL stack overflow variations here
++    if (sig == SIGSEGV) {
++      address addr = (address) info->si_addr;
++
++      // check if fault address is within thread stack
++      if (addr < thread->stack_base() &&
++          addr >= thread->stack_base() - thread->stack_size()) {
++        // stack overflow
++        if (thread->in_stack_yellow_zone(addr)) {
++          thread->disable_stack_yellow_zone();
++          if (thread->thread_state() == _thread_in_Java) {
++            // Throw a stack overflow exception.  Guard pages will be reenabled
++            // while unwinding the stack.
++            stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
++          } else {
++            // Thread was in the vm or native code.  Return and try to finish.
++            return 1;
++          }
++        } else if (thread->in_stack_red_zone(addr)) {
++          // Fatal red zone violation.  Disable the guard pages and fall through
++          // to handle_unexpected_exception way down below.
++          thread->disable_stack_red_zone();
++          tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
++
++          // This is a likely cause, but hard to verify. Let's just print
++          // it as a hint.
++          tty->print_raw_cr("Please check if any of your loaded .so files has "
++                            "enabled executable stack (see man page execstack(8))");
++        } else {
++          // Accessing stack address below sp may cause SEGV if current
++          // thread has MAP_GROWSDOWN stack. This should only happen when
++          // current thread was created by user code with MAP_GROWSDOWN flag
++          // and then attached to VM. See notes in os_linux.cpp.
++          if (thread->osthread()->expanding_stack() == 0) {
++             thread->osthread()->set_expanding_stack();
++             if (os::Linux::manually_expand_stack(thread, addr)) {
++               thread->osthread()->clear_expanding_stack();
++               return 1;
++             }
++             thread->osthread()->clear_expanding_stack();
++          } else {
++             fatal("recursive segv. expanding stack.");
++          }
++        }
++      }
++    }
++
++    if (thread->thread_state() == _thread_in_Java) {
++      // Java thread running in Java code => find exception handler if any
++      // a fault inside compiled code, the interpreter, or a stub
++
++      // Handle signal from NativeJump::patch_verified_entry().
++      if ((sig == SIGILL || sig == SIGTRAP)
++          && nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) {
++        if (TraceTraps) {
++          tty->print_cr("trap: zombie_not_entrant (%s)", (sig == SIGTRAP) ? "SIGTRAP" : "SIGILL");
++        }
++        stub = SharedRuntime::get_handle_wrong_method_stub();
++      } else if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
++        stub = SharedRuntime::get_poll_stub(pc);
++      } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
++        // BugId 4454115: A read from a MappedByteBuffer can fault
++        // here if the underlying file has been truncated.
++        // Do not crash the VM in such a case.
++        CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
++        nmethod* nm = (cb != NULL && cb->is_nmethod()) ? (nmethod*)cb : NULL;
++        if (nm != NULL && nm->has_unsafe_access()) {
++          stub = handle_unsafe_access(thread, pc);
++        }
++      }
++      else
++
++      if (sig == SIGFPE  &&
++          (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) {
++        stub =
++          SharedRuntime::
++          continuation_for_implicit_exception(thread,
++                                              pc,
++                                              SharedRuntime::
++                                              IMPLICIT_DIVIDE_BY_ZERO);
++      } else if (sig == SIGSEGV &&
++               !MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) {
++          // Determination of interpreter/vtable stub/compiled code null exception
++          stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
++      }
++    } else if (thread->thread_state() == _thread_in_vm &&
++               sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
++               thread->doing_unsafe_access()) {
++        stub = handle_unsafe_access(thread, pc);
++    }
++
++    // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in
++    // and the heap gets shrunk before the field access.
++    if ((sig == SIGSEGV) || (sig == SIGBUS)) {
++      address addr = JNI_FastGetField::find_slowcase_pc(pc);
++      if (addr != (address)-1) {
++        stub = addr;
++      }
++    }
++
++    // Check to see if we caught the safepoint code in the
++    // process of write protecting the memory serialization page.
++    // It write enables the page immediately after protecting it
++    // so we can just return to retry the write.
++    if ((sig == SIGSEGV) &&
++        os::is_memory_serialize_page(thread, (address) info->si_addr)) {
++      // Block current thread until the memory serialize page permission restored.
++      os::block_on_serialize_page_trap();
++      return true;
++    }
++  }
++
++  if (stub != NULL) {
++    // save all thread context in case we need to restore it
++    if (thread != NULL) thread->set_saved_exception_pc(pc);
++
++    uc->uc_mcontext.pc = (__u64)stub;
++    return true;
++  }
++
++  // signal-chaining
++  if (os::Linux::chained_handler(sig, info, ucVoid)) {
++     return true;
++  }
++
++  if (!abort_if_unrecognized) {
++    // caller wants another chance, so give it to him
++    return false;
++  }
++
++  if (pc == NULL && uc != NULL) {
++    pc = os::Linux::ucontext_get_pc(uc);
++  }
++
++  // unmask current signal
++  sigset_t newset;
++  sigemptyset(&newset);
++  sigaddset(&newset, sig);
++  sigprocmask(SIG_UNBLOCK, &newset, NULL);
++
++  VMError err(t, sig, pc, info, ucVoid);
++  err.report_and_die();
++
++  ShouldNotReachHere();
++  return true; // Mute compiler
++}
++
++void os::Linux::init_thread_fpu_state(void) {
++}
++
++int os::Linux::get_fpu_control_word(void) {
++  return 0;
++}
++
++void os::Linux::set_fpu_control_word(int fpu_control) {
++}
++
++// Check that the linux kernel version is 2.4 or higher since earlier
++// versions do not support SSE without patches.
++bool os::supports_sse() {
++  return true;
++}
++
++bool os::is_allocatable(size_t bytes) {
++  return true;
++}
++
++////////////////////////////////////////////////////////////////////////////////
++// thread stack
++
++size_t os::Linux::min_stack_allowed  = 64 * K;
++
++// amd64: pthread on amd64 is always in floating stack mode
++bool os::Linux::supports_variable_stack_size() {  return true; }
++
++// return default stack size for thr_type
++size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
++  // default stack size (compiler thread needs larger stack)
++  size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
++  return s;
++}
++
++size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
++  // Creating guard page is very expensive. Java thread has HotSpot
++  // guard page, only enable glibc guard page for non-Java threads.
++  return (thr_type == java_thread ? 0 : page_size());
++}
++
++// Java thread:
++//
++//   Low memory addresses
++//    +------------------------+
++//    |                        |\  JavaThread created by VM does not have glibc
++//    |    glibc guard page    | - guard, attached Java thread usually has
++//    |                        |/  1 page glibc guard.
++// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
++//    |                        |\
++//    |  HotSpot Guard Pages   | - red and yellow pages
++//    |                        |/
++//    +------------------------+ JavaThread::stack_yellow_zone_base()
++//    |                        |\
++//    |      Normal Stack      | -
++//    |                        |/
++// P2 +------------------------+ Thread::stack_base()
++//
++// Non-Java thread:
++//
++//   Low memory addresses
++//    +------------------------+
++//    |                        |\
++//    |  glibc guard page      | - usually 1 page
++//    |                        |/
++// P1 +------------------------+ Thread::stack_base() - Thread::stack_size()
++//    |                        |\
++//    |      Normal Stack      | -
++//    |                        |/
++// P2 +------------------------+ Thread::stack_base()
++//
++// ** P1 (aka bottom) and size ( P2 = P1 - size) are the address and stack size returned from
++//    pthread_attr_getstack()
++
++static void current_stack_region(address * bottom, size_t * size) {
++  if (os::is_primordial_thread()) {
++     // primordial thread needs special handling because pthread_getattr_np()
++     // may return bogus value.
++     *bottom = os::Linux::initial_thread_stack_bottom();
++     *size   = os::Linux::initial_thread_stack_size();
++  } else {
++     pthread_attr_t attr;
++
++     int rslt = pthread_getattr_np(pthread_self(), &attr);
++
++     // JVM needs to know exact stack location, abort if it fails
++     if (rslt != 0) {
++       if (rslt == ENOMEM) {
++         vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
++       } else {
++         fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
++       }
++     }
++
++     if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
++         fatal("Can not locate current stack attributes!");
++     }
++
++     pthread_attr_destroy(&attr);
++
++  }
++  assert(os::current_stack_pointer() >= *bottom &&
++         os::current_stack_pointer() < *bottom + *size, "just checking");
++}
++
++address os::current_stack_base() {
++  address bottom;
++  size_t size;
++  current_stack_region(&bottom, &size);
++  return (bottom + size);
++}
++
++size_t os::current_stack_size() {
++  // stack size includes normal stack and HotSpot guard pages
++  address bottom;
++  size_t size;
++  current_stack_region(&bottom, &size);
++  return size;
++}
++
++/////////////////////////////////////////////////////////////////////////////
++// helper functions for fatal error handler
++
++void os::print_context(outputStream *st, void *context) {
++  if (context == NULL) return;
++
++  ucontext_t *uc = (ucontext_t*)context;
++  st->print_cr("Registers:");
++  for (int r = 0; r < 31; r++)
++          st->print_cr(  "R%d=" INTPTR_FORMAT, r, (int64_t)uc->uc_mcontext.regs[r]);
++  st->cr();
++
++  intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
++  st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
++  print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
++  st->cr();
++
++  // Note: it may be unsafe to inspect memory near pc. For example, pc may
++  // point to garbage if entry point in an nmethod is corrupted. Leave
++  // this at the end, and hope for the best.
++  address pc = os::Linux::ucontext_get_pc(uc);
++  st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
++  print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
++}
++
++void os::print_register_info(outputStream *st, void *context) {
++  if (context == NULL) return;
++
++  ucontext_t *uc = (ucontext_t*)context;
++
++  st->print_cr("Register to memory mapping:");
++  st->cr();
++
++  // this is horrendously verbose but the layout of the registers in the
++  // context does not match how we defined our abstract Register set, so
++  // we can't just iterate through the gregs area
++
++  // this is only for the "general purpose" registers
++
++  for (int r = 0; r < 31; r++)
++          st->print_cr(  "R%d=" INTPTR_FORMAT, r, (int64_t)uc->uc_mcontext.regs[r]);
++  st->cr();
++}
++
++void os::setup_fpu() {
++}
++
++#ifndef PRODUCT
++void os::verify_stack_alignment() {
++  assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
++}
++#endif
++
++extern "C" {
++  int SpinPause() {
++    return 0;
++  }
++
++  void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
++    if (from > to) {
++      const jshort *end = from + count;
++      while (from < end)
++        *(to++) = *(from++);
++    }
++    else if (from < to) {
++      const jshort *end = from;
++      from += count - 1;
++      to   += count - 1;
++      while (from >= end)
++        *(to--) = *(from--);
++    }
++  }
++  void _Copy_conjoint_jints_atomic(jint* from, jint* to, size_t count) {
++    if (from > to) {
++      const jint *end = from + count;
++      while (from < end)
++        *(to++) = *(from++);
++    }
++    else if (from < to) {
++      const jint *end = from;
++      from += count - 1;
++      to   += count - 1;
++      while (from >= end)
++        *(to--) = *(from--);
++    }
++  }
++  void _Copy_conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) {
++    if (from > to) {
++      const jlong *end = from + count;
++      while (from < end)
++        os::atomic_copy64(from++, to++);
++    }
++    else if (from < to) {
++      const jlong *end = from;
++      from += count - 1;
++      to   += count - 1;
++      while (from >= end)
++        os::atomic_copy64(from--, to--);
++    }
++  }
++
++  void _Copy_arrayof_conjoint_bytes(HeapWord* from,
++                                    HeapWord* to,
++                                    size_t    count) {
++    memmove(to, from, count);
++  }
++  void _Copy_arrayof_conjoint_jshorts(HeapWord* from,
++                                      HeapWord* to,
++                                      size_t    count) {
++    memmove(to, from, count * 2);
++  }
++  void _Copy_arrayof_conjoint_jints(HeapWord* from,
++                                    HeapWord* to,
++                                    size_t    count) {
++    memmove(to, from, count * 4);
++  }
++  void _Copy_arrayof_conjoint_jlongs(HeapWord* from,
++                                     HeapWord* to,
++                                     size_t    count) {
++    memmove(to, from, count * 8);
++  }
++};
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp
+new file mode 100644
+index 0000000000..b576b846ed
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp
+@@ -0,0 +1,58 @@
++/*
++ * Copyright (c) 1999, 2011, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_HPP
++#define OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_HPP
++
++  static void setup_fpu();
++  static bool supports_sse();
++
++  static jlong rdtsc();
++
++  static bool is_allocatable(size_t bytes);
++
++  // Used to register dynamic code cache area with the OS
++  // Note: Currently only used in 64 bit Windows implementations
++  static bool register_code_area(char *low, char *high) { return true; }
++
++  // Atomically copy 64 bits of data
++  static void atomic_copy64(volatile void *src, volatile void *dst) {
++#if defined(PPC) && !defined(_LP64)
++    double tmp;
++    asm volatile ("lfd  %0, 0(%1)\n"
++                  "stfd %0, 0(%2)\n"
++                  : "=f"(tmp)
++                  : "b"(src), "b"(dst));
++#elif defined(S390) && !defined(_LP64)
++    double tmp;
++    asm volatile ("ld  %0, 0(%1)\n"
++                  "std %0, 0(%2)\n"
++                  : "=r"(tmp)
++                  : "a"(src), "a"(dst));
++#else
++    *(jlong *) dst = *(jlong *) src;
++#endif
++  }
++
++#endif // OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp
+new file mode 100644
+index 0000000000..c22c351697
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp
+@@ -0,0 +1,39 @@
++/*
++ * Copyright (c) 2011, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_INLINE_HPP
++#define OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_INLINE_HPP
++
++#include "runtime/os.hpp"
++
++// See http://www.technovelty.org/code/c/reading-rdtsc.htl for details
++inline jlong os::rdtsc() {
++  uint64_t res;
++  uint32_t ts1, ts2;
++  __asm__ __volatile__ ("rdtsc" : "=a" (ts1), "=d" (ts2));
++  res = ((uint64_t)ts1 | (uint64_t)ts2 << 32);
++  return (jlong)res;
++}
++
++#endif // OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp
+new file mode 100644
+index 0000000000..374cf9fd8b
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 2003, 2010, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_PREFETCH_LINUX_AARCH64_INLINE_HPP
++#define OS_CPU_LINUX_AARCH64_VM_PREFETCH_LINUX_AARCH64_INLINE_HPP
++
++#include "runtime/prefetch.hpp"
++
++
++inline void Prefetch::read (void *loc, intx interval) {
++  if (interval >= 0)
++    asm("prfm PLDL1KEEP, [%0, %1]" : : "r"(loc), "r"(interval));
++}
++
++inline void Prefetch::write(void *loc, intx interval) {
++  if (interval >= 0)
++    asm("prfm PSTL1KEEP, [%0, %1]" : : "r"(loc), "r"(interval));
++}
++
++#endif // OS_CPU_LINUX_AARCH64_VM_PREFETCH_LINUX_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.cpp
+new file mode 100644
+index 0000000000..5256d42c3d
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.cpp
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (c) 1999, 2010, 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 "runtime/threadLocalStorage.hpp"
++#include "runtime/thread.inline.hpp"
++
++void ThreadLocalStorage::generate_code_for_get_thread() {
++    // nothing we can do here for user-level thread
++}
++
++void ThreadLocalStorage::pd_init() {
++}
++
++__thread Thread *aarch64_currentThread;
++
++void ThreadLocalStorage::pd_set_thread(Thread* thread) {
++  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
++  aarch64_currentThread = thread;
++}
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp
+new file mode 100644
+index 0000000000..3e79b6dc58
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp
+@@ -0,0 +1,36 @@
++/*
++ * Copyright (c) 1999, 2010, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
++#define OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
++
++  // Processor dependent parts of ThreadLocalStorage
++
++public:
++
++  static Thread *thread() {
++    return aarch64_currentThread;
++  }
++
++#endif // OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp
+new file mode 100644
+index 0000000000..87e42318a6
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp
+@@ -0,0 +1,92 @@
++/*
++ * Copyright (c) 2003, 2010, 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 "runtime/frame.inline.hpp"
++#include "runtime/thread.inline.hpp"
++
++// For Forte Analyzer AsyncGetCallTrace profiling support - thread is
++// currently interrupted by SIGPROF
++bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr,
++  void* ucontext, bool isInJava) {
++
++  assert(Thread::current() == this, "caller must be current thread");
++  return pd_get_top_frame(fr_addr, ucontext, isInJava);
++}
++
++bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
++  return pd_get_top_frame(fr_addr, ucontext, isInJava);
++}
++
++bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
++  assert(this->is_Java_thread(), "must be JavaThread");
++  JavaThread* jt = (JavaThread *)this;
++
++  // If we have a last_Java_frame, then we should use it even if
++  // isInJava == true.  It should be more reliable than ucontext info.
++  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
++    *fr_addr = jt->pd_last_frame();
++    return true;
++  }
++
++  // At this point, we don't have a last_Java_frame, so
++  // we try to glean some information out of the ucontext
++  // if we were running Java code when SIGPROF came in.
++  if (isInJava) {
++    ucontext_t* uc = (ucontext_t*) ucontext;
++
++    intptr_t* ret_fp;
++    intptr_t* ret_sp;
++    ExtendedPC addr = os::Linux::fetch_frame_from_ucontext(this, uc,
++      &ret_sp, &ret_fp);
++    if (addr.pc() == NULL || ret_sp == NULL ) {
++      // ucontext wasn't useful
++      return false;
++    }
++
++    frame ret_frame(ret_sp, ret_fp, addr.pc());
++    if (!ret_frame.safe_for_sender(jt)) {
++#ifdef COMPILER2
++      // C2 uses ebp as a general register see if NULL fp helps
++      frame ret_frame2(ret_sp, NULL, addr.pc());
++      if (!ret_frame2.safe_for_sender(jt)) {
++        // nothing else to try if the frame isn't good
++        return false;
++      }
++      ret_frame = ret_frame2;
++#else
++      // nothing else to try if the frame isn't good
++      return false;
++#endif /* COMPILER2 */
++    }
++    *fr_addr = ret_frame;
++    return true;
++  }
++
++  // nothing else to try
++  return false;
++}
++
++void JavaThread::cache_global_variables() { }
++
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp
+new file mode 100644
+index 0000000000..a2f0135c2d
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (c) 2000, 2010, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_THREAD_LINUX_AARCH64_HPP
++#define OS_CPU_LINUX_AARCH64_VM_THREAD_LINUX_AARCH64_HPP
++
++ private:
++#ifdef ASSERT
++  // spill stack holds N callee-save registers at each Java call and
++  // grows downwards towards limit
++  // we need limit to check we have space for a spill and base so we
++  // can identify all live spill frames at GC (eventually)
++  address          _spill_stack;
++  address          _spill_stack_base;
++  address          _spill_stack_limit;
++#endif // ASSERT
++
++  void pd_initialize() {
++    _anchor.clear();
++  }
++
++  frame pd_last_frame() {
++    assert(has_last_Java_frame(), "must have last_Java_sp() when suspended");
++    return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc());
++  }
++
++ public:
++  // Mutators are highly dangerous....
++  intptr_t* last_Java_fp()                       { return _anchor.last_Java_fp(); }
++  void  set_last_Java_fp(intptr_t* fp)           { _anchor.set_last_Java_fp(fp);   }
++
++  void set_base_of_stack_pointer(intptr_t* base_sp) {
++  }
++
++  static ByteSize last_Java_fp_offset()          {
++    return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset();
++  }
++
++  intptr_t* base_of_stack_pointer() {
++    return NULL;
++  }
++  void record_base_of_stack_pointer() {
++  }
++
++  bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
++    bool isInJava);
++
++  bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava);
++private:
++  bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
++public:
++
++  // These routines are only used on cpu architectures that
++  // have separate register stacks (Itanium).
++  static bool register_stack_overflow() { return false; }
++  static void enable_register_stack_guard() {}
++  static void disable_register_stack_guard() {}
++
++#endif // OS_CPU_LINUX_AARCH64_VM_THREAD_LINUX_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
+new file mode 100644
+index 0000000000..6d482b259e
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (c) 2000, 2012, 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.
++ *
++ */
++
++#ifndef OS_CPU_LINUX_AARCH64_VM_VMSTRUCTS_LINUX_AARCH64_HPP
++#define OS_CPU_LINUX_AARCH64_VM_VMSTRUCTS_LINUX_AARCH64_HPP
++
++// These are the OS and CPU-specific fields, types and integer
++// constants required by the Serviceability Agent. This file is
++// referenced by vmStructs.cpp.
++
++#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
++                                                                                                                                     \
++  /******************************/                                                                                                   \
++  /* Threads (NOTE: incomplete) */                                                                                                   \
++  /******************************/                                                                                                   \
++  nonstatic_field(OSThread,                      _thread_id,                                      OSThread::thread_id_t)             \
++  nonstatic_field(OSThread,                      _pthread_id,                                     pthread_t)
++
++
++#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
++                                                                          \
++  /**********************/                                                \
++  /* Posix Thread IDs   */                                                \
++  /**********************/                                                \
++                                                                          \
++  declare_integer_type(OSThread::thread_id_t)                             \
++  declare_unsigned_integer_type(pthread_t)
++
++#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
++
++#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
++
++#endif // OS_CPU_LINUX_AARCH64_VM_VMSTRUCTS_LINUX_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
+new file mode 100644
+index 0000000000..e9a0c606f3
+--- /dev/null
++++ hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
+@@ -0,0 +1,28 @@
++/*
++ * Copyright (c) 2006, 2010, 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 "runtime/os.hpp"
++#include "vm_version_aarch64.hpp"
++
+-- 
+2.31.1
+
+
+From dd2c51534c8f0af8d7a7ecd29fa91df934e83e07 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:03:38 +0200
+Subject: [PATCH 02/18] Mechanically convert linux -> bsd
+
+for file in $(ls hotspot/src/os_cpu/bsd_aarch64/vm/*) \
+  hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java \
+  hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
+do
+  sed -i '' 's/linux/bsd/g' ${file}
+  sed -i '' 's/Linux/Bsd/g' ${file}
+  sed -i '' 's/LINUX/BSD/g' ${file}
+done
+---
+ .../bsd/aarch64/BsdAARCH64CFrame.java         | 12 ++--
+ .../bsd/aarch64/BsdAARCH64ThreadContext.java  | 10 +--
+ .../BsdAARCH64JavaThreadPDAccess.java         |  4 +-
+ .../vm/atomic_bsd_aarch64.inline.hpp          |  6 +-
+ .../src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad  |  2 +-
+ .../vm/bytes_bsd_aarch64.inline.hpp           |  6 +-
+ .../vm/copy_bsd_aarch64.inline.hpp            |  6 +-
+ .../bsd_aarch64/vm/globals_bsd_aarch64.hpp    |  6 +-
+ .../vm/orderAccess_bsd_aarch64.inline.hpp     |  6 +-
+ .../os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp  | 66 +++++++++----------
+ .../os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp  |  6 +-
+ .../bsd_aarch64/vm/os_bsd_aarch64.inline.hpp  |  6 +-
+ .../vm/prefetch_bsd_aarch64.inline.hpp        |  6 +-
+ .../bsd_aarch64/vm/threadLS_bsd_aarch64.hpp   |  6 +-
+ .../bsd_aarch64/vm/thread_bsd_aarch64.cpp     |  2 +-
+ .../bsd_aarch64/vm/thread_bsd_aarch64.hpp     |  6 +-
+ .../bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp  |  6 +-
+ 17 files changed, 81 insertions(+), 81 deletions(-)
+
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
+index 28e36759a5..1f1df50726 100644
+--- hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64CFrame.java
+@@ -23,16 +23,16 @@
+  *
+  */
+ 
+-package sun.jvm.hotspot.debugger.linux.aarch64;
++package sun.jvm.hotspot.debugger.bsd.aarch64;
+ 
+ import sun.jvm.hotspot.debugger.*;
+ import sun.jvm.hotspot.debugger.aarch64.*;
+-import sun.jvm.hotspot.debugger.linux.*;
++import sun.jvm.hotspot.debugger.bsd.*;
+ import sun.jvm.hotspot.debugger.cdbg.*;
+ import sun.jvm.hotspot.debugger.cdbg.basic.*;
+ 
+-final public class LinuxAARCH64CFrame extends BasicCFrame {
+-   public LinuxAARCH64CFrame(LinuxDebugger dbg, Address fp, Address pc) {
++final public class BsdAARCH64CFrame extends BasicCFrame {
++   public BsdAARCH64CFrame(BsdDebugger dbg, Address fp, Address pc) {
+       super(dbg.getCDebugger());
+       this.fp = fp;
+       this.pc = pc;
+@@ -74,7 +74,7 @@ final public class LinuxAARCH64CFrame extends BasicCFrame {
+       if (nextPC == null) {
+         return null;
+       }
+-      return new LinuxAARCH64CFrame(dbg, nextFP, nextPC);
++      return new BsdAARCH64CFrame(dbg, nextFP, nextPC);
+    }
+ 
+    // package/class internals only
+@@ -82,5 +82,5 @@ final public class LinuxAARCH64CFrame extends BasicCFrame {
+    private Address pc;
+    private Address sp;
+    private Address fp;
+-   private LinuxDebugger dbg;
++   private BsdDebugger dbg;
+ }
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
+index 7700316867..49d09bcfe0 100644
+--- hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/aarch64/BsdAARCH64ThreadContext.java
+@@ -23,16 +23,16 @@
+  *
+  */
+ 
+-package sun.jvm.hotspot.debugger.linux.aarch64;
++package sun.jvm.hotspot.debugger.bsd.aarch64;
+ 
+ import sun.jvm.hotspot.debugger.*;
+ import sun.jvm.hotspot.debugger.aarch64.*;
+-import sun.jvm.hotspot.debugger.linux.*;
++import sun.jvm.hotspot.debugger.bsd.*;
+ 
+-public class LinuxAARCH64ThreadContext extends AARCH64ThreadContext {
+-  private LinuxDebugger debugger;
++public class BsdAARCH64ThreadContext extends AARCH64ThreadContext {
++  private BsdDebugger debugger;
+ 
+-  public LinuxAARCH64ThreadContext(LinuxDebugger debugger) {
++  public BsdAARCH64ThreadContext(BsdDebugger debugger) {
+     super();
+     this.debugger = debugger;
+   }
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+index bf40afe005..4f84e1576d 100644
+--- hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+@@ -23,7 +23,7 @@
+  *
+  */
+ 
+-package sun.jvm.hotspot.runtime.linux_aarch64;
++package sun.jvm.hotspot.runtime.bsd_aarch64;
+ 
+ import java.io.*;
+ import java.util.*;
+@@ -34,7 +34,7 @@ import sun.jvm.hotspot.runtime.aarch64.*;
+ import sun.jvm.hotspot.types.*;
+ import sun.jvm.hotspot.utilities.*;
+ 
+-public class LinuxAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
++public class BsdAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
+   private static AddressField  lastJavaFPField;
+   private static AddressField  osThreadField;
+ 
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp
+index fba64e15f8..7d29915558 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/atomic_bsd_aarch64.inline.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_ATOMIC_BSD_AARCH64_INLINE_HPP
++#define OS_CPU_BSD_AARCH64_VM_ATOMIC_BSD_AARCH64_INLINE_HPP
+ 
+ #include "runtime/atomic.hpp"
+ #include "runtime/os.hpp"
+@@ -140,4 +140,4 @@ inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void
+ 
+ inline jlong Atomic::load(volatile jlong* src) { return *src; }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_ATOMIC_LINUX_AARCH64_INLINE_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_ATOMIC_BSD_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad b/hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad
+index a71f7d16c1..ecc3e2e2fc 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad
++++ hotspot/src/os_cpu/bsd_aarch64/vm/bsd_aarch64.ad
+@@ -22,7 +22,7 @@
+ //
+ //
+ 
+-// AMD64 Linux Architecture Description File
++// AMD64 Bsd Architecture Description File
+ 
+ //----------OS-DEPENDENT ENCODING BLOCK----------------------------------------
+ // This block specifies the encoding classes used by the compiler to
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
+index beb33f8afd..8e38f8d810 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_BYTES_LINUX_AARCH64_INLINE_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_BYTES_LINUX_AARCH64_INLINE_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP
++#define OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP
+ 
+ #include <byteswap.h>
+ 
+@@ -41,4 +41,4 @@ inline u8 Bytes::swap_u8(u8 x) {
+   return bswap_64(x);
+ }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_BYTES_LINUX_AARCH64_INLINE_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp
+index c47e866f0a..4a6bc5edfd 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.inline.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_COPY_LINUX_AARCH64_INLINE_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_COPY_LINUX_AARCH64_INLINE_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_COPY_BSD_AARCH64_INLINE_HPP
++#define OS_CPU_BSD_AARCH64_VM_COPY_BSD_AARCH64_INLINE_HPP
+ 
+ #define COPY_SMALL(from, to, count)                                     \
+ {                                                                       \
+@@ -245,4 +245,4 @@ static void pd_arrayof_conjoint_oops(HeapWord* from, HeapWord* to, size_t count)
+   _Copy_arrayof_conjoint_jlongs(from, to, count);
+ }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_COPY_LINUX_AARCH64_INLINE_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_COPY_BSD_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp
+index 2733b47278..8258f4b18b 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/globals_bsd_aarch64.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_GLOBALS_LINUX_AARCH64_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_GLOBALS_LINUX_AARCH64_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_GLOBALS_BSD_AARCH64_HPP
++#define OS_CPU_BSD_AARCH64_VM_GLOBALS_BSD_AARCH64_HPP
+ 
+ // Sets the default values for platform dependent flags used by the runtime system.
+ // (see globals.hpp)
+@@ -41,4 +41,4 @@ define_pd_global(uintx,HeapBaseMinAddress,       2*G);
+ 
+ extern __thread Thread *aarch64_currentThread;
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_GLOBALS_LINUX_AARCH64_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_GLOBALS_BSD_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp
+index c54c0469fa..cafce47cbe 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/orderAccess_bsd_aarch64.inline.hpp
+@@ -23,8 +23,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_ORDERACCESS_BSD_AARCH64_INLINE_HPP
++#define OS_CPU_BSD_AARCH64_VM_ORDERACCESS_BSD_AARCH64_INLINE_HPP
+ 
+ #include "runtime/atomic.inline.hpp"
+ #include "runtime/orderAccess.hpp"
+@@ -141,4 +141,4 @@ inline void     OrderAccess::release_store_fence(volatile jdouble* p, jdouble v)
+ inline void     OrderAccess::release_store_ptr_fence(volatile intptr_t* p, intptr_t v) { release_store_ptr(p, v); fence(); }
+ inline void     OrderAccess::release_store_ptr_fence(volatile void*     p, void*    v) { release_store_ptr(p, v); fence(); }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_ORDERACCESS_LINUX_AARCH64_INLINE_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_ORDERACCESS_BSD_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
+index 82e36d27f8..a0bd1e9a20 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
+@@ -30,10 +30,10 @@
+ #include "code/icBuffer.hpp"
+ #include "code/vtableStubs.hpp"
+ #include "interpreter/interpreter.hpp"
+-#include "jvm_linux.h"
++#include "jvm_bsd.h"
+ #include "memory/allocation.inline.hpp"
+-#include "mutex_linux.inline.hpp"
+-#include "os_share_linux.hpp"
++#include "mutex_bsd.inline.hpp"
++#include "os_share_bsd.hpp"
+ #include "prims/jniFastGetField.hpp"
+ #include "prims/jvm.h"
+ #include "prims/jvm_misc.hpp"
+@@ -93,24 +93,24 @@ char* os::non_memory_address_word() {
+ void os::initialize_thread(Thread *thr) {
+ }
+ 
+-address os::Linux::ucontext_get_pc(ucontext_t * uc) {
++address os::Bsd::ucontext_get_pc(ucontext_t * uc) {
+   return (address)uc->uc_mcontext.pc;
+ }
+ 
+-intptr_t* os::Linux::ucontext_get_sp(ucontext_t * uc) {
++intptr_t* os::Bsd::ucontext_get_sp(ucontext_t * uc) {
+   return (intptr_t*)uc->uc_mcontext.sp;
+ }
+ 
+-intptr_t* os::Linux::ucontext_get_fp(ucontext_t * uc) {
++intptr_t* os::Bsd::ucontext_get_fp(ucontext_t * uc) {
+   return (intptr_t*)uc->uc_mcontext.regs[REG_FP];
+ }
+ 
+ // For Forte Analyzer AsyncGetCallTrace profiling support - thread
+ // is currently interrupted by SIGPROF.
+ // os::Solaris::fetch_frame_from_ucontext() tries to skip nested signal
+-// frames. Currently we don't do that on Linux, so it's the same as
++// frames. Currently we don't do that on Bsd, so it's the same as
+ // os::fetch_frame_from_context().
+-ExtendedPC os::Linux::fetch_frame_from_ucontext(Thread* thread,
++ExtendedPC os::Bsd::fetch_frame_from_ucontext(Thread* thread,
+   ucontext_t* uc, intptr_t** ret_sp, intptr_t** ret_fp) {
+ 
+   assert(thread != NULL, "just checking");
+@@ -127,9 +127,9 @@ ExtendedPC os::fetch_frame_from_context(void* ucVoid,
+   ucontext_t* uc = (ucontext_t*)ucVoid;
+ 
+   if (uc != NULL) {
+-    epc = ExtendedPC(os::Linux::ucontext_get_pc(uc));
+-    if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc);
+-    if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc);
++    epc = ExtendedPC(os::Bsd::ucontext_get_pc(uc));
++    if (ret_sp) *ret_sp = os::Bsd::ucontext_get_sp(uc);
++    if (ret_fp) *ret_fp = os::Bsd::ucontext_get_fp(uc);
+   } else {
+     // construct empty ExtendedPC for return value checking
+     epc = ExtendedPC(NULL);
+@@ -186,7 +186,7 @@ static address handle_unsafe_access(JavaThread* thread, address pc) {
+ }
+ 
+ extern "C" JNIEXPORT int
+-JVM_handle_linux_signal(int sig,
++JVM_handle_bsd_signal(int sig,
+                         siginfo_t* info,
+                         void* ucVoid,
+                         int abort_if_unrecognized) {
+@@ -203,13 +203,13 @@ JVM_handle_linux_signal(int sig,
+   // Note: it's not uncommon that JNI code uses signal/sigset to install
+   // then restore certain signal handler (e.g. to temporarily block SIGPIPE,
+   // or have a SIGILL handler when detecting CPU type). When that happens,
+-  // JVM_handle_linux_signal() might be invoked with junk info/ucVoid. To
++  // JVM_handle_bsd_signal() might be invoked with junk info/ucVoid. To
+   // avoid unnecessary crash when libjsig is not preloaded, try handle signals
+   // that do not require siginfo/ucontext first.
+ 
+   if (sig == SIGPIPE || sig == SIGXFSZ) {
+     // allow chained handler to go first
+-    if (os::Linux::chained_handler(sig, info, ucVoid)) {
++    if (os::Bsd::chained_handler(sig, info, ucVoid)) {
+       return true;
+     } else {
+       if (PrintMiscellaneous && (WizardMode || Verbose)) {
+@@ -223,7 +223,7 @@ JVM_handle_linux_signal(int sig,
+ 
+   JavaThread* thread = NULL;
+   VMThread* vmthread = NULL;
+-  if (os::Linux::signal_handlers_are_installed) {
++  if (os::Bsd::signal_handlers_are_installed) {
+     if (t != NULL ){
+       if(t->is_Java_thread()) {
+         thread = (JavaThread*)t;
+@@ -234,7 +234,7 @@ JVM_handle_linux_signal(int sig,
+     }
+   }
+ /*
+-  NOTE: does not seem to work on linux.
++  NOTE: does not seem to work on bsd.
+   if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) {
+     // can't decode this kind of signal
+     info = NULL;
+@@ -249,7 +249,7 @@ JVM_handle_linux_signal(int sig,
+ 
+   //%note os_trap_1
+   if (info != NULL && uc != NULL && thread != NULL) {
+-    pc = (address) os::Linux::ucontext_get_pc(uc);
++    pc = (address) os::Bsd::ucontext_get_pc(uc);
+ 
+     if (StubRoutines::is_safefetch_fault(pc)) {
+       uc->uc_mcontext.pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
+@@ -298,10 +298,10 @@ JVM_handle_linux_signal(int sig,
+           // Accessing stack address below sp may cause SEGV if current
+           // thread has MAP_GROWSDOWN stack. This should only happen when
+           // current thread was created by user code with MAP_GROWSDOWN flag
+-          // and then attached to VM. See notes in os_linux.cpp.
++          // and then attached to VM. See notes in os_bsd.cpp.
+           if (thread->osthread()->expanding_stack() == 0) {
+              thread->osthread()->set_expanding_stack();
+-             if (os::Linux::manually_expand_stack(thread, addr)) {
++             if (os::Bsd::manually_expand_stack(thread, addr)) {
+                thread->osthread()->clear_expanding_stack();
+                return 1;
+              }
+@@ -387,7 +387,7 @@ JVM_handle_linux_signal(int sig,
+   }
+ 
+   // signal-chaining
+-  if (os::Linux::chained_handler(sig, info, ucVoid)) {
++  if (os::Bsd::chained_handler(sig, info, ucVoid)) {
+      return true;
+   }
+ 
+@@ -397,7 +397,7 @@ JVM_handle_linux_signal(int sig,
+   }
+ 
+   if (pc == NULL && uc != NULL) {
+-    pc = os::Linux::ucontext_get_pc(uc);
++    pc = os::Bsd::ucontext_get_pc(uc);
+   }
+ 
+   // unmask current signal
+@@ -413,17 +413,17 @@ JVM_handle_linux_signal(int sig,
+   return true; // Mute compiler
+ }
+ 
+-void os::Linux::init_thread_fpu_state(void) {
++void os::Bsd::init_thread_fpu_state(void) {
+ }
+ 
+-int os::Linux::get_fpu_control_word(void) {
++int os::Bsd::get_fpu_control_word(void) {
+   return 0;
+ }
+ 
+-void os::Linux::set_fpu_control_word(int fpu_control) {
++void os::Bsd::set_fpu_control_word(int fpu_control) {
+ }
+ 
+-// Check that the linux kernel version is 2.4 or higher since earlier
++// Check that the bsd kernel version is 2.4 or higher since earlier
+ // versions do not support SSE without patches.
+ bool os::supports_sse() {
+   return true;
+@@ -436,19 +436,19 @@ bool os::is_allocatable(size_t bytes) {
+ ////////////////////////////////////////////////////////////////////////////////
+ // thread stack
+ 
+-size_t os::Linux::min_stack_allowed  = 64 * K;
++size_t os::Bsd::min_stack_allowed  = 64 * K;
+ 
+ // amd64: pthread on amd64 is always in floating stack mode
+-bool os::Linux::supports_variable_stack_size() {  return true; }
++bool os::Bsd::supports_variable_stack_size() {  return true; }
+ 
+ // return default stack size for thr_type
+-size_t os::Linux::default_stack_size(os::ThreadType thr_type) {
++size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
+   // default stack size (compiler thread needs larger stack)
+   size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M);
+   return s;
+ }
+ 
+-size_t os::Linux::default_guard_size(os::ThreadType thr_type) {
++size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
+   // Creating guard page is very expensive. Java thread has HotSpot
+   // guard page, only enable glibc guard page for non-Java threads.
+   return (thr_type == java_thread ? 0 : page_size());
+@@ -491,8 +491,8 @@ static void current_stack_region(address * bottom, size_t * size) {
+   if (os::is_primordial_thread()) {
+      // primordial thread needs special handling because pthread_getattr_np()
+      // may return bogus value.
+-     *bottom = os::Linux::initial_thread_stack_bottom();
+-     *size   = os::Linux::initial_thread_stack_size();
++     *bottom = os::Bsd::initial_thread_stack_bottom();
++     *size   = os::Bsd::initial_thread_stack_size();
+   } else {
+      pthread_attr_t attr;
+ 
+@@ -545,7 +545,7 @@ void os::print_context(outputStream *st, void *context) {
+           st->print_cr(  "R%d=" INTPTR_FORMAT, r, (int64_t)uc->uc_mcontext.regs[r]);
+   st->cr();
+ 
+-  intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
++  intptr_t *sp = (intptr_t *)os::Bsd::ucontext_get_sp(uc);
+   st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
+   print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
+   st->cr();
+@@ -553,7 +553,7 @@ void os::print_context(outputStream *st, void *context) {
+   // Note: it may be unsafe to inspect memory near pc. For example, pc may
+   // point to garbage if entry point in an nmethod is corrupted. Leave
+   // this at the end, and hope for the best.
+-  address pc = os::Linux::ucontext_get_pc(uc);
++  address pc = os::Bsd::ucontext_get_pc(uc);
+   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", p2i(pc));
+   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
+ }
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp
+index b576b846ed..f84ea16c12 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_HPP
++#define OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_HPP
+ 
+   static void setup_fpu();
+   static bool supports_sse();
+@@ -55,4 +55,4 @@
+ #endif
+   }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp
+index c22c351697..6afcb4305e 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.inline.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_INLINE_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_INLINE_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_INLINE_HPP
++#define OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_INLINE_HPP
+ 
+ #include "runtime/os.hpp"
+ 
+@@ -36,4 +36,4 @@ inline jlong os::rdtsc() {
+   return (jlong)res;
+ }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_OS_LINUX_AARCH64_INLINE_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_OS_BSD_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp
+index 374cf9fd8b..2eebe1f847 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/prefetch_bsd_aarch64.inline.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_PREFETCH_LINUX_AARCH64_INLINE_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_PREFETCH_LINUX_AARCH64_INLINE_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_PREFETCH_BSD_AARCH64_INLINE_HPP
++#define OS_CPU_BSD_AARCH64_VM_PREFETCH_BSD_AARCH64_INLINE_HPP
+ 
+ #include "runtime/prefetch.hpp"
+ 
+@@ -38,4 +38,4 @@ inline void Prefetch::write(void *loc, intx interval) {
+     asm("prfm PSTL1KEEP, [%0, %1]" : : "r"(loc), "r"(interval));
+ }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_PREFETCH_LINUX_AARCH64_INLINE_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_PREFETCH_BSD_AARCH64_INLINE_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp
+index 3e79b6dc58..dbaaa665f4 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/threadLS_bsd_aarch64.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_THREADLS_BSD_AARCH64_HPP
++#define OS_CPU_BSD_AARCH64_VM_THREADLS_BSD_AARCH64_HPP
+ 
+   // Processor dependent parts of ThreadLocalStorage
+ 
+@@ -33,4 +33,4 @@ public:
+     return aarch64_currentThread;
+   }
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_THREADLS_LINUX_AARCH64_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_THREADLS_BSD_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp
+index 87e42318a6..b49ed16c34 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.cpp
+@@ -58,7 +58,7 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
+ 
+     intptr_t* ret_fp;
+     intptr_t* ret_sp;
+-    ExtendedPC addr = os::Linux::fetch_frame_from_ucontext(this, uc,
++    ExtendedPC addr = os::Bsd::fetch_frame_from_ucontext(this, uc,
+       &ret_sp, &ret_fp);
+     if (addr.pc() == NULL || ret_sp == NULL ) {
+       // ucontext wasn't useful
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp
+index a2f0135c2d..ca679236a9 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/thread_bsd_aarch64.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_THREAD_LINUX_AARCH64_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_THREAD_LINUX_AARCH64_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_THREAD_BSD_AARCH64_HPP
++#define OS_CPU_BSD_AARCH64_VM_THREAD_BSD_AARCH64_HPP
+ 
+  private:
+ #ifdef ASSERT
+@@ -77,4 +77,4 @@ public:
+   static void enable_register_stack_guard() {}
+   static void disable_register_stack_guard() {}
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_THREAD_LINUX_AARCH64_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_THREAD_BSD_AARCH64_HPP
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
+index 6d482b259e..a0e19ac226 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
+@@ -22,8 +22,8 @@
+  *
+  */
+ 
+-#ifndef OS_CPU_LINUX_AARCH64_VM_VMSTRUCTS_LINUX_AARCH64_HPP
+-#define OS_CPU_LINUX_AARCH64_VM_VMSTRUCTS_LINUX_AARCH64_HPP
++#ifndef OS_CPU_BSD_AARCH64_VM_VMSTRUCTS_BSD_AARCH64_HPP
++#define OS_CPU_BSD_AARCH64_VM_VMSTRUCTS_BSD_AARCH64_HPP
+ 
+ // These are the OS and CPU-specific fields, types and integer
+ // constants required by the Serviceability Agent. This file is
+@@ -51,4 +51,4 @@
+ 
+ #define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+ 
+-#endif // OS_CPU_LINUX_AARCH64_VM_VMSTRUCTS_LINUX_AARCH64_HPP
++#endif // OS_CPU_BSD_AARCH64_VM_VMSTRUCTS_BSD_AARCH64_HPP
+-- 
+2.31.1
+
+
+From 65a52e4fe6d23c58dc0654f299c898630f6e3f91 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Sun, 9 May 2021 11:09:49 +0200
+Subject: [PATCH 03/18] Copy/paste some linux aarch64 makefile
+
+---
+ hotspot/make/bsd/makefiles/aarch64.make | 40 +++++++++++++++++++++++++
+ hotspot/make/bsd/platform_aarch64       | 15 ++++++++++
+ 2 files changed, 55 insertions(+)
+ create mode 100644 hotspot/make/bsd/makefiles/aarch64.make
+ create mode 100644 hotspot/make/bsd/platform_aarch64
+
+diff --git a/hotspot/make/bsd/makefiles/aarch64.make b/hotspot/make/bsd/makefiles/aarch64.make
+new file mode 100644
+index 0000000000..4aa1165475
+--- /dev/null
++++ hotspot/make/bsd/makefiles/aarch64.make
+@@ -0,0 +1,40 @@
++#
++# Copyright (c) 2003, 2010, 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.
++#  
++#
++
++# If FDLIBM_CFLAGS is non-empty it holds CFLAGS needed to be passed to
++# the compiler so as to be able to produce optimized objects
++# without losing precision.
++ifneq ($(FDLIBM_CFLAGS),)
++  OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/SPEED) $(FDLIBM_CFLAGS)
++  OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/SPEED) $(FDLIBM_CFLAGS)
++else
++  OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
++  OPT_CFLAGS/sharedRuntimeTrans.o = $(OPT_CFLAGS/NOOPT)
++endif
++# Must also specify if CPU is little endian
++CFLAGS += -DVM_LITTLE_ENDIAN
++
++# CFLAGS += -D_LP64=1
++
++OPT_CFLAGS/compactingPermGenGen.o = -O1
+diff --git a/hotspot/make/bsd/platform_aarch64 b/hotspot/make/bsd/platform_aarch64
+new file mode 100644
+index 0000000000..f0bbf337c9
+--- /dev/null
++++ hotspot/make/bsd/platform_aarch64
+@@ -0,0 +1,15 @@
++os_family = linux
++
++arch = aarch64
++
++arch_model = aarch64
++
++os_arch = linux_aarch64
++
++os_arch_model = linux_aarch64
++
++lib_arch = aarch64
++
++compiler = gcc
++
++sysdefs = -DLINUX -D_GNU_SOURCE -DAARCH64
+-- 
+2.31.1
+
+
+From ee56dde41fbdb671deab48f50989547ee0d9d61f Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Sun, 9 May 2021 11:12:33 +0200
+Subject: [PATCH 04/18] Mechanically convert linux -> bsd
+
+---
+ hotspot/make/bsd/platform_aarch64 | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/hotspot/make/bsd/platform_aarch64 b/hotspot/make/bsd/platform_aarch64
+index f0bbf337c9..d0301c09aa 100644
+--- hotspot/make/bsd/platform_aarch64
++++ hotspot/make/bsd/platform_aarch64
+@@ -1,15 +1,15 @@
+-os_family = linux
++os_family = bsd
+ 
+ arch = aarch64
+ 
+ arch_model = aarch64
+ 
+-os_arch = linux_aarch64
++os_arch = bsd_aarch64
+ 
+-os_arch_model = linux_aarch64
++os_arch_model = bsd_aarch64
+ 
+ lib_arch = aarch64
+ 
+ compiler = gcc
+ 
+-sysdefs = -DLINUX -D_GNU_SOURCE -DAARCH64
++sysdefs = -D_ALLBSD_SOURCE -D_GNU_SOURCE -DAARCH64
+-- 
+2.31.1
+
+
+From d88ef532116250f0b61da0511d92c1abae29e32f Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:18:40 +0200
+Subject: [PATCH 05/18] Fix byteswap on FreeBSD
+
+---
+ .../os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
+index 8e38f8d810..7b83c4aaf5 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/bytes_bsd_aarch64.inline.hpp
+@@ -25,7 +25,15 @@
+ #ifndef OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP
+ #define OS_CPU_BSD_AARCH64_VM_BYTES_BSD_AARCH64_INLINE_HPP
+ 
+-#include <byteswap.h>
++#if defined(__FreeBSD__)
++#  define bswap_16(x) __bswap16(x)
++#  define bswap_32(x) __bswap32(x)
++#  define bswap_64(x) __bswap64(x)
++#elif defined(__OpenBSD__)
++#  define bswap_16(x) swap16(x)
++#  define bswap_32(x) swap32(x)
++#  define bswap_64(x) swap64(x)
++#endif
+ 
+ // Efficient swapping of data bytes from Java byte
+ // ordering to native byte ordering and vice versa.
+-- 
+2.31.1
+
+
+From 30c386f2b891bde714080ba3d74e2309a6fc41d6 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:21:18 +0200
+Subject: [PATCH 06/18] Fix various build error with clang
+
+---
+ hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp  | 4 ++--
+ hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp | 6 +++---
+ hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp    | 4 ++--
+ hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s  | 2 +-
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp
+index 056fb7b118..e9d7e63fe5 100644
+--- hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp
++++ hotspot/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp
+@@ -309,10 +309,10 @@ class SlowSignatureHandler
+     _from -= Interpreter::stackElementSize;
+ 
+     if (_num_int_args < Argument::n_int_register_parameters_c-1) {
+-      *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
++      *_int_args++ = (*from_addr == 0) ? 0 : (intptr_t)from_addr;
+       _num_int_args++;
+     } else {
+-      *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
++      *_to++ = (*from_addr == 0) ? 0 : (intptr_t) from_addr;
+       _num_int_args++;
+     }
+   }
+diff --git a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
+index 91f1fd6505..8a5f5c4324 100644
+--- hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
++++ hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
+@@ -1435,7 +1435,7 @@ void MacroAssembler::movptr(Register r, uintptr_t imm64) {
+ #ifndef PRODUCT
+   {
+     char buffer[64];
+-    snprintf(buffer, sizeof(buffer), "0x%"PRIX64, imm64);
++    snprintf(buffer, sizeof(buffer), "0x%" PRIX64, imm64);
+     block_comment(buffer);
+   }
+ #endif
+@@ -1498,7 +1498,7 @@ void MacroAssembler::mov_immediate64(Register dst, u_int64_t imm64)
+ #ifndef PRODUCT
+   {
+     char buffer[64];
+-    snprintf(buffer, sizeof(buffer), "0x%"PRIX64, imm64);
++    snprintf(buffer, sizeof(buffer), "0x%" PRIX64, imm64);
+     block_comment(buffer);
+   }
+ #endif
+@@ -1611,7 +1611,7 @@ void MacroAssembler::mov_immediate32(Register dst, u_int32_t imm32)
+ #ifndef PRODUCT
+     {
+       char buffer[64];
+-      snprintf(buffer, sizeof(buffer), "0x%"PRIX32, imm32);
++      snprintf(buffer, sizeof(buffer), "0x%" PRIX32, imm32);
+       block_comment(buffer);
+     }
+ #endif
+diff --git a/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp
+index 59d5b04de1..7a8b3a02d3 100644
+--- hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp
++++ hotspot/src/cpu/aarch64/vm/vtableStubs_aarch64.cpp
+@@ -115,7 +115,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
+   __ flush();
+ 
+   if (PrintMiscellaneous && (WizardMode || Verbose)) {
+-    tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
++    tty->print_cr("vtable #%d at " PTR_FORMAT"[%d] left over: %d",
+                   vtable_index, p2i(s->entry_point()),
+                   (int)(s->code_end() - s->entry_point()),
+                   (int)(s->code_end() - __ pc()));
+@@ -213,7 +213,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
+   __ flush();
+ 
+   if (PrintMiscellaneous && (WizardMode || Verbose)) {
+-    tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
++    tty->print_cr("itable #%d at " PTR_FORMAT"[%d] left over: %d",
+                   itable_index, p2i(s->entry_point()),
+                   (int)(s->code_end() - s->entry_point()),
+                   (int)(s->code_end() - __ pc()));
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s b/hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s
+index 6d00d9f74e..e7f9215c60 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s
++++ hotspot/src/os_cpu/bsd_aarch64/vm/copy_bsd_aarch64.s
+@@ -329,7 +329,7 @@ unal_bwd_copy:
+         blo     unal_bwd_copy_drain
+ 
+ unal_bwd_copy_again:
+-        prfm    pldl1keep, [s, #-256]
++        prfum   pldl1keep, [s, #-256]
+         str     t1, [d, #-8]
+         stp     t3, t0, [d, #-24]
+         ldp     t0, t1, [s, #-16]
+-- 
+2.31.1
+
+
+From 1a7dd4ed66d9b8590efce8eb7b8dbd463b353b63 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:30:23 +0200
+Subject: [PATCH 07/18] Port os_bsd_aarch64.cpp to bsd aarch64
+
+---
+ hotspot/src/os/bsd/vm/os_bsd.hpp              |   1 +
+ .../os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp  | 176 ++++++++++++------
+ 2 files changed, 124 insertions(+), 53 deletions(-)
+
+diff --git a/hotspot/src/os/bsd/vm/os_bsd.hpp b/hotspot/src/os/bsd/vm/os_bsd.hpp
+index f6e230e692..ba5686c544 100644
+--- hotspot/src/os/bsd/vm/os_bsd.hpp
++++ hotspot/src/os/bsd/vm/os_bsd.hpp
+@@ -107,6 +107,7 @@ class Bsd {
+   static address   ucontext_get_pc(ucontext_t* uc);
+   static intptr_t* ucontext_get_sp(ucontext_t* uc);
+   static intptr_t* ucontext_get_fp(ucontext_t* uc);
++  static void      ucontext_set_pc(ucontext_t * uc, address);
+ 
+   // For Analyzer Forte AsyncGetCallTrace profiling support:
+   //
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
+index a0bd1e9a20..d015358f89 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/os_bsd_aarch64.cpp
+@@ -63,7 +63,6 @@
+ # include <stdio.h>
+ # include <unistd.h>
+ # include <sys/resource.h>
+-# include <pthread.h>
+ # include <sys/stat.h>
+ # include <sys/time.h>
+ # include <sys/utsname.h>
+@@ -71,8 +70,18 @@
+ # include <sys/wait.h>
+ # include <pwd.h>
+ # include <poll.h>
++#ifdef __FreeBSD__
+ # include <ucontext.h>
+-# include <fpu_control.h>
++# include <sys/sysctl.h>
++# include <sys/procctl.h>
++# include <pthread_np.h>
++# ifndef PROC_STACKGAP_STATUS
++#  define PROC_STACKGAP_STATUS	18
++# endif
++# ifndef PROC_STACKGAP_DISABLE
++#  define PROC_STACKGAP_DISABLE	0x0002
++# endif
++#endif /* __FreeBSD__ */
+ 
+ #define REG_FP 29
+ 
+@@ -94,15 +103,35 @@ void os::initialize_thread(Thread *thr) {
+ }
+ 
+ address os::Bsd::ucontext_get_pc(ucontext_t * uc) {
+-  return (address)uc->uc_mcontext.pc;
++#if defined(__FreeBSD__)
++  return (address)uc->uc_mcontext.mc_gpregs.gp_elr;
++#elif defined(__OpenBSD__)
++  return (address)uc->sc_elr;
++#endif
++}
++
++void os::Bsd::ucontext_set_pc(ucontext_t * uc, address pc) {
++#if defined(__FreeBSD__)
++  uc->uc_mcontext.mc_gpregs.gp_elr = (intptr_t)pc;
++#elif defined(__OpenBSD__)
++  uc->sc_elr = (unsigned long)pc;
++#endif
+ }
+ 
+ intptr_t* os::Bsd::ucontext_get_sp(ucontext_t * uc) {
+-  return (intptr_t*)uc->uc_mcontext.sp;
++#if defined(__FreeBSD__)
++  return (intptr_t*)uc->uc_mcontext.mc_gpregs.gp_sp;
++#elif defined(__OpenBSD__)
++  return (intptr_t*)uc->sc_sp;
++#endif
+ }
+ 
+ intptr_t* os::Bsd::ucontext_get_fp(ucontext_t * uc) {
+-  return (intptr_t*)uc->uc_mcontext.regs[REG_FP];
++#if defined(__FreeBSD__)
++  return (intptr_t*)uc->uc_mcontext.mc_gpregs.gp_x[REG_FP];
++#elif defined(__OpenBSD__)
++  return (intptr_t*)uc->sc_x[REG_FP];
++#endif
+ }
+ 
+ // For Forte Analyzer AsyncGetCallTrace profiling support - thread
+@@ -252,7 +281,7 @@ JVM_handle_bsd_signal(int sig,
+     pc = (address) os::Bsd::ucontext_get_pc(uc);
+ 
+     if (StubRoutines::is_safefetch_fault(pc)) {
+-      uc->uc_mcontext.pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc));
++      os::Bsd::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
+       return 1;
+     }
+ 
+@@ -269,6 +298,55 @@ JVM_handle_bsd_signal(int sig,
+     // Handle ALL stack overflow variations here
+     if (sig == SIGSEGV) {
+       address addr = (address) info->si_addr;
++#ifdef __FreeBSD__
++      /*
++       * Determine whether the kernel stack guard pages have been disabled
++       */
++      int status = 0;
++      int ret = procctl(P_PID, getpid(), PROC_STACKGAP_STATUS, &status);
++
++      /*
++       * Check if the call to procctl(2) failed or the stack guard is not
++       * disabled.  Either way, we'll then attempt a workaround.
++       */
++      if (ret == -1 || !(status & PROC_STACKGAP_DISABLE)) {
++          /*
++           * Try to work around the problems caused on FreeBSD where the kernel
++           * may place guard pages above JVM guard pages and prevent the Java
++           * thread stacks growing into the JVM guard pages.  The work around
++           * is to determine how many such pages there may be and round down the
++           * fault address so that tests of whether it is in the JVM guard zone
++           * succeed.
++           *
++           * Note that this is a partial workaround at best since the normally
++           * the JVM could then unprotect the reserved area to allow a critical
++           * section to complete.  This is not possible if the kernel has
++           * placed guard pages below the reserved area.
++           *
++           * This also suffers from the problem that the
++           * security.bsd.stack_guard_page sysctl is dynamic and may have
++           * changed since the stack was allocated.  This is likely to be rare
++           * in practice though.
++           *
++           * What this does do is prevent the JVM crashing on FreeBSD and
++           * instead throwing a StackOverflowError when infinite recursion
++           * is attempted, which is the expected behaviour.  Due to it's
++           * limitations though, objects may be in unexpected states when
++           * this occurs.
++           *
++           * A better way to avoid these problems is either to be on a new
++           * enough version of FreeBSD (one that has PROC_STACKGAP_CTL) or set
++           * security.bsd.stack_guard_page to zero.
++           */
++          int guard_pages = 0;
++          size_t size = sizeof(guard_pages);
++          if (sysctlbyname("security.bsd.stack_guard_page",
++                           &guard_pages, &size, NULL, 0) == 0 &&
++              guard_pages > 0) {
++            addr -= guard_pages * os::vm_page_size();
++          }
++      }
++#endif
+ 
+       // check if fault address is within thread stack
+       if (addr < thread->stack_base() &&
+@@ -294,21 +372,6 @@ JVM_handle_bsd_signal(int sig,
+           // it as a hint.
+           tty->print_raw_cr("Please check if any of your loaded .so files has "
+                             "enabled executable stack (see man page execstack(8))");
+-        } else {
+-          // Accessing stack address below sp may cause SEGV if current
+-          // thread has MAP_GROWSDOWN stack. This should only happen when
+-          // current thread was created by user code with MAP_GROWSDOWN flag
+-          // and then attached to VM. See notes in os_bsd.cpp.
+-          if (thread->osthread()->expanding_stack() == 0) {
+-             thread->osthread()->set_expanding_stack();
+-             if (os::Bsd::manually_expand_stack(thread, addr)) {
+-               thread->osthread()->clear_expanding_stack();
+-               return 1;
+-             }
+-             thread->osthread()->clear_expanding_stack();
+-          } else {
+-             fatal("recursive segv. expanding stack.");
+-          }
+         }
+       }
+     }
+@@ -382,7 +445,7 @@ JVM_handle_bsd_signal(int sig,
+     // save all thread context in case we need to restore it
+     if (thread != NULL) thread->set_saved_exception_pc(pc);
+ 
+-    uc->uc_mcontext.pc = (__u64)stub;
++    os::Bsd::ucontext_set_pc(uc, stub);
+     return true;
+   }
+ 
+@@ -416,13 +479,6 @@ JVM_handle_bsd_signal(int sig,
+ void os::Bsd::init_thread_fpu_state(void) {
+ }
+ 
+-int os::Bsd::get_fpu_control_word(void) {
+-  return 0;
+-}
+-
+-void os::Bsd::set_fpu_control_word(int fpu_control) {
+-}
+-
+ // Check that the bsd kernel version is 2.4 or higher since earlier
+ // versions do not support SSE without patches.
+ bool os::supports_sse() {
+@@ -488,32 +544,36 @@ size_t os::Bsd::default_guard_size(os::ThreadType thr_type) {
+ //    pthread_attr_getstack()
+ 
+ static void current_stack_region(address * bottom, size_t * size) {
+-  if (os::is_primordial_thread()) {
+-     // primordial thread needs special handling because pthread_getattr_np()
+-     // may return bogus value.
+-     *bottom = os::Bsd::initial_thread_stack_bottom();
+-     *size   = os::Bsd::initial_thread_stack_size();
+-  } else {
+-     pthread_attr_t attr;
++#if defined(__OpenBSD__)
++  stack_t ss;
++  int rslt = pthread_stackseg_np(pthread_self(), &ss);
++
++  if (rslt != 0)
++    fatal(err_msg("pthread_stackseg_np failed with err = %d", rslt));
+ 
+-     int rslt = pthread_getattr_np(pthread_self(), &attr);
++  *bottom = (address)((char *)ss.ss_sp - ss.ss_size);
++  *size   = ss.ss_size;
++#else
++  pthread_attr_t attr;
+ 
+-     // JVM needs to know exact stack location, abort if it fails
+-     if (rslt != 0) {
+-       if (rslt == ENOMEM) {
+-         vm_exit_out_of_memory(0, OOM_MMAP_ERROR, "pthread_getattr_np");
+-       } else {
+-         fatal(err_msg("pthread_getattr_np failed with errno = %d", rslt));
+-       }
+-     }
++  int rslt = pthread_attr_init(&attr);
+ 
+-     if (pthread_attr_getstack(&attr, (void **)bottom, size) != 0) {
+-         fatal("Can not locate current stack attributes!");
+-     }
++  // JVM needs to know exact stack location, abort if it fails
++  if (rslt != 0)
++    fatal(err_msg("pthread_attr_init failed with err = %d", rslt));
+ 
+-     pthread_attr_destroy(&attr);
++  rslt = pthread_attr_get_np(pthread_self(), &attr);
+ 
++  if (rslt != 0)
++    fatal(err_msg("pthread_attr_get_np failed with err = %d", rslt));
++
++  if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 ||
++    pthread_attr_getstacksize(&attr, size) != 0) {
++    fatal("Can not locate current stack attributes!");
+   }
++
++  pthread_attr_destroy(&attr);
++#endif
+   assert(os::current_stack_pointer() >= *bottom &&
+          os::current_stack_pointer() < *bottom + *size, "just checking");
+ }
+@@ -541,8 +601,14 @@ void os::print_context(outputStream *st, void *context) {
+ 
+   ucontext_t *uc = (ucontext_t*)context;
+   st->print_cr("Registers:");
+-  for (int r = 0; r < 31; r++)
+-          st->print_cr(  "R%d=" INTPTR_FORMAT, r, (int64_t)uc->uc_mcontext.regs[r]);
++  for (int r = 0; r < 30; r++) {
++    st->print("R%-2d=", r);
++#if defined(__FreeBSD__)
++    print_location(st, uc->uc_mcontext.mc_gpregs.gp_x[r]);
++#elif defined(__OpenBSD__)
++    print_location(st, uc->sc_x[r]);
++#endif
++  }
+   st->cr();
+ 
+   intptr_t *sp = (intptr_t *)os::Bsd::ucontext_get_sp(uc);
+@@ -572,8 +638,12 @@ void os::print_register_info(outputStream *st, void *context) {
+ 
+   // this is only for the "general purpose" registers
+ 
+-  for (int r = 0; r < 31; r++)
+-          st->print_cr(  "R%d=" INTPTR_FORMAT, r, (int64_t)uc->uc_mcontext.regs[r]);
++  for (int r = 0; r < 30; r++)
++#if defined(__FreeBSD__)
++    st->print_cr(  "R%d=" INTPTR_FORMAT, r, (uintptr_t)uc->uc_mcontext.mc_gpregs.gp_x[r]);
++#elif defined(__OpenBSD__)
++    st->print_cr(  "R%d=" INTPTR_FORMAT, r, (uintptr_t)uc->sc_x[r]);
++#endif
+   st->cr();
+ }
+ 
+-- 
+2.31.1
+
+
+From ed18c50e7b81d3171682d2259833fd0cb6b2c0c5 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:32:03 +0200
+Subject: [PATCH 08/18] debugger: Add bsd aarch64 support
+
+---
+ hotspot/agent/make/Makefile                   |  3 +++
+ hotspot/agent/src/os/bsd/BsdDebuggerLocal.c   | 20 +++++++++++++++++++
+ hotspot/agent/src/os/bsd/Makefile             |  3 ++-
+ .../hotspot/debugger/bsd/BsdCDebugger.java    |  9 +++++++++
+ .../debugger/bsd/BsdThreadContextFactory.java |  3 +++
+ hotspot/make/bsd/makefiles/sa.make            |  1 +
+ 6 files changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/hotspot/agent/make/Makefile b/hotspot/agent/make/Makefile
+index ea051b0580..de49b9f12e 100644
+--- hotspot/agent/make/Makefile
++++ hotspot/agent/make/Makefile
+@@ -49,6 +49,7 @@ sun.jvm.hotspot.compiler \
+ sun.jvm.hotspot.debugger \
+ sun.jvm.hotspot.debugger.amd64 \
+ sun.jvm.hotspot.debugger.bsd \
++sun.jvm.hotspot.debugger.bsd.aarch64 \
+ sun.jvm.hotspot.debugger.bsd.amd64 \
+ sun.jvm.hotspot.debugger.bsd.ppc64 \
+ sun.jvm.hotspot.debugger.bsd.x86 \
+@@ -65,6 +66,7 @@ sun.jvm.hotspot.debugger.posix \
+ sun.jvm.hotspot.debugger.posix.elf \
+ sun.jvm.hotspot.debugger.ppc64 \
+ sun.jvm.hotspot.debugger.proc \
++sun.jvm.hotspot.debugger.proc.aarch64 \
+ sun.jvm.hotspot.debugger.proc.amd64 \
+ sun.jvm.hotspot.debugger.proc.aarch64 \
+ sun.jvm.hotspot.debugger.proc.ppc64 \
+@@ -144,6 +146,7 @@ sun/jvm/hotspot/compiler/*.java \
+ sun/jvm/hotspot/debugger/*.java \
+ sun/jvm/hotspot/debugger/amd64/*.java \
+ sun/jvm/hotspot/debugger/bsd/*.java \
++sun/jvm/hotspot/debugger/bsd/aarch64/*.java \
+ sun/jvm/hotspot/debugger/bsd/amd64/*.java \
+ sun/jvm/hotspot/debugger/bsd/ppc64/*.java \
+ sun/jvm/hotspot/debugger/bsd/x86/*.java \
+diff --git a/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c b/hotspot/agent/src/os/bsd/BsdDebuggerLocal.c
+index 59886d48c8..a3d020432c 100644
+--- hotspot/agent/src/os/bsd/BsdDebuggerLocal.c
++++ hotspot/agent/src/os/bsd/BsdDebuggerLocal.c
+@@ -42,6 +42,10 @@
+ #include "sun_jvm_hotspot_debugger_sparc_SPARCThreadContext.h"
+ #endif
+ 
++#ifdef aarch64
++#include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h"
++#endif
++
+ #ifdef ppc64
+ #include "sun_jvm_hotspot_debugger_ppc64_PPC64ThreadContext.h"
+ #endif
+@@ -311,6 +315,9 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_
+ #ifdef amd64
+ #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
+ #endif
++#ifdef aarch64
++#define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG
++#endif
+ #if defined(sparc) || defined(sparcv9)
+ #define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
+ #endif
+@@ -456,6 +463,19 @@ JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_
+   regs[REG_INDEX(R31)] = gregs.fixreg[31];
+ 
+ #endif
++
++#if defined(aarch64)
++
++#define REG_INDEX(reg) sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_##reg
++
++  {
++    int i;
++    for (i = 0; i < 31; i++)
++      regs[i] = gregs.x[i];
++    regs[REG_INDEX(SP)] = gregs.sp;
++    regs[REG_INDEX(PC)] = gregs.elr;
++  }
++#endif /* aarch64 */
+  
+ 
+   (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
+diff --git a/hotspot/agent/src/os/bsd/Makefile b/hotspot/agent/src/os/bsd/Makefile
+index 4f85885f4e..0615ebb9f2 100644
+--- hotspot/agent/src/os/bsd/Makefile
++++ hotspot/agent/src/os/bsd/Makefile
+@@ -70,7 +70,8 @@ MacosxDebuggerLocal.o: MacosxDebuggerLocal.m
+ 	echo "OS="$(OS)
+ 	$(JAVAH) -jni -classpath ../../../build/classes  \
+ 		sun.jvm.hotspot.debugger.x86.X86ThreadContext \
+-		sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
++		sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext \
++		sun.jvm.hotspot.debugger.aarch64.AARCH64ThreadContext
+ 	$(GCC) $(CFLAGS) $(FOUNDATIONFLAGS) $<
+ 
+ sadis.o: ../../share/native/sadis.c
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java
+index 37d2eb792a..ceb163fd6a 100644
+--- hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdCDebugger.java
+@@ -29,9 +29,11 @@ import java.util.*;
+ import sun.jvm.hotspot.debugger.*;
+ import sun.jvm.hotspot.debugger.cdbg.*;
+ import sun.jvm.hotspot.debugger.x86.*;
++import sun.jvm.hotspot.debugger.aarch64.*;
+ import sun.jvm.hotspot.debugger.amd64.*;
+ import sun.jvm.hotspot.debugger.ppc64.*;
+ import sun.jvm.hotspot.debugger.bsd.x86.*;
++import sun.jvm.hotspot.debugger.bsd.aarch64.*;
+ import sun.jvm.hotspot.debugger.bsd.amd64.*;
+ import sun.jvm.hotspot.debugger.bsd.ppc64.*;
+ import sun.jvm.hotspot.utilities.*;
+@@ -96,6 +98,13 @@ class BsdCDebugger implements CDebugger {
+         Address pc  = context.getRegisterAsAddress(PPC64ThreadContext.PC);
+         if (pc == null) return null;
+         return new BsdPPC64CFrame(dbg, sp, pc, BsdDebuggerLocal.getAddressSize());
++    } else if (cpu.equals("aarch64")) {
++       AARCH64ThreadContext context = (AARCH64ThreadContext) thread.getContext();
++       Address fp = context.getRegisterAsAddress(AARCH64ThreadContext.FP);
++       if (fp == null) return null;
++       Address pc  = context.getRegisterAsAddress(AARCH64ThreadContext.PC);
++       if (pc == null) return null;
++       return new BsdAARCH64CFrame(dbg, fp, pc);
+     } else {
+        throw new DebuggerException(cpu + " is not yet supported");
+     }
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java
+index fb44a08cfd..06dbc15242 100644
+--- hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdThreadContextFactory.java
+@@ -25,6 +25,7 @@
+ package sun.jvm.hotspot.debugger.bsd;
+ 
+ import sun.jvm.hotspot.debugger.*;
++import sun.jvm.hotspot.debugger.bsd.aarch64.*;
+ import sun.jvm.hotspot.debugger.bsd.amd64.*;
+ import sun.jvm.hotspot.debugger.bsd.x86.*;
+ import sun.jvm.hotspot.debugger.bsd.ppc64.*;
+@@ -38,6 +39,8 @@ class BsdThreadContextFactory {
+          return new BsdAMD64ThreadContext(dbg);
+       }  else if (cpu.equals("ppc64")) {
+           return new BsdPPC64ThreadContext(dbg);
++      } else if (cpu.equals("aarch64")) {
++          return new BsdAARCH64ThreadContext(dbg);
+       } else {
+          throw new RuntimeException("cpu " + cpu + " is not yet supported");
+       }
+diff --git a/hotspot/make/bsd/makefiles/sa.make b/hotspot/make/bsd/makefiles/sa.make
+index ca64d5335c..1166806d08 100644
+--- hotspot/make/bsd/makefiles/sa.make
++++ hotspot/make/bsd/makefiles/sa.make
+@@ -108,6 +108,7 @@ $(GENERATED)/sa-jdi.jar:: $(AGENT_FILES)
+ 	$(QUIETLY) $(REMOTE) $(RUN.JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
+ 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext
+ 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.amd64.AMD64ThreadContext
++	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.aarch64.AARCH64ThreadContext
+ 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.sparc.SPARCThreadContext
+ 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.debugger.ppc64.PPC64ThreadContext
+ 	$(QUIETLY) $(REMOTE) $(RUN.JAVAH) -classpath $(SA_CLASSDIR) -d $(GENERATED) -jni sun.jvm.hotspot.asm.Disassembler
+-- 
+2.31.1
+
+
+From a08e7d2631d30ab4a8638d440c0f03e653346de1 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:41:27 +0200
+Subject: [PATCH 09/18] Import icedtea-hotspot-insantiate-arrayallocator.patch
+ patch from alpinelinux:
+
+Workarounds build error:
+Error: dl failure on line 895
+Error relocating .../libjvm.so: _ZN14ArrayAllocatorImL10MemoryType7EE4freeEv: symbol not found
+
+Possibly due to g++ 10.x error on not properly instantiating the template.
+
+https://git.alpinelinux.org/aports/commit/?id=c4ee41d5047cded26ad472cb64f146f1e0e0c205
+---
+ hotspot/src/share/vm/utilities/bitMap.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/hotspot/src/share/vm/utilities/bitMap.cpp b/hotspot/src/share/vm/utilities/bitMap.cpp
+index e64add155d..9323efb7ba 100644
+--- hotspot/src/share/vm/utilities/bitMap.cpp
++++ hotspot/src/share/vm/utilities/bitMap.cpp
+@@ -42,6 +42,8 @@
+ # include "os_bsd.inline.hpp"
+ #endif
+ 
++template class ArrayAllocator<BitMap::bm_word_t, mtInternal>;
++
+ 
+ BitMap::BitMap(bm_word_t* map, idx_t size_in_bits) :
+   _map(map), _size(size_in_bits), _map_allocator(false)
+-- 
+2.31.1
+
+
+From f2156cbc43e51ee4e04c943cdc5e43a8a1f6241e Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:49:11 +0200
+Subject: [PATCH 10/18] Add some includes for bsd aarch64
+
+---
+ hotspot/src/cpu/aarch64/vm/bytes_aarch64.hpp        | 3 +++
+ hotspot/src/cpu/aarch64/vm/copy_aarch64.hpp         | 3 +++
+ hotspot/src/os/bsd/vm/os_perf_bsd.cpp               | 3 +++
+ hotspot/src/share/vm/runtime/atomic.inline.hpp      | 3 +++
+ hotspot/src/share/vm/runtime/globals.hpp            | 3 +++
+ hotspot/src/share/vm/runtime/orderAccess.inline.hpp | 3 +++
+ hotspot/src/share/vm/runtime/os.hpp                 | 3 +++
+ hotspot/src/share/vm/runtime/prefetch.inline.hpp    | 3 +++
+ hotspot/src/share/vm/runtime/thread.hpp             | 3 +++
+ hotspot/src/share/vm/runtime/threadLocalStorage.hpp | 3 +++
+ hotspot/src/share/vm/runtime/vmStructs.cpp          | 3 +++
+ 11 files changed, 33 insertions(+)
+
+diff --git a/hotspot/src/cpu/aarch64/vm/bytes_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/bytes_aarch64.hpp
+index b1eaa670af..b6c0fb272f 100644
+--- hotspot/src/cpu/aarch64/vm/bytes_aarch64.hpp
++++ hotspot/src/cpu/aarch64/vm/bytes_aarch64.hpp
+@@ -69,6 +69,9 @@ class Bytes: AllStatic {
+ 
+ // The following header contains the implementations of swap_u2, swap_u4, and swap_u8[_base]
+ 
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "bytes_bsd_aarch64.inline.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_linux_aarch64
+ # include "bytes_linux_aarch64.inline.hpp"
+ #endif
+diff --git a/hotspot/src/cpu/aarch64/vm/copy_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/copy_aarch64.hpp
+index 62c1581f31..63e6d3861c 100644
+--- hotspot/src/cpu/aarch64/vm/copy_aarch64.hpp
++++ hotspot/src/cpu/aarch64/vm/copy_aarch64.hpp
+@@ -30,6 +30,9 @@
+ // Inline functions for memory copy and fill.
+ 
+ // Contains inline asm implementations
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "copy_bsd_aarch64.inline.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_linux_aarch64
+ # include "copy_linux_aarch64.inline.hpp"
+ #endif
+diff --git a/hotspot/src/os/bsd/vm/os_perf_bsd.cpp b/hotspot/src/os/bsd/vm/os_perf_bsd.cpp
+index bfce29d7e2..32e33eccab 100644
+--- hotspot/src/os/bsd/vm/os_perf_bsd.cpp
++++ hotspot/src/os/bsd/vm/os_perf_bsd.cpp
+@@ -27,6 +27,9 @@
+ #include "runtime/os.hpp"
+ #include "runtime/os_perf.hpp"
+ 
++#ifdef TARGET_ARCH_aarch64
++# include "vm_version_ext_aarch64.hpp"
++#endif
+ #ifdef TARGET_ARCH_x86
+ # include "vm_version_ext_x86.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/atomic.inline.hpp b/hotspot/src/share/vm/runtime/atomic.inline.hpp
+index 9ab317638c..2c1d72704d 100644
+--- hotspot/src/share/vm/runtime/atomic.inline.hpp
++++ hotspot/src/share/vm/runtime/atomic.inline.hpp
+@@ -66,6 +66,9 @@
+ #endif
+ 
+ // BSD
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "atomic_bsd_aarch64.inline.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "atomic_bsd_ppc.inline.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
+index 1563ff6cbb..8d0c1f7c7f 100644
+--- hotspot/src/share/vm/runtime/globals.hpp
++++ hotspot/src/share/vm/runtime/globals.hpp
+@@ -100,6 +100,9 @@
+ #ifdef TARGET_OS_ARCH_aix_ppc
+ # include "globals_aix_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "globals_bsd_aarch64.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "globals_bsd_ppc.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/orderAccess.inline.hpp b/hotspot/src/share/vm/runtime/orderAccess.inline.hpp
+index d444414939..7d5bb1aff0 100644
+--- hotspot/src/share/vm/runtime/orderAccess.inline.hpp
++++ hotspot/src/share/vm/runtime/orderAccess.inline.hpp
+@@ -67,6 +67,9 @@
+ #endif
+ 
+ // BSD
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "orderAccess_bsd_aarch64.inline.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "orderAccess_bsd_ppc.inline.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
+index cc767b5bfd..8dffa6e1ec 100644
+--- hotspot/src/share/vm/runtime/os.hpp
++++ hotspot/src/share/vm/runtime/os.hpp
+@@ -884,6 +884,9 @@ class os: AllStatic {
+ #ifdef TARGET_OS_ARCH_aix_ppc
+ # include "os_aix_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "os_bsd_aarch64.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "os_bsd_ppc.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/prefetch.inline.hpp b/hotspot/src/share/vm/runtime/prefetch.inline.hpp
+index 0126967299..4235b4f984 100644
+--- hotspot/src/share/vm/runtime/prefetch.inline.hpp
++++ hotspot/src/share/vm/runtime/prefetch.inline.hpp
+@@ -66,6 +66,9 @@
+ #endif
+ 
+ // BSD
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "prefetch_bsd_aarch64.inline.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "prefetch_bsd_ppc.inline.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
+index 07d30c1eab..ee2d5c5d5a 100644
+--- hotspot/src/share/vm/runtime/thread.hpp
++++ hotspot/src/share/vm/runtime/thread.hpp
+@@ -1728,6 +1728,9 @@ public:
+ #ifdef TARGET_OS_ARCH_aix_ppc
+ # include "thread_aix_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "thread_bsd_aarch64.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "thread_bsd_ppc.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/threadLocalStorage.hpp b/hotspot/src/share/vm/runtime/threadLocalStorage.hpp
+index f30ad52bba..1322c629b2 100644
+--- hotspot/src/share/vm/runtime/threadLocalStorage.hpp
++++ hotspot/src/share/vm/runtime/threadLocalStorage.hpp
+@@ -78,6 +78,9 @@ class ThreadLocalStorage : AllStatic {
+ #ifdef TARGET_OS_ARCH_aix_ppc
+ # include "threadLS_aix_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "threadLS_bsd_aarch64.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "threadLS_bsd_ppc.hpp"
+ #endif
+diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
+index 841b90b058..4168c43562 100644
+--- hotspot/src/share/vm/runtime/vmStructs.cpp
++++ hotspot/src/share/vm/runtime/vmStructs.cpp
+@@ -152,6 +152,9 @@
+ #ifdef TARGET_OS_ARCH_aix_ppc
+ # include "vmStructs_aix_ppc.hpp"
+ #endif
++#ifdef TARGET_OS_ARCH_bsd_aarch64
++# include "vmStructs_bsd_aarch64.hpp"
++#endif
+ #ifdef TARGET_OS_ARCH_bsd_ppc
+ # include "vmStructs_bsd_ppc.hpp"
+ #endif
+-- 
+2.31.1
+
+
+From a698adabb4799eed63d13fefa1a27f5a998dd523 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 16:52:31 +0200
+Subject: [PATCH 11/18] Add a definition for cpu_arch for bsd aarch64
+
+---
+ hotspot/src/os/bsd/vm/os_bsd.cpp | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
+index 434ad5878e..8401fbdc26 100644
+--- hotspot/src/os/bsd/vm/os_bsd.cpp
++++ hotspot/src/os/bsd/vm/os_bsd.cpp
+@@ -277,6 +277,8 @@ static char cpu_arch[] = "sparcv9";
+ #  else
+ static char cpu_arch[] = "sparc";
+ #  endif
++#elif defined(AARCH64)
++static char cpu_arch[] = "aarch64";
+ #else
+ #error Add appropriate cpu_arch setting
+ #endif
+-- 
+2.31.1
+
+
+From cb4a5aed8867bcb5eb59391a6e9f080bf12b5e39 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 18:26:47 +0200
+Subject: [PATCH 12/18] 
+ hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java: Add bsd
+ aarch64
+
+---
+ .../src/share/classes/sun/jvm/hotspot/runtime/Threads.java     | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
+index e3658dd3bd..1705a366d7 100644
+--- hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
+@@ -37,6 +37,7 @@ import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess;
+ import sun.jvm.hotspot.runtime.linux_sparc.LinuxSPARCJavaThreadPDAccess;
+ import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess;
+ import sun.jvm.hotspot.runtime.bsd_x86.BsdX86JavaThreadPDAccess;
++import sun.jvm.hotspot.runtime.bsd_aarch64.BsdAARCH64JavaThreadPDAccess;
+ import sun.jvm.hotspot.runtime.bsd_amd64.BsdAMD64JavaThreadPDAccess;
+ import sun.jvm.hotspot.runtime.bsd_ppc64.BsdPPC64JavaThreadPDAccess;
+ import sun.jvm.hotspot.utilities.*;
+@@ -107,6 +108,8 @@ public class Threads {
+                 access = new BsdX86JavaThreadPDAccess();
+             } else if (cpu.equals("amd64") || cpu.equals("x86_64")) {
+                 access = new BsdAMD64JavaThreadPDAccess();
++            } else if (cpu.equals("aarch64")) {
++                access = new BsdAARCH64JavaThreadPDAccess();
+             } else if (cpu.equals("ppc64")) {
+                 access = new BsdPPC64JavaThreadPDAccess();
+             }
+-- 
+2.31.1
+
+
+From 2059ef2ce765225bbfab47902532c06fc744b77e Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Fri, 7 May 2021 18:31:06 +0200
+Subject: [PATCH 13/18] vm_version_aarch64.cpp: add bsd aarch64 support
+
+---
+ .../src/cpu/aarch64/vm/vm_version_aarch64.cpp |  18 ++
+ .../src/cpu/aarch64/vm/vm_version_aarch64.hpp |   3 +
+ .../bsd_aarch64/vm/vm_version_bsd_aarch64.cpp | 260 ++++++++++++++++++
+ 3 files changed, 281 insertions(+)
+
+diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
+index 6b5f19ba5a..c1943ec99b 100644
+--- hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
++++ hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
+@@ -34,13 +34,25 @@
+ # include "os_linux.inline.hpp"
+ #endif
+ 
++#if defined (__linux__)
+ #include <sys/auxv.h>
+ #include <asm/hwcap.h>
++#elif defined (__FreeBSD__)
++#include <machine/elf.h>
++#endif
++
++#ifndef HWCAP_ASIMD
++#define HWCAP_ASIMD (1<<1)
++#endif
+ 
+ #ifndef HWCAP_AES
+ #define HWCAP_AES   (1<<3)
+ #endif
+ 
++#ifndef HWCAP_PMULL
++#define HWCAP_PMULL (1<<4)
++#endif
++
+ #ifndef HWCAP_SHA1
+ #define HWCAP_SHA1  (1<<5)
+ #endif
+@@ -140,6 +152,7 @@ void VM_Version::get_processor_features() {
+   }
+   FLAG_SET_DEFAULT(UseSSE42Intrinsics, true);
+ 
++#if defined(__linux__)
+   unsigned long auxv = getauxval(AT_HWCAP);
+ 
+   char buf[512];
+@@ -175,6 +188,11 @@ void VM_Version::get_processor_features() {
+     }
+     fclose(f);
+   }
++#elif defined(__FreeBSD__) || defined(__OpenBSD__)
++  char buf[512];
++  int cpu_lines = 0;
++  unsigned long auxv = os_get_processor_features();
++#endif
+ 
+   // Enable vendor specific features
+   if (_cpu == CPU_CAVIUM) {
+diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
+index 7f3a532624..507400b0f4 100644
+--- hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
++++ hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
+@@ -49,6 +49,9 @@ protected:
+   };
+   static PsrInfo _psr_info;
+   static void get_processor_features();
++#if defined(__FreeBSD__) || defined(__OpenBSD__)
++  static unsigned long os_get_processor_features();
++#endif
+ 
+ public:
+   // Initialization
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp b/hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
+index e9a0c606f3..c1ce881071 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/vm_version_bsd_aarch64.cpp
+@@ -26,3 +26,263 @@
+ #include "runtime/os.hpp"
+ #include "vm_version_aarch64.hpp"
+ 
++#include <machine/armreg.h>
++#if defined (__FreeBSD__)
++#include <machine/elf.h>
++#endif
++
++#ifndef HWCAP_ASIMD
++#define HWCAP_ASIMD (1<<1)
++#endif
++
++#ifndef HWCAP_AES
++#define HWCAP_AES   (1<<3)
++#endif
++
++#ifndef HWCAP_PMULL
++#define HWCAP_PMULL (1<<4)
++#endif
++
++#ifndef HWCAP_SHA1
++#define HWCAP_SHA1  (1<<5)
++#endif
++
++#ifndef HWCAP_SHA2
++#define HWCAP_SHA2  (1<<6)
++#endif
++
++#ifndef HWCAP_CRC32
++#define HWCAP_CRC32 (1<<7)
++#endif
++
++#ifndef HWCAP_ATOMICS
++#define HWCAP_ATOMICS (1<<8)
++#endif
++
++#ifndef ID_AA64PFR0_AdvSIMD_SHIFT
++#define ID_AA64PFR0_AdvSIMD_SHIFT 20
++#endif
++
++#ifndef ID_AA64PFR0_AdvSIMD
++#define ID_AA64PFR0_AdvSIMD(x) ((x) & (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT))
++#endif
++
++#ifndef ID_AA64PFR0_AdvSIMD_IMPL
++#define ID_AA64PFR0_AdvSIMD_IMPL (UL(0x0) << ID_AA64PFR0_AdvSIMD_SHIFT)
++#endif
++
++#ifndef ID_AA64PFR0_AdvSIMD_HP
++#define ID_AA64PFR0_AdvSIMD_HP (UL(0x1) << ID_AA64PFR0_AdvSIMD_SHIFT)
++#endif
++
++#ifndef ID_AA64ISAR0_AES_VAL
++#define ID_AA64ISAR0_AES_VAL ID_AA64ISAR0_AES
++#endif
++
++#ifndef ID_AA64ISAR0_SHA1_VAL
++#define ID_AA64ISAR0_SHA1_VAL ID_AA64ISAR0_SHA1
++#endif
++
++#ifndef ID_AA64ISAR0_SHA2_VAL
++#define ID_AA64ISAR0_SHA2_VAL ID_AA64ISAR0_SHA2
++#endif
++
++#ifndef ID_AA64ISAR0_CRC32_VAL
++#define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32
++#endif
++
++#define	CPU_IMPL_ARM		0x41
++#define	CPU_IMPL_BROADCOM	0x42
++#define	CPU_IMPL_CAVIUM		0x43
++#define	CPU_IMPL_DEC		0x44
++#define	CPU_IMPL_INFINEON	0x49
++#define	CPU_IMPL_FREESCALE	0x4D
++#define	CPU_IMPL_NVIDIA		0x4E
++#define	CPU_IMPL_APM		0x50
++#define	CPU_IMPL_QUALCOMM	0x51
++#define	CPU_IMPL_MARVELL	0x56
++#define	CPU_IMPL_INTEL		0x69
++
++/* ARM Part numbers */
++#define	CPU_PART_FOUNDATION	0xD00
++#define	CPU_PART_CORTEX_A35	0xD04
++#define	CPU_PART_CORTEX_A53	0xD03
++#define	CPU_PART_CORTEX_A55	0xD05
++#define	CPU_PART_CORTEX_A57	0xD07
++#define	CPU_PART_CORTEX_A72	0xD08
++#define	CPU_PART_CORTEX_A73	0xD09
++#define	CPU_PART_CORTEX_A75	0xD0A
++
++/* Cavium Part numbers */
++#define	CPU_PART_THUNDERX	0x0A1
++#define	CPU_PART_THUNDERX_81XX	0x0A2
++#define	CPU_PART_THUNDERX_83XX	0x0A3
++#define	CPU_PART_THUNDERX2	0x0AF
++
++#define	CPU_REV_THUNDERX_1_0	0x00
++#define	CPU_REV_THUNDERX_1_1	0x01
++
++#define	CPU_REV_THUNDERX2_0	0x00
++
++#define	CPU_IMPL(midr)	(((midr) >> 24) & 0xff)
++#define	CPU_PART(midr)	(((midr) >> 4) & 0xfff)
++#define	CPU_VAR(midr)	(((midr) >> 20) & 0xf)
++#define	CPU_REV(midr)	(((midr) >> 0) & 0xf)
++#define UL(x)   UINT64_C(x)
++
++struct cpu_desc {
++	u_int		cpu_impl;
++	u_int		cpu_part_num;
++	u_int		cpu_variant;
++	u_int		cpu_revision;
++	const char	*cpu_impl_name;
++	const char	*cpu_part_name;
++};
++
++struct cpu_parts {
++	u_int		part_id;
++	const char	*part_name;
++};
++#define	CPU_PART_NONE	{ 0, "Unknown Processor" }
++
++struct cpu_implementers {
++	u_int			impl_id;
++	const char		*impl_name;
++	/*
++	 * Part number is implementation defined
++	 * so each vendor will have its own set of values and names.
++	 */
++	const struct cpu_parts	*cpu_parts;
++};
++#define	CPU_IMPLEMENTER_NONE	{ 0, "Unknown Implementer", cpu_parts_none }
++
++/*
++ * Per-implementer table of (PartNum, CPU Name) pairs.
++ */
++/* ARM Ltd. */
++static const struct cpu_parts cpu_parts_arm[] = {
++	{ CPU_PART_FOUNDATION, "Foundation-Model" },
++	{ CPU_PART_CORTEX_A35, "Cortex-A35" },
++	{ CPU_PART_CORTEX_A53, "Cortex-A53" },
++	{ CPU_PART_CORTEX_A55, "Cortex-A55" },
++	{ CPU_PART_CORTEX_A57, "Cortex-A57" },
++	{ CPU_PART_CORTEX_A72, "Cortex-A72" },
++	{ CPU_PART_CORTEX_A73, "Cortex-A73" },
++	{ CPU_PART_CORTEX_A75, "Cortex-A75" },
++	CPU_PART_NONE,
++};
++/* Cavium */
++static const struct cpu_parts cpu_parts_cavium[] = {
++	{ CPU_PART_THUNDERX, "ThunderX" },
++	{ CPU_PART_THUNDERX2, "ThunderX2" },
++	CPU_PART_NONE,
++};
++
++/* Unknown */
++static const struct cpu_parts cpu_parts_none[] = {
++	CPU_PART_NONE,
++};
++
++/*
++ * Implementers table.
++ */
++const struct cpu_implementers cpu_implementers[] = {
++	{ CPU_IMPL_ARM,		"ARM",		cpu_parts_arm },
++	{ CPU_IMPL_BROADCOM,	"Broadcom",	cpu_parts_none },
++	{ CPU_IMPL_CAVIUM,	"Cavium",	cpu_parts_cavium },
++	{ CPU_IMPL_DEC,		"DEC",		cpu_parts_none },
++	{ CPU_IMPL_INFINEON,	"IFX",		cpu_parts_none },
++	{ CPU_IMPL_FREESCALE,	"Freescale",	cpu_parts_none },
++	{ CPU_IMPL_NVIDIA,	"NVIDIA",	cpu_parts_none },
++	{ CPU_IMPL_APM,		"APM",		cpu_parts_none },
++	{ CPU_IMPL_QUALCOMM,	"Qualcomm",	cpu_parts_none },
++	{ CPU_IMPL_MARVELL,	"Marvell",	cpu_parts_none },
++	{ CPU_IMPL_INTEL,	"Intel",	cpu_parts_none },
++	CPU_IMPLEMENTER_NONE,
++};
++
++#ifdef __OpenBSD__
++// READ_SPECIALREG is not available from userland on OpenBSD.
++// Hardcode these values to the "lowest common denominator"
++unsigned long VM_Version::os_get_processor_features() {
++  _cpu = CPU_IMPL_ARM;
++  _model = CPU_PART_CORTEX_A53;
++  _variant = 0;
++  _revision = 0;
++  return HWCAP_ASIMD;
++}
++#else
++unsigned long VM_Version::os_get_processor_features() {
++  struct cpu_desc cpu_desc[1];
++  struct cpu_desc user_cpu_desc;
++  unsigned long auxv = 0;
++  uint64_t id_aa64isar0, id_aa64pfr0;
++
++  uint32_t midr;
++  uint32_t impl_id;
++  uint32_t part_id;
++  uint32_t cpu = 0;
++  size_t i;
++  const struct cpu_parts *cpu_partsp = NULL;
++
++  midr = READ_SPECIALREG(midr_el1);
++
++  impl_id = CPU_IMPL(midr);
++  for (i = 0; i < nitems(cpu_implementers); i++) {
++    if (impl_id == cpu_implementers[i].impl_id ||
++      cpu_implementers[i].impl_id == 0) {
++      cpu_desc[cpu].cpu_impl = impl_id;
++      cpu_desc[cpu].cpu_impl_name = cpu_implementers[i].impl_name;
++      cpu_partsp = cpu_implementers[i].cpu_parts;
++      break;
++    }
++  }
++
++  part_id = CPU_PART(midr);
++  for (i = 0; &cpu_partsp[i] != NULL; i++) {
++    if (part_id == cpu_partsp[i].part_id || cpu_partsp[i].part_id == 0) {
++      cpu_desc[cpu].cpu_part_num = part_id;
++      cpu_desc[cpu].cpu_part_name = cpu_partsp[i].part_name;
++      break;
++    }
++  }
++
++  cpu_desc[cpu].cpu_revision = CPU_REV(midr);
++  cpu_desc[cpu].cpu_variant = CPU_VAR(midr);
++
++  _cpu = cpu_desc[cpu].cpu_impl;
++  _variant = cpu_desc[cpu].cpu_variant;
++  _model = cpu_desc[cpu].cpu_part_num;
++  _revision = cpu_desc[cpu].cpu_revision;
++
++  id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
++  id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1);
++
++  if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_BASE) {
++    auxv = auxv | HWCAP_AES;
++  }
++
++  if (ID_AA64ISAR0_AES_VAL(id_aa64isar0) == ID_AA64ISAR0_AES_PMULL) {
++    auxv = auxv | HWCAP_PMULL;
++  }
++
++  if (ID_AA64ISAR0_SHA1_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA1_BASE) {
++    auxv = auxv | HWCAP_SHA1;
++  }
++
++  if (ID_AA64ISAR0_SHA2_VAL(id_aa64isar0) == ID_AA64ISAR0_SHA2_BASE) {
++    auxv = auxv | HWCAP_SHA2;
++  }
++
++  if (ID_AA64ISAR0_CRC32_VAL(id_aa64isar0) == ID_AA64ISAR0_CRC32_BASE) {
++    auxv = auxv | HWCAP_CRC32;
++  }
++
++  if (ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_IMPL || \
++      ID_AA64PFR0_AdvSIMD(id_aa64pfr0) == ID_AA64PFR0_AdvSIMD_HP ) {
++    auxv = auxv | HWCAP_ASIMD;
++  }
++
++  return auxv;
++}
++#endif
+-- 
+2.31.1
+
+
+From b3ba6fcca827d49bb26efd14ef6869952c9d43d6 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Sun, 9 May 2021 11:14:03 +0200
+Subject: [PATCH 15/18] Add bsd aarch64 makefiles
+
+---
+ hotspot/make/bsd/makefiles/buildtree.make | 1 +
+ hotspot/make/bsd/makefiles/defs.make      | 9 +++++++++
+ hotspot/make/bsd/makefiles/gcc.make       | 2 ++
+ 3 files changed, 12 insertions(+)
+
+diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make
+index 3c40b174bb..35ae749fd1 100644
+--- hotspot/make/bsd/makefiles/buildtree.make
++++ hotspot/make/bsd/makefiles/buildtree.make
+@@ -202,6 +202,7 @@ LP64_SETTING/64 = LP64 = 1
+ 
+ DATA_MODE/i486 = 32
+ DATA_MODE/amd64 = 64
++DATA_MODE/aarch64 = 64
+ 
+ DATA_MODE = $(DATA_MODE/$(BUILDARCH))
+ 
+diff --git a/hotspot/make/bsd/makefiles/defs.make b/hotspot/make/bsd/makefiles/defs.make
+index 9b4a7479a2..3b9d05226c 100644
+--- hotspot/make/bsd/makefiles/defs.make
++++ hotspot/make/bsd/makefiles/defs.make
+@@ -140,6 +140,15 @@ ifneq (,$(findstring $(ARCH), ppc ppc64))
+   HS_ARCH = ppc
+ endif
+ 
++# AARCH64
++ifeq ($(ARCH), aarch64)
++  ARCH_DATA_MODEL  = 64
++  MAKE_ARGS        += LP64=1
++  PLATFORM         = bsd-aarch64
++  VM_PLATFORM      = bsd_aarch64
++  HS_ARCH          = aarch64
++endif
++
+ # On 32 bit bsd we build server and client, on 64 bit just server.
+ ifeq ($(JVM_VARIANTS),)
+   ifeq ($(ARCH_DATA_MODEL), 32)
+diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make
+index 16d9088763..72caf476f6 100644
+--- hotspot/make/bsd/makefiles/gcc.make
++++ hotspot/make/bsd/makefiles/gcc.make
+@@ -232,6 +232,7 @@ endif
+ ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
+ ARCHFLAG/i486    = -m32 -march=i586
+ ARCHFLAG/amd64   = -m64 $(STACK_ALIGNMENT_OPT)
++ARCHFLAG/aarch64 =
+ ARCHFLAG/ia64    =
+ ARCHFLAG/sparc   = -m32 -mcpu=v9
+ ARCHFLAG/sparcv9 = -m64 -mcpu=v9
+@@ -477,6 +478,7 @@ else
+     STABS_CFLAGS/arm   = -g
+     STABS_CFLAGS/ppc   = -g
+     STABS_CFLAGS/amd64 = -g
++    STABS_CFLAGS/aarch64 = -g
+     ifeq ($(STABS_CFLAGS/$(BUILDARCH)),)
+       STABS_CFLAGS += -gstabs
+     else
+-- 
+2.31.1
+
+
+From 380dad7993adf208ad3589cdd493ed97b4f41e83 Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Mon, 10 May 2021 18:17:28 +0200
+Subject: [PATCH 16/18] Add libsa for bsd aarch64
+
+---
+ hotspot/make/bsd/makefiles/defs.make | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/hotspot/make/bsd/makefiles/defs.make b/hotspot/make/bsd/makefiles/defs.make
+index 3b9d05226c..4b4785a795 100644
+--- hotspot/make/bsd/makefiles/defs.make
++++ hotspot/make/bsd/makefiles/defs.make
+@@ -377,6 +377,8 @@ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+   endif
+ endif
+ 
++ADD_SA_BINARIES/aarch64   = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
++                        $(EXPORT_LIB_DIR)/sa-jdi.jar
+ ADD_SA_BINARIES/ppc   = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+                         $(EXPORT_LIB_DIR)/sa-jdi.jar
+ ADD_SA_BINARIES/universal = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+@@ -384,11 +386,13 @@ ADD_SA_BINARIES/universal = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFI
+ 
+ ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+   ifeq ($(ZIP_DEBUGINFO_FILES),1)
++      ADD_SA_BINARIES/aarch64 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
+       ADD_SA_BINARIES/ppc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
+   else
+     ifeq ($(OS_VENDOR), Darwin)
+         ADD_SA_BINARIES/ppc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX).dSYM
+     else
++        ADD_SA_BINARIES/aarch64 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+         ADD_SA_BINARIES/ppc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+     endif
+   endif
+-- 
+2.31.1
+
+
+From 32d1d1035e42ce0c74ac73775faced9b3c47208b Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Mon, 10 May 2021 19:03:54 +0200
+Subject: [PATCH 17/18] Fix runtime crash if memnode is compiled at O2
+
+---
+ hotspot/make/bsd/makefiles/aarch64.make | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hotspot/make/bsd/makefiles/aarch64.make b/hotspot/make/bsd/makefiles/aarch64.make
+index 4aa1165475..aac810f118 100644
+--- hotspot/make/bsd/makefiles/aarch64.make
++++ hotspot/make/bsd/makefiles/aarch64.make
+@@ -38,3 +38,6 @@ CFLAGS += -DVM_LITTLE_ENDIAN
+ # CFLAGS += -D_LP64=1
+ 
+ OPT_CFLAGS/compactingPermGenGen.o = -O1
++
++PCH_FLAG/memnode.o = $(PCH_FLAG/NO_PCH)
++OPT_CFLAGS/memnode.o = -O0
+-- 
+2.31.1
+
+
+From d27557188bf484279ef3ab1cf35ec70b7f7e99ec Mon Sep 17 00:00:00 2001
+From: mikael <mikael@FreeBSD.org>
+Date: Mon, 10 May 2021 19:10:28 +0200
+Subject: [PATCH 18/18] backport
+ https://github.com/battleblow/openjdk-jdk11u/commit/9feb0ec45ceb6591a35321476c500d899677753f
+
+---
+ .../bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java     | 11 ++++++++---
+ .../os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp   |  5 ++---
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+index 4f84e1576d..3388a55ab9 100644
+--- hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
++++ hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/bsd_aarch64/BsdAARCH64JavaThreadPDAccess.java
+@@ -29,6 +29,8 @@ import java.io.*;
+ import java.util.*;
+ import sun.jvm.hotspot.debugger.*;
+ import sun.jvm.hotspot.debugger.aarch64.*;
++import sun.jvm.hotspot.debugger.bsd.BsdDebugger;
++import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal;
+ import sun.jvm.hotspot.runtime.*;
+ import sun.jvm.hotspot.runtime.aarch64.*;
+ import sun.jvm.hotspot.types.*;
+@@ -38,8 +40,9 @@ public class BsdAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
+   private static AddressField  lastJavaFPField;
+   private static AddressField  osThreadField;
+ 
+-  // Field from OSThread
++  // Fields from OSThread
+   private static CIntegerField osThreadThreadIDField;
++  private static CIntegerField osThreadUniqueThreadIDField;
+ 
+   // This is currently unneeded but is being kept in case we change
+   // the currentFrameGuess algorithm
+@@ -62,6 +65,7 @@ public class BsdAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
+ 
+     Type osThreadType = db.lookupType("OSThread");
+     osThreadThreadIDField   = osThreadType.getCIntegerField("_thread_id");
++    osThreadUniqueThreadIDField = osThreadType.getCIntegerField("_unique_thread_id");
+   }
+ 
+   public Address getLastJavaFP(Address addr) {
+@@ -125,8 +129,9 @@ public class BsdAARCH64JavaThreadPDAccess implements JavaThreadPDAccess {
+     Address osThreadAddr = osThreadField.getValue(addr);
+     // Get the address of the _thread_id from the OSThread
+     Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset());
++    Address uniqueThreadIdAddr = osThreadAddr.addOffsetTo(osThreadUniqueThreadIDField.getOffset());
+ 
+-    JVMDebugger debugger = VM.getVM().getDebugger();
+-    return debugger.getThreadForIdentifierAddress(threadIdAddr);
++    BsdDebuggerLocal debugger = (BsdDebuggerLocal) VM.getVM().getDebugger();
++    return debugger.getThreadForIdentifierAddress(threadIdAddr, uniqueThreadIdAddr);
+   }
+ }
+diff --git a/hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp b/hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
+index a0e19ac226..e080f78264 100644
+--- hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
++++ hotspot/src/os_cpu/bsd_aarch64/vm/vmStructs_bsd_aarch64.hpp
+@@ -35,7 +35,7 @@
+   /* Threads (NOTE: incomplete) */                                                                                                   \
+   /******************************/                                                                                                   \
+   nonstatic_field(OSThread,                      _thread_id,                                      OSThread::thread_id_t)             \
+-  nonstatic_field(OSThread,                      _pthread_id,                                     pthread_t)
++  nonstatic_field(OSThread,                      _unique_thread_id,                               uint64_t)
+ 
+ 
+ #define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
+@@ -44,8 +44,7 @@
+   /* Posix Thread IDs   */                                                \
+   /**********************/                                                \
+                                                                           \
+-  declare_integer_type(OSThread::thread_id_t)                             \
+-  declare_unsigned_integer_type(pthread_t)
++  declare_unsigned_integer_type(OSThread::thread_id_t)
+ 
+ #define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
+ 
+-- 
+2.31.1
+
