jdk/src/jdk.pack/share/native/common-unpack/utils.cpp
changeset 42693 6645de32a866
parent 33653 c1ee09fe3274
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.pack/share/native/common-unpack/utils.cpp	Wed Dec 14 10:51:13 2016 -0800
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2001, 2015, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/stat.h>
+
+#ifdef _MSC_VER
+#include <direct.h>
+#include <io.h>
+#include <process.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "constants.h"
+#include "defines.h"
+#include "bytes.h"
+#include "utils.h"
+
+#include "unpack.h"
+
+void* must_malloc(size_t size) {
+  size_t msize = size;
+  #ifdef USE_MTRACE
+  if (msize >= 0 && msize < sizeof(int))
+    msize = sizeof(int);  // see 0xbaadf00d below
+  #endif
+  void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : malloc(msize);
+  if (ptr != null) {
+    memset(ptr, 0, size);
+  } else {
+    unpack_abort(ERROR_ENOMEM);
+  }
+  mtrace('m', ptr, size);
+  return ptr;
+}
+
+void mkdirs(int oklen, char* path) {
+
+  if (strlen(path) <= (size_t)oklen)  return;
+  char dir[PATH_MAX];
+
+  strcpy(dir, path);
+  char* slash = strrchr(dir, '/');
+  if (slash == 0)  return;
+  *slash = 0;
+  mkdirs(oklen, dir);
+  MKDIR(dir);
+}
+
+
+#ifndef PRODUCT
+#ifndef STATIC_BUILD
+// use the definition in libjvm when building statically
+void breakpoint() { }  // hook for debugger
+int assert_failed(const char* p) {
+  char message[1<<12];
+  sprintf(message, "@assert failed: %s\n", p);
+  fprintf(stdout, "%s", 1+message);
+  breakpoint();
+  unpack_abort(message);
+  return 0;
+}
+#endif
+#endif
+
+void unpack_abort(const char* msg, unpacker* u) {
+  if (msg == null)  msg = "corrupt pack file or internal error";
+  if (u == null)
+    u = unpacker::current();
+  if (u == null) {
+    fprintf(stderr, "Error: unpacker: %s\n", msg);
+    ::abort();
+    return;
+  }
+  u->abort(msg);
+}
+
+bool unpack_aborting(unpacker* u) {
+  if (u == null)
+    u = unpacker::current();
+  if (u == null) {
+    fprintf(stderr, "Error: unpacker: no current instance\n");
+    ::abort();
+    return true;
+  }
+  return u->aborting();
+}
+
+#ifdef USE_MTRACE
+// Use this occasionally for detecting storage leaks in unpack.
+void mtrace(char c, void* ptr, size_t size) {
+  if (c == 'f')  *(int*)ptr = 0xbaadf00d;
+  static FILE* mtfp;
+  if (mtfp == (FILE*)-1)  return;
+  if (mtfp == null) {
+    if (getenv("USE_MTRACE") == null) {
+      mtfp = (FILE*)-1;
+      return;
+    }
+    char fname[1024];
+    sprintf(fname, "mtr%d.txt", getpid());
+    mtfp = fopen(fname, "w");
+    if (mtfp == null)
+      mtfp = stdout;
+  }
+  fprintf(mtfp, "%c %p %p\n", c, ptr, (void*)size);
+}
+
+/* # Script for processing memory traces.
+   # It should report only a limited number (2) of "suspended" blocks,
+   # even if a large number of archive segments are processed.
+   # It should report no "leaked" blocks at all.
+   nawk < mtr*.txt '
+   function checkleaks(what) {
+     nd = 0
+     for (ptr in allocated) {
+       if (allocated[ptr] == 1) {
+         print NR ": " what " " ptr
+         #allocated[ptr] = 0  # stop the dangle
+         nd++
+       }
+     }
+     if (nd > 0)  print NR ": count " what " " nd
+   }
+
+   /^[mfr]/ {
+       ptr = $2
+       a1 = ($1 == "m")? 1: 0
+       a0 = 0+allocated[ptr]
+       allocated[ptr] = a1
+       if (a0 + a1 != 1) {
+         if (a0 == 0 && a1 == 0)
+           print NR ": double free " ptr
+         else if (a0 == 1 && a1 == 1)
+           print NR ": double malloc " ptr
+         else
+           print NR ": oddity " $0
+       }
+       next
+     }
+
+   /^s/ {
+     checkleaks("suspended")
+     next
+   }
+
+   {
+     print NR ": unrecognized " $0
+   }
+   END {
+     checkleaks("leaked")
+   }
+'
+*/
+#endif // USE_MTRACE