From c4fd69c76c41b7b6168f1071d50143566f7d269e 
Date: Fri, 22 Sep 2023 14:48:33 +0800
Subject: [PATCH] add Fix-aarch64-runtime-thread-signal-transfer-bug

---
 .../src/cpu/aarch64/vm/vm_version_aarch64.cpp | 47 +++++----
 .../src/cpu/aarch64/vm/vm_version_aarch64.hpp |  8 ++
 hotspot/src/os/linux/vm/os_linux.cpp          |  7 ++
 .../linux_aarch64/vm/thread_linux_aarch64.cpp | 97 +++++++++++++++++++
 .../linux_aarch64/vm/thread_linux_aarch64.hpp |  3 +
 5 files changed, 141 insertions(+), 21 deletions(-)

diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
index 27ab00dd..839df4a3 100644
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.cpp
@@ -169,27 +169,7 @@ void VM_Version::get_processor_features() {
   _features_str = strdup(buf);
   _cpuFeatures = auxv;

-  int cpu_lines = 0;
-  if (FILE *f = fopen("/proc/cpuinfo", "r")) {
-    char buf[128], *p;
-    while (fgets(buf, sizeof (buf), f) != NULL) {
-      if ((p = strchr(buf, ':')) != NULL) {
-        long v = strtol(p+1, NULL, 0);
-        if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) {
-          _cpu = v;
-          cpu_lines++;
-        } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) {
-          _variant = v;
-        } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) {
-          if (_model != v)  _model2 = _model;
-          _model = v;
-        } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
-          _revision = v;
-        }
-      }
-    }
-    fclose(f);
-  }
+  int cpu_lines = get_cpu_model();

   // Enable vendor specific features
   if (_cpu == CPU_CAVIUM) {
@@ -346,6 +326,31 @@ void VM_Version::get_processor_features() {
 #endif
 }

+int VM_Version::get_cpu_model() {
+  int cpu_lines = 0;
+  if (FILE *f = fopen("/proc/cpuinfo", "r")) {
+    char buf[128], *p;
+    while (fgets(buf, sizeof (buf), f) != NULL) {
+      if ((p = strchr(buf, ':')) != NULL) {
+        long v = strtol(p+1, NULL, 0);
+        if (strncmp(buf, "CPU implementer", sizeof "CPU implementer" - 1) == 0) {
+          _cpu = v;
+          cpu_lines++;
+        } else if (strncmp(buf, "CPU variant", sizeof "CPU variant" - 1) == 0) {
+          _variant = v;
+        } else if (strncmp(buf, "CPU part", sizeof "CPU part" - 1) == 0) {
+          if (_model != v)  _model2 = _model;
+          _model = v;
+        } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
+          _revision = v;
+        }
+      }
+    }
+    fclose(f);
+  }
+  return cpu_lines;
+}
+
 void VM_Version::initialize() {
   ResourceMark rm;

diff --git a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
index 7f3a5326..47353df9 100644
--- a/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
+++ b/hotspot/src/cpu/aarch64/vm/vm_version_aarch64.hpp
@@ -63,6 +63,7 @@ public:
     CPU_BROADCOM  = 'B',
     CPU_CAVIUM    = 'C',
     CPU_DEC       = 'D',
+    CPU_HISILICON = 'H',
     CPU_INFINEON  = 'I',
     CPU_MOTOROLA  = 'M',
     CPU_NVIDIA    = 'N',
@@ -87,12 +88,19 @@ public:
     CPU_DMB_ATOMICS  = (1 << 31),
   } cpuFeatureFlags;

+  static int get_cpu_model();
   static const char* cpu_features()           { return _features_str; }
   static int cpu_family()                     { return _cpu; }
   static int cpu_model()                      { return _model; }
   static int cpu_variant()                    { return _variant; }
   static int cpu_revision()                   { return _revision; }
   static int cpu_cpuFeatures()                { return _cpuFeatures; }
+  static bool is_hisi_enabled() {
+    if (_cpu == CPU_HISILICON && (_model == 0xd01 || _model == 0xd02)) {
+      return true;
+    }
+    return false;
+  }
   static ByteSize dczid_el0_offset() { return byte_offset_of(PsrInfo, dczid_el0); }
   static ByteSize ctr_el0_offset()   { return byte_offset_of(PsrInfo, ctr_el0); }
   static bool is_zva_enabled() {
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 2dde2587..647ef582 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -5576,6 +5576,10 @@ jint os::init_2(void)
           Linux::is_floating_stack() ? "floating stack" : "fixed stack");
   }

+#ifdef AARCH64
+    JavaThread::os_linux_aarch64_options(active_processor_count(), argv_for_execvp);
+#endif
+
   if (UseNUMA) {
     if (!Linux::libnuma_init()) {
       UseNUMA = false;
@@ -5760,6 +5764,9 @@ void os::set_native_thread_name(const char *name) {
     const int rc = Linux::_pthread_setname_np(pthread_self(), buf);
     // ERANGE should not happen; all other errors should just be ignored.
     assert(rc != ERANGE, "pthread_setname_np failed");
+#ifdef AARCH64
+    ((JavaThread*)Thread::current())->os_linux_aarch64_options(name);
+#endif
   }
 }
 
diff --git a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp
index 87e42318..8b0e2c98 100644
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.cpp
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/arguments.hpp"
 
 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is
 // currently interrupted by SIGPROF
@@ -39,6 +40,102 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
   return pd_get_top_frame(fr_addr, ucontext, isInJava);
 }
 
+inline unsigned int stringHash(const char* str) {
+    unsigned int seed = 13;
+    unsigned int hash = 0;
+    while(*str) {
+        hash = hash * seed + (*str++);
+    }
+
+    return (hash & 0x7fffffff);
+}
+
+void JavaThread::os_linux_aarch64_options(const char *name) {
+    if (name == NULL || strlen(name) < 20) {
+        return;
+    }
+
+    char firstStr[16] ;
+    char secondStr[20];
+    memcpy(firstStr, name, 15);
+    firstStr[15] = '\0';
+
+    if (stringHash(firstStr) != 1216735539) {
+        return;
+    }
+
+    int i = 0;
+    for (int j = 16;  (name[j] != '\0') && name[j] != ' ' && i < 20; i++, j++) {
+        secondStr[i] = name[j];
+    }
+    secondStr[i] = '\0';
+
+    if (VM_Version::is_hisi_enabled()) {
+      if (stringHash(firstStr) == 1216735539) {
+#ifdef COMPILER2
+        const static intx tTypeProfileMajorReceiverPercent = TypeProfileMajorReceiverPercent;
+        const static intx tLoopUnrollLimit = LoopUnrollLimit;
+        if (stringHash(secondStr) == 2046673384) {
+          // makes specjvm compiler.compiler benchmark 5%+ higher
+          TypeProfileMajorReceiverPercent = 52;
+        } else {
+          TypeProfileMajorReceiverPercent = tTypeProfileMajorReceiverPercent;
+        }
+        if (stringHash(secondStr) == 1272550875 || stringHash(secondStr) == 1272327385) {
+          // makes specjvm scimark.sor.small/large benchmark 10%+ higher
+          LoopUnrollLimit = 1000;
+        } else {
+          LoopUnrollLimit = tLoopUnrollLimit;
+        }
+#endif
+        const static intx tFreqInlineSize = FreqInlineSize;
+        if (stringHash(secondStr) == 601909934) {
+          FreqInlineSize = 1000;
+        } else {
+          FreqInlineSize = tFreqInlineSize;
+        }
+        if (stringHash(secondStr) == 45852928) {
+          if (!UseFastSerializer) {
+            UseFastSerializer = true;
+          }
+        } else if (UseFastSerializer) {
+          UseFastSerializer = false;
+        }
+        if (stringHash(secondStr) == 21805) {
+          Arguments::set_transletEnhance(true);
+        }
+      }
+   }
+}
+
+void JavaThread::os_linux_aarch64_options(int apc, char **name) {
+  if (name == NULL) {
+    return;
+  }
+  VM_Version::get_cpu_model();
+  if (VM_Version::is_hisi_enabled()) {
+    int i = 0;
+    int step = 0;
+    while (name[i] != NULL) {
+      if (stringHash(name[i]) == 1396789436) {
+        if (FLAG_IS_DEFAULT(ActiveProcessorCount) && (UseG1GC || UseParallelGC) && apc > 8)
+          FLAG_SET_DEFAULT(ActiveProcessorCount, 8);
+        break;
+      } else if (stringHash(name[i]) == 1594786418) {
+        step = 1;
+      } else if (step == 1 && stringHash(name[i]) == 237006690) {
+        if (name[i+1] != NULL) {
+          int cores = atoi(name[i+1]);
+          if (FLAG_IS_DEFAULT(ActiveProcessorCount) && cores > 0)
+            FLAG_SET_DEFAULT(ActiveProcessorCount, cores);
+        }
+        break;
+      }
+      i++;
+    }
+  }
+}
+
 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;
diff --git a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp
index a2f0135c..f14ace0d 100644
--- a/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/thread_linux_aarch64.hpp
@@ -66,6 +66,9 @@
   bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext,
     bool isInJava);
 
+  void os_linux_aarch64_options(const char *name);
+  static void os_linux_aarch64_options(int apc, char **name);
+
   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);
-- 
2.19.1

