8000489: older builds of hsdis don't work anymore after 6879063
authorminqi
Fri, 02 Nov 2012 13:30:47 -0700
changeset 14384 801df8025142
parent 14382 5e86124b835d
child 14387 ac54dac010f1
8000489: older builds of hsdis don't work anymore after 6879063 Summary: The old function not defined properly, need a definition for export in dll. Also changes made to let new jvm work with old hsdis. Reviewed-by: jrose, sspitsyn, kmo Contributed-by: yumin.qi@oracle.com
hotspot/src/share/tools/hsdis/hsdis-demo.c
hotspot/src/share/tools/hsdis/hsdis.c
hotspot/src/share/tools/hsdis/hsdis.h
hotspot/src/share/vm/compiler/disassembler.cpp
hotspot/src/share/vm/compiler/disassembler.hpp
--- a/hotspot/src/share/tools/hsdis/hsdis-demo.c	Fri Nov 02 07:44:11 2012 -0700
+++ b/hotspot/src/share/tools/hsdis/hsdis-demo.c	Fri Nov 02 13:30:47 2012 -0700
@@ -85,9 +85,11 @@
 
 #include "dlfcn.h"
 
-#define DECODE_INSTRUCTIONS_NAME "decode_instructions_virtual"
+#define DECODE_INSTRUCTIONS_VIRTUAL_NAME "decode_instructions_virtual"
+#define DECODE_INSTRUCTIONS_NAME "decode_instructions"
 #define HSDIS_NAME               "hsdis"
 static void* decode_instructions_pv = 0;
+static void* decode_instructions_sv = 0;
 static const char* hsdis_path[] = {
   HSDIS_NAME"-"LIBARCH LIB_EXT,
   "./" HSDIS_NAME"-"LIBARCH LIB_EXT,
@@ -101,11 +103,12 @@
   void* dllib = NULL;
   const char* *next_in_path = hsdis_path;
   while (1) {
-    decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);
-    if (decode_instructions_pv != NULL)
+    decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
+    decode_instructions_sv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME);
+    if (decode_instructions_pv != NULL || decode_instructions_sv != NULL)
       return NULL;
     if (dllib != NULL)
-      return "plugin does not defined "DECODE_INSTRUCTIONS_NAME;
+      return "plugin does not defined "DECODE_INSTRUCTIONS_VIRTUAL_NAME" and "DECODE_INSTRUCTIONS_NAME;
     for (dllib = NULL; dllib == NULL; ) {
       const char* next_lib = (*next_in_path++);
       if (next_lib == NULL)
@@ -213,20 +216,44 @@
     printf("%s: %s\n", err, dlerror());
     exit(1);
   }
-  printf("Decoding from %p to %p...\n", from, to);
-  decode_instructions_ftype decode_instructions
-    = (decode_instructions_ftype) decode_instructions_pv;
+  decode_func_vtype decode_instructions_v
+    = (decode_func_vtype) decode_instructions_pv;
+  decode_func_stype decode_instructions_s
+    = (decode_func_stype) decode_instructions_sv;
   void* res;
-  if (raw && xml) {
-    res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
-  } else if (raw) {
-    res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options);
-  } else {
-    res = (*decode_instructions)(from, to, (unsigned char*)from, to - from,
-                                 handle_event, (void*) event_cookie,
-                                 fprintf_callback, stdout,
-                                 options);
+  if (decode_instructions_pv != NULL) {
+    printf("\nDecoding from %p to %p...with %s\n", from, to, DECODE_INSTRUCTIONS_VIRTUAL_NAME);
+    if (raw) {
+      res = (*decode_instructions_v)(from, to,
+                                     (unsigned char*)from, to - from,
+                                     simple_handle_event, stdout,
+                                     NULL, stdout,
+                                     options, 0);
+    } else {
+      res = (*decode_instructions_v)(from, to,
+                                    (unsigned char*)from, to - from,
+                                     handle_event, (void*) event_cookie,
+                                     fprintf_callback, stdout,
+                                     options, 0);
+    }
+    if (res != (void*)to)
+      printf("*** Result was %p!\n", res);
   }
-  if (res != (void*)to)
-    printf("*** Result was %p!\n", res);
+  void* sres;
+  if (decode_instructions_sv != NULL) {
+    printf("\nDecoding from %p to %p...with old decode_instructions\n", from, to, DECODE_INSTRUCTIONS_NAME);
+    if (raw) {
+      sres = (*decode_instructions_s)(from, to,
+                                      simple_handle_event, stdout,
+                                      NULL, stdout,
+                                      options);
+    } else {
+      sres = (*decode_instructions_s)(from, to,
+                                      handle_event, (void*) event_cookie,
+                                      fprintf_callback, stdout,
+                                      options);
+    }
+    if (sres != (void *)to)
+      printf("*** Result of decode_instructions %p!\n", sres);
+  }
 }
--- a/hotspot/src/share/tools/hsdis/hsdis.c	Fri Nov 02 07:44:11 2012 -0700
+++ b/hotspot/src/share/tools/hsdis/hsdis.c	Fri Nov 02 13:30:47 2012 -0700
@@ -99,7 +99,7 @@
                             unsigned char* buffer, uintptr_t length,
                             event_callback_t  event_callback_arg,  void* event_stream_arg,
                             printf_callback_t printf_callback_arg, void* printf_stream_arg,
-                            const char* options) {
+                            const char* options, int newline) {
   struct hsdis_app_data app_data;
   memset(&app_data, 0, sizeof(app_data));
   app_data.start_va    = start_va;
@@ -110,7 +110,7 @@
   app_data.event_stream    = event_stream_arg;
   app_data.printf_callback = printf_callback_arg;
   app_data.printf_stream   = printf_stream_arg;
-  app_data.do_newline = false;
+  app_data.do_newline = newline == 0 ? false : true;
 
   return decode(&app_data, options);
 }
@@ -132,7 +132,7 @@
                              event_stream_arg,
                              printf_callback_arg,
                              printf_stream_arg,
-                             options);
+                             options, false);
 }
 
 static void* decode(struct hsdis_app_data* app_data, const char* options) {
@@ -173,7 +173,7 @@
       if (!app_data->losing) {
         const char* insn_close = format_insn_close("/insn", &app_data->dinfo,
                                                    buf, sizeof(buf));
-        (*event_callback)(event_stream, insn_close, (void*) p) != NULL;
+        (*event_callback)(event_stream, insn_close, (void*) p);
 
         if (app_data->do_newline) {
           /* follow each complete insn by a nice newline */
@@ -182,13 +182,14 @@
       }
     }
 
-    (*event_callback)(event_stream, "/insns", (void*) p);
+    if (app_data->losing) (*event_callback)(event_stream, "/insns", (void*) p);
     return (void*) p;
   }
 }
 
 /* take the address of the function, for luck, and also test the typedef: */
-const decode_instructions_ftype decode_instructions_address = &decode_instructions_virtual;
+const decode_func_vtype decode_func_virtual_address = &decode_instructions_virtual;
+const decode_func_stype decode_func_address = &decode_instructions;
 
 static const char* format_insn_close(const char* close,
                                      disassemble_info* dinfo,
--- a/hotspot/src/share/tools/hsdis/hsdis.h	Fri Nov 02 07:44:11 2012 -0700
+++ b/hotspot/src/share/tools/hsdis/hsdis.h	Fri Nov 02 13:30:47 2012 -0700
@@ -47,6 +47,9 @@
    where tag is a simple identifier, signifying (as in XML) a element start,
    element end, and standalone element.  (To render as XML, add angle brackets.)
 */
+#ifndef SHARED_TOOLS_HSDIS_H
+#define SHARED_TOOLS_HSDIS_H
+
 extern
 #ifdef DLL_EXPORT
   DLL_EXPORT
@@ -57,16 +60,37 @@
                                   void* event_stream,
                                   int (*printf_callback)(void*, const char*, ...),
                                   void* printf_stream,
-                                  const char* options);
+                                  const char* options,
+                                  int newline /* bool value for nice new line */);
+
+/* This is the compatability interface for older versions of hotspot */
+extern
+#ifdef DLL_ENTRY
+  DLL_ENTRY
+#endif
+void* decode_instructions(void* start_pv, void* end_pv,
+                    void* (*event_callback)(void*, const char*, void*),
+                    void* event_stream,
+                    int   (*printf_callback)(void*, const char*, ...),
+                    void* printf_stream,
+                    const char* options);
 
 /* convenience typedefs */
 
 typedef void* (*decode_instructions_event_callback_ftype)  (void*, const char*, void*);
 typedef int   (*decode_instructions_printf_callback_ftype) (void*, const char*, ...);
-typedef void* (*decode_instructions_ftype) (uintptr_t start_va, uintptr_t end_va,
-                                            unsigned char* buffer, uintptr_t length,
-                                            decode_instructions_event_callback_ftype event_callback,
-                                            void* event_stream,
-                                            decode_instructions_printf_callback_ftype printf_callback,
-                                            void* printf_stream,
-                                            const char* options);
+typedef void* (*decode_func_vtype) (uintptr_t start_va, uintptr_t end_va,
+                                    unsigned char* buffer, uintptr_t length,
+                                    decode_instructions_event_callback_ftype event_callback,
+                                    void* event_stream,
+                                    decode_instructions_printf_callback_ftype printf_callback,
+                                    void* printf_stream,
+                                    const char* options,
+                                    int newline);
+typedef void* (*decode_func_stype) (void* start_pv, void* end_pv,
+                                    decode_instructions_event_callback_ftype event_callback,
+                                    void* event_stream,
+                                    decode_instructions_printf_callback_ftype printf_callback,
+                                    void* printf_stream,
+                                    const char* options);
+#endif /* SHARED_TOOLS_HSDIS_H */
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Fri Nov 02 07:44:11 2012 -0700
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Fri Nov 02 13:30:47 2012 -0700
@@ -55,16 +55,18 @@
 bool        Disassembler::_tried_to_load_library = false;
 
 // This routine is in the shared library:
+Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL;
 Disassembler::decode_func Disassembler::_decode_instructions = NULL;
 
 static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH;
-static const char decode_instructions_name[] = "decode_instructions_virtual";
-
+static const char decode_instructions_virtual_name[] = "decode_instructions_virtual";
+static const char decode_instructions_name[] = "decode_instructions";
+static bool use_new_version = true;
 #define COMMENT_COLUMN  40 LP64_ONLY(+8) /*could be an option*/
 #define BYTES_COMMENT   ";..."  /* funky byte display comment */
 
 bool Disassembler::load_library() {
-  if (_decode_instructions != NULL) {
+  if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) {
     // Already succeeded.
     return true;
   }
@@ -123,11 +125,19 @@
     _library = os::dll_load(buf, ebuf, sizeof ebuf);
   }
   if (_library != NULL) {
+    _decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual,
+                                          os::dll_lookup(_library, decode_instructions_virtual_name));
+  }
+  if (_decode_instructions_virtual == NULL) {
+    // could not spot in new version, try old version
     _decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func,
                                           os::dll_lookup(_library, decode_instructions_name));
+    use_new_version = false;
+  } else {
+    use_new_version = true;
   }
   _tried_to_load_library = true;
-  if (_decode_instructions == NULL) {
+  if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) {
     tty->print_cr("Could not load %s; %s; %s", buf,
                   ((_library != NULL)
                    ? "entry point is missing"
@@ -450,17 +460,31 @@
     // This is mainly for debugging the library itself.
     FILE* out = stdout;
     FILE* xmlout = (_print_raw > 1 ? out : NULL);
-    return (address)
-      (*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end,
-                                            start, end - start,
+    return use_new_version ?
+      (address)
+      (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
+                                                    start, end - start,
+                                                    NULL, (void*) xmlout,
+                                                    NULL, (void*) out,
+                                                    options(), 0/*nice new line*/)
+      :
+      (address)
+      (*Disassembler::_decode_instructions)(start, end,
                                             NULL, (void*) xmlout,
                                             NULL, (void*) out,
                                             options());
   }
 
-  return (address)
-    (*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end,
-                                          start, end - start,
+  return use_new_version ?
+    (address)
+    (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
+                                                  start, end - start,
+                                                  &event_to_env,  (void*) this,
+                                                  &printf_to_env, (void*) this,
+                                                  options(), 0/*nice new line*/)
+    :
+    (address)
+    (*Disassembler::_decode_instructions)(start, end,
                                           &event_to_env,  (void*) this,
                                           &printf_to_env, (void*) this,
                                           options());
--- a/hotspot/src/share/vm/compiler/disassembler.hpp	Fri Nov 02 07:44:11 2012 -0700
+++ b/hotspot/src/share/vm/compiler/disassembler.hpp	Fri Nov 02 13:30:47 2012 -0700
@@ -49,18 +49,27 @@
   friend class decode_env;
  private:
   // this is the type of the dll entry point:
-  typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va,
+  typedef void* (*decode_func_virtual)(uintptr_t start_va, uintptr_t end_va,
                                unsigned char* buffer, uintptr_t length,
                                void* (*event_callback)(void*, const char*, void*),
                                void* event_stream,
                                int (*printf_callback)(void*, const char*, ...),
                                void* printf_stream,
+                               const char* options,
+                               int newline);
+  // this is the type of the dll entry point for old version:
+  typedef void* (*decode_func)(void* start_va, void* end_va,
+                               void* (*event_callback)(void*, const char*, void*),
+                               void* event_stream,
+                               int (*printf_callback)(void*, const char*, ...),
+                               void* printf_stream,
                                const char* options);
   // points to the library.
   static void*    _library;
   // bailout
   static bool     _tried_to_load_library;
   // points to the decode function.
+  static decode_func_virtual _decode_instructions_virtual;
   static decode_func _decode_instructions;
   // tries to load library and return whether it succedded.
   static bool load_library();
@@ -85,7 +94,9 @@
 
  public:
   static bool can_decode() {
-    return (_decode_instructions != NULL) || load_library();
+    return (_decode_instructions_virtual != NULL) ||
+           (_decode_instructions != NULL) ||
+           load_library();
   }
   static void decode(CodeBlob *cb,               outputStream* st = NULL);
   static void decode(nmethod* nm,                outputStream* st = NULL);