From 2fd15967a7974d1d61cc7aa706c82733c572964d Mon Sep 17 00:00:00 2001
Date: Thu, 21 Sep 2023 15:14:11 +0800
Subject: The-OverWriteOldestGCLog-option-is-added-to-control

---
 hotspot/src/share/vm/runtime/globals.hpp   |  3 ++
 hotspot/src/share/vm/utilities/ostream.cpp | 45 ++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index 4f649bd45..fdd9db149 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -2571,6 +2571,9 @@ class CommandLineFlags {
           "GC log file size, requires UseGCLogFileRotation. "               \
           "Set to 0 to only trigger rotation via jcmd")                     \
                                                                             \
+  product(bool, OverWriteOldestGCLog, false,                                \
+          "Over write the oldest gclog")                                    \
+                                                                            \
   /* JVMTI heap profiling */                                                \
                                                                             \
   diagnostic(bool, TraceJVMTIObjectTagging, false,                          \
diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp
index f4e127145..133b5a7c0 100644
--- a/hotspot/src/share/vm/utilities/ostream.cpp
+++ b/hotspot/src/share/vm/utilities/ostream.cpp
@@ -843,6 +843,48 @@ gcLogFileStream::~gcLogFileStream() {
   delete _file_lock;
 }
 
+static uintx next_file_number(const char*  filename) {
+  uintx next_num;
+  uintx index;
+  char gclog[JVM_MAXPATHLEN];
+  struct stat st;
+  long oldestTime = LONG_MAX;
+  bool normal_file_exist;
+  bool current_file_exist;
+  for (index = 0; index < NumberOfGCLogFiles; ++index) {
+    // normal gc log file
+    jio_snprintf(gclog, JVM_MAXPATHLEN, "%s.%d", filename, index);
+    normal_file_exist = (os::stat(gclog, &st) == 0);
+    if (normal_file_exist && oldestTime > st.st_mtime) {
+      oldestTime = st.st_mtime;
+      next_num = index;
+    }
+
+    // current gc log file
+    jio_snprintf(gclog, JVM_MAXPATHLEN, "%s.%d" CURRENTAPPX, filename, index);
+    current_file_exist = (os::stat(gclog, &st) == 0);
+    if (current_file_exist && oldestTime > st.st_mtime) {
+      oldestTime = st.st_mtime;
+      next_num = index;
+    }
+
+    // Stop looking if we find an unused file name
+    if (!normal_file_exist && !current_file_exist) {
+      next_num = index;
+      break;
+    }
+  }
+  // remove the existing normal file
+  char exist_file_name[JVM_MAXPATHLEN];
+  jio_snprintf(exist_file_name, JVM_MAXPATHLEN, "%s.%d", filename, next_num);
+  if (access(exist_file_name, 0) == 0) { // mode 0: Check whether the file exists, F_OK=0. F_OK will cause Windows build failure. Use 0 instead.
+    if (remove(exist_file_name) != 0) {
+      warning("Could not delete existing normal file %s\n", exist_file_name);
+    }
+  }
+  return next_num;
+}
+
 gcLogFileStream::gcLogFileStream(const char* file_name) : _file_lock(NULL) {
   _cur_file_num = 0;
   _bytes_written = 0L;
@@ -857,6 +899,9 @@ gcLogFileStream::gcLogFileStream(const char* file_name) : _file_lock(NULL) {
 
   // gc log file rotation
   if (UseGCLogFileRotation && NumberOfGCLogFiles > 1) {
+    if (OverWriteOldestGCLog) {
+      _cur_file_num = next_file_number(_file_name);
+    }
     char tempbuf[JVM_MAXPATHLEN];
     jio_snprintf(tempbuf, sizeof(tempbuf), "%s.%d" CURRENTAPPX, _file_name, _cur_file_num);
     _file = fopen(tempbuf, "w");
-- 
2.22.0

