7071311: Decoder enhancement

Tue, 17 Jan 2012 13:08:52 -0500

author
zgu
date
Tue, 17 Jan 2012 13:08:52 -0500
changeset 3430
d7e3846464d0
parent 3428
4f3ce9284781
child 3431
6520f9861937

7071311: Decoder enhancement
Summary: Made decoder thread-safe
Reviewed-by: coleenp, kamg

src/os/bsd/vm/decoder_bsd.cpp file | annotate | diff | comparison | revisions
src/os/bsd/vm/decoder_machO.cpp file | annotate | diff | comparison | revisions
src/os/bsd/vm/decoder_machO.hpp file | annotate | diff | comparison | revisions
src/os/linux/vm/decoder_linux.cpp file | annotate | diff | comparison | revisions
src/os/linux/vm/os_linux.cpp file | annotate | diff | comparison | revisions
src/os/solaris/vm/decoder_solaris.cpp file | annotate | diff | comparison | revisions
src/os/solaris/vm/os_solaris.cpp file | annotate | diff | comparison | revisions
src/os/windows/vm/decoder_windows.cpp file | annotate | diff | comparison | revisions
src/os/windows/vm/decoder_windows.hpp file | annotate | diff | comparison | revisions
src/os/windows/vm/os_windows.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/decoder.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/decoder.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/decoder_elf.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/decoder_elf.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/elfFile.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/elfFile.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/elfStringTable.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/elfStringTable.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/elfSymbolTable.cpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/elfSymbolTable.hpp file | annotate | diff | comparison | revisions
src/share/vm/utilities/vmError.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/os/bsd/vm/decoder_bsd.cpp	Wed Jan 11 17:58:26 2012 -0500
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,66 +0,0 @@
     1.4 -/*
     1.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 - *
     1.8 - * This code is free software; you can redistribute it and/or modify it
     1.9 - * under the terms of the GNU General Public License version 2 only, as
    1.10 - * published by the Free Software Foundation.
    1.11 - *
    1.12 - * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 - * version 2 for more details (a copy is included in the LICENSE file that
    1.16 - * accompanied this code).
    1.17 - *
    1.18 - * You should have received a copy of the GNU General Public License version
    1.19 - * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 - *
    1.22 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 - * or visit www.oracle.com if you need additional information or have any
    1.24 - * questions.
    1.25 - *
    1.26 - */
    1.27 -
    1.28 -#include "prims/jvm.h"
    1.29 -#include "utilities/decoder.hpp"
    1.30 -
    1.31 -#include <cxxabi.h>
    1.32 -
    1.33 -#ifdef __APPLE__
    1.34 -
    1.35 -void Decoder::initialize() {
    1.36 -  _initialized = true;
    1.37 -}
    1.38 -
    1.39 -void Decoder::uninitialize() {
    1.40 -  _initialized = false;
    1.41 -}
    1.42 -
    1.43 -bool Decoder::can_decode_C_frame_in_vm() {
    1.44 -  return false;
    1.45 -}
    1.46 -
    1.47 -Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
    1.48 -  return symbol_not_found;
    1.49 -}
    1.50 -
    1.51 -
    1.52 -#endif
    1.53 -
    1.54 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
    1.55 -  int   status;
    1.56 -  char* result;
    1.57 -  size_t size = (size_t)buflen;
    1.58 -
    1.59 -  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
    1.60 -  // __cxa_demangle will call system "realloc" for additional memory, which
    1.61 -  // may use different malloc/realloc mechanism that allocates 'buf'.
    1.62 -  if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
    1.63 -    jio_snprintf(buf, buflen, "%s", result);
    1.64 -      // call c library's free
    1.65 -      ::free(result);
    1.66 -      return true;
    1.67 -  }
    1.68 -  return false;
    1.69 -}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/os/bsd/vm/decoder_machO.cpp	Tue Jan 17 13:08:52 2012 -0500
     2.3 @@ -0,0 +1,31 @@
     2.4 +/*
     2.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.
    2.11 + *
    2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.15 + * version 2 for more details (a copy is included in the LICENSE file that
    2.16 + * accompanied this code).
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License version
    2.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.21 + *
    2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.23 + * or visit www.oracle.com if you need additional information or have any
    2.24 + * questions.
    2.25 + *
    2.26 + */
    2.27 +
    2.28 +#include "precompiled.hpp"
    2.29 +
    2.30 +#ifdef __APPLE__
    2.31 +#include "decoder_machO.hpp"
    2.32 +#endif
    2.33 +
    2.34 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/os/bsd/vm/decoder_machO.hpp	Tue Jan 17 13:08:52 2012 -0500
     3.3 @@ -0,0 +1,42 @@
     3.4 +/*
     3.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.7 + *
     3.8 + * This code is free software; you can redistribute it and/or modify it
     3.9 + * under the terms of the GNU General Public License version 2 only, as
    3.10 + * published by the Free Software Foundation.
    3.11 + *
    3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.15 + * version 2 for more details (a copy is included in the LICENSE file that
    3.16 + * accompanied this code).
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License version
    3.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    3.21 + *
    3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    3.23 + * or visit www.oracle.com if you need additional information or have any
    3.24 + * questions.
    3.25 + *
    3.26 + */
    3.27 +
    3.28 +#ifndef OS_BSD_VM_DECODER_MACHO_HPP
    3.29 +#define OS_BSD_VM_DECODER_MACHO_HPP
    3.30 +
    3.31 +#ifdef __APPLE__
    3.32 +
    3.33 +#include "utilities/decoder.hpp"
    3.34 +
    3.35 +// Just a placehold for now
    3.36 +class MachODecoder: public NullDecoder {
    3.37 +public:
    3.38 +  MachODecoder() { }
    3.39 +  ~MachODecoder() { }
    3.40 +};
    3.41 +
    3.42 +#endif
    3.43 +
    3.44 +#endif // OS_BSD_VM_DECODER_MACHO_HPP
    3.45 +
     4.1 --- a/src/os/linux/vm/decoder_linux.cpp	Wed Jan 11 17:58:26 2012 -0500
     4.2 +++ b/src/os/linux/vm/decoder_linux.cpp	Tue Jan 17 13:08:52 2012 -0500
     4.3 @@ -23,11 +23,11 @@
     4.4   */
     4.5  
     4.6  #include "prims/jvm.h"
     4.7 -#include "utilities/decoder.hpp"
     4.8 +#include "utilities/decoder_elf.hpp"
     4.9  
    4.10  #include <cxxabi.h>
    4.11  
    4.12 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
    4.13 +bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
    4.14    int   status;
    4.15    char* result;
    4.16    size_t size = (size_t)buflen;
    4.17 @@ -43,3 +43,4 @@
    4.18    }
    4.19    return false;
    4.20  }
    4.21 +
     5.1 --- a/src/os/linux/vm/os_linux.cpp	Wed Jan 11 17:58:26 2012 -0500
     5.2 +++ b/src/os/linux/vm/os_linux.cpp	Tue Jan 17 13:08:52 2012 -0500
     5.3 @@ -1732,7 +1732,7 @@
     5.4      return true;
     5.5    } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
     5.6      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
     5.7 -       dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
     5.8 +        buf, buflen, offset, dlinfo.dli_fname)) {
     5.9         return true;
    5.10      }
    5.11    }
     6.1 --- a/src/os/solaris/vm/decoder_solaris.cpp	Wed Jan 11 17:58:26 2012 -0500
     6.2 +++ b/src/os/solaris/vm/decoder_solaris.cpp	Tue Jan 17 13:08:52 2012 -0500
     6.3 @@ -22,10 +22,11 @@
     6.4   *
     6.5   */
     6.6  
     6.7 -#include "utilities/decoder.hpp"
     6.8 +#include "utilities/decoder_elf.hpp"
     6.9  
    6.10  #include <demangle.h>
    6.11  
    6.12 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
    6.13 +bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
    6.14    return !cplus_demangle(symbol, buf, (size_t)buflen);
    6.15  }
    6.16 +
     7.1 --- a/src/os/solaris/vm/os_solaris.cpp	Wed Jan 11 17:58:26 2012 -0500
     7.2 +++ b/src/os/solaris/vm/os_solaris.cpp	Tue Jan 17 13:08:52 2012 -0500
     7.3 @@ -1997,7 +1997,7 @@
     7.4        }
     7.5        if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
     7.6          if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
     7.7 -          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
     7.8 +           buf, buflen, offset, dlinfo.dli_fname)) {
     7.9            return true;
    7.10          }
    7.11        }
    7.12 @@ -2015,7 +2015,7 @@
    7.13          return true;
    7.14        } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    7.15          if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    7.16 -          dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
    7.17 +          buf, buflen, offset, dlinfo.dli_fname)) {
    7.18            return true;
    7.19          }
    7.20        }
     8.1 --- a/src/os/windows/vm/decoder_windows.cpp	Wed Jan 11 17:58:26 2012 -0500
     8.2 +++ b/src/os/windows/vm/decoder_windows.cpp	Tue Jan 17 13:08:52 2012 -0500
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -24,22 +24,24 @@
    8.11  
    8.12  #include "precompiled.hpp"
    8.13  #include "prims/jvm.h"
    8.14 -#include "runtime/os.hpp"
    8.15 -#include "utilities/decoder.hpp"
    8.16 +#include "decoder_windows.hpp"
    8.17  
    8.18 -HMODULE                   Decoder::_dbghelp_handle = NULL;
    8.19 -bool                      Decoder::_can_decode_in_vm = false;
    8.20 -pfn_SymGetSymFromAddr64   Decoder::_pfnSymGetSymFromAddr64 = NULL;
    8.21 -pfn_UndecorateSymbolName  Decoder::_pfnUndecorateSymbolName = NULL;
    8.22 +WindowsDecoder::WindowsDecoder() {
    8.23 +  _dbghelp_handle = NULL;
    8.24 +  _can_decode_in_vm = false;
    8.25 +  _pfnSymGetSymFromAddr64 = NULL;
    8.26 +  _pfnUndecorateSymbolName = NULL;
    8.27  
    8.28 -void Decoder::initialize() {
    8.29 -  if (!_initialized) {
    8.30 -    _initialized = true;
    8.31 +  _decoder_status = no_error;
    8.32 +  initialize();
    8.33 +}
    8.34  
    8.35 -    HINSTANCE handle = os::win32::load_Windows_dll("dbghelp.dll", NULL, 0);
    8.36 +void WindowsDecoder::initialize() {
    8.37 +  if (!has_error() && _dbghelp_handle == NULL) {
    8.38 +    HMODULE handle = ::LoadLibrary("dbghelp.dll");
    8.39      if (!handle) {
    8.40        _decoder_status = helper_not_found;
    8.41 -        return;
    8.42 +      return;
    8.43      }
    8.44  
    8.45      _dbghelp_handle = handle;
    8.46 @@ -70,32 +72,29 @@
    8.47  
    8.48       // find out if jvm.dll contains private symbols, by decoding
    8.49       // current function and comparing the result
    8.50 -     address addr = (address)Decoder::initialize;
    8.51 +     address addr = (address)Decoder::decode;
    8.52       char buf[MAX_PATH];
    8.53 -     if (decode(addr, buf, sizeof(buf), NULL) == no_error) {
    8.54 -       _can_decode_in_vm = !strcmp(buf, "Decoder::initialize");
    8.55 +     if (decode(addr, buf, sizeof(buf), NULL)) {
    8.56 +       _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
    8.57       }
    8.58    }
    8.59  }
    8.60  
    8.61 -void Decoder::uninitialize() {
    8.62 -  assert(_initialized, "Decoder not yet initialized");
    8.63 +void WindowsDecoder::uninitialize() {
    8.64    _pfnSymGetSymFromAddr64 = NULL;
    8.65    _pfnUndecorateSymbolName = NULL;
    8.66    if (_dbghelp_handle != NULL) {
    8.67      ::FreeLibrary(_dbghelp_handle);
    8.68    }
    8.69 -  _initialized = false;
    8.70 +  _dbghelp_handle = NULL;
    8.71  }
    8.72  
    8.73 -bool Decoder::can_decode_C_frame_in_vm() {
    8.74 -  initialize();
    8.75 -  return  _can_decode_in_vm;
    8.76 +bool WindowsDecoder::can_decode_C_frame_in_vm() const {
    8.77 +  return  (!has_error() && _can_decode_in_vm);
    8.78  }
    8.79  
    8.80  
    8.81 -Decoder::decoder_status Decoder::decode(address addr, char *buf, int buflen, int *offset) {
    8.82 -  assert(_initialized, "Decoder not yet initialized");
    8.83 +bool WindowsDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* modulepath)  {
    8.84    if (_pfnSymGetSymFromAddr64 != NULL) {
    8.85      PIMAGEHLP_SYMBOL64 pSymbol;
    8.86      char symbolInfo[MAX_PATH + sizeof(IMAGEHLP_SYMBOL64)];
    8.87 @@ -105,19 +104,20 @@
    8.88      DWORD64 displacement;
    8.89      if (_pfnSymGetSymFromAddr64(::GetCurrentProcess(), (DWORD64)addr, &displacement, pSymbol)) {
    8.90        if (buf != NULL) {
    8.91 -        if (!demangle(pSymbol->Name, buf, buflen)) {
    8.92 +        if (demangle(pSymbol->Name, buf, buflen)) {
    8.93            jio_snprintf(buf, buflen, "%s", pSymbol->Name);
    8.94          }
    8.95        }
    8.96 -      if (offset != NULL) *offset = (int)displacement;
    8.97 -      return no_error;
    8.98 +      if(offset != NULL) *offset = (int)displacement;
    8.99 +      return true;
   8.100      }
   8.101    }
   8.102 -  return helper_not_found;
   8.103 +  if (buf != NULL && buflen > 0) buf[0] = '\0';
   8.104 +  if (offset != NULL) *offset = -1;
   8.105 +  return false;
   8.106  }
   8.107  
   8.108 -bool Decoder::demangle(const char* symbol, char *buf, int buflen) {
   8.109 -  assert(_initialized, "Decoder not yet initialized");
   8.110 +bool WindowsDecoder::demangle(const char* symbol, char *buf, int buflen) {
   8.111    return _pfnUndecorateSymbolName != NULL &&
   8.112           _pfnUndecorateSymbolName(symbol, buf, buflen, UNDNAME_COMPLETE);
   8.113  }
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/os/windows/vm/decoder_windows.hpp	Tue Jan 17 13:08:52 2012 -0500
     9.3 @@ -0,0 +1,61 @@
     9.4 +/*
     9.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
     9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.7 + *
     9.8 + * This code is free software; you can redistribute it and/or modify it
     9.9 + * under the terms of the GNU General Public License version 2 only, as
    9.10 + * published by the Free Software Foundation.
    9.11 + *
    9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    9.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    9.15 + * version 2 for more details (a copy is included in the LICENSE file that
    9.16 + * accompanied this code).
    9.17 + *
    9.18 + * You should have received a copy of the GNU General Public License version
    9.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    9.21 + *
    9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    9.23 + * or visit www.oracle.com if you need additional information or have any
    9.24 + * questions.
    9.25 + *
    9.26 + */
    9.27 +
    9.28 +#ifndef OS_WINDOWS_VM_DECODER_WINDOWS_HPP
    9.29 +#define OS_WINDOWS_VM_DECIDER_WINDOWS_HPP
    9.30 +
    9.31 +#include <windows.h>
    9.32 +#include <imagehlp.h>
    9.33 +
    9.34 +#include "utilities/decoder.hpp"
    9.35 +
    9.36 +// functions needed for decoding symbols
    9.37 +typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
    9.38 +typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
    9.39 +typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
    9.40 +typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
    9.41 +
    9.42 +class WindowsDecoder: public NullDecoder {
    9.43 +
    9.44 +public:
    9.45 +  WindowsDecoder();
    9.46 +  ~WindowsDecoder() { uninitialize(); };
    9.47 +
    9.48 +  bool can_decode_C_frame_in_vm() const;
    9.49 +  bool demangle(const char* symbol, char *buf, int buflen);
    9.50 +  bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath = NULL);
    9.51 +
    9.52 +private:
    9.53 +  void initialize();
    9.54 +  void uninitialize();
    9.55 +
    9.56 +private:
    9.57 +  HMODULE                   _dbghelp_handle;
    9.58 +  bool                      _can_decode_in_vm;
    9.59 +  pfn_SymGetSymFromAddr64   _pfnSymGetSymFromAddr64;
    9.60 +  pfn_UndecorateSymbolName  _pfnUndecorateSymbolName;
    9.61 +};
    9.62 +
    9.63 +#endif // OS_WINDOWS_VM_DECODER_WINDOWS_HPP
    9.64 +
    10.1 --- a/src/os/windows/vm/os_windows.cpp	Wed Jan 11 17:58:26 2012 -0500
    10.2 +++ b/src/os/windows/vm/os_windows.cpp	Tue Jan 17 13:08:52 2012 -0500
    10.3 @@ -1391,7 +1391,7 @@
    10.4  
    10.5  bool os::dll_address_to_function_name(address addr, char *buf,
    10.6                                        int buflen, int *offset) {
    10.7 -  if (Decoder::decode(addr, buf, buflen, offset) == Decoder::no_error) {
    10.8 +  if (Decoder::decode(addr, buf, buflen, offset)) {
    10.9      return true;
   10.10    }
   10.11    if (offset != NULL)  *offset  = -1;
    11.1 --- a/src/share/vm/utilities/decoder.cpp	Wed Jan 11 17:58:26 2012 -0500
    11.2 +++ b/src/share/vm/utilities/decoder.cpp	Tue Jan 17 13:08:52 2012 -0500
    11.3 @@ -24,80 +24,85 @@
    11.4  
    11.5  #include "precompiled.hpp"
    11.6  #include "prims/jvm.h"
    11.7 +#include "runtime/mutexLocker.hpp"
    11.8  #include "utilities/decoder.hpp"
    11.9  
   11.10 -Decoder::decoder_status  Decoder::_decoder_status = Decoder::no_error;
   11.11 -bool                     Decoder::_initialized = false;
   11.12 +#if defined(_WINDOWS)
   11.13 +  #include "decoder_windows.hpp"
   11.14 +#elif defined(__APPLE__)
   11.15 +  #include "decoder_machO.hpp"
   11.16 +#else
   11.17 +  #include "decoder_elf.hpp"
   11.18 +#endif
   11.19  
   11.20 -#if !defined(_WINDOWS) && !defined(__APPLE__)
   11.21 +NullDecoder*  Decoder::_decoder = NULL;
   11.22 +NullDecoder   Decoder::_do_nothing_decoder;
   11.23 +Mutex*           Decoder::_decoder_lock = new Mutex(Mutex::safepoint,
   11.24 +                                "DecoderLock");
   11.25  
   11.26 -// Implementation of common functionalities among Solaris and Linux
   11.27 -#include "utilities/elfFile.hpp"
   11.28 +// _decoder_lock should already acquired before enter this method
   11.29 +NullDecoder* Decoder::get_decoder() {
   11.30 +  assert(_decoder_lock != NULL && _decoder_lock->owned_by_self(),
   11.31 +    "Require DecoderLock to enter");
   11.32  
   11.33 -ElfFile* Decoder::_opened_elf_files = NULL;
   11.34 +  if (_decoder != NULL) {
   11.35 +    return _decoder;
   11.36 +  }
   11.37 +
   11.38 +  // Decoder is a secondary service. Although, it is good to have,
   11.39 +  // but we can live without it.
   11.40 +#if defined(_WINDOWS)
   11.41 +  _decoder = new (std::nothrow) WindowsDecoder();
   11.42 +#elif defined (__APPLE__)
   11.43 +    _decoder = new (std::nothrow)MachODecoder();
   11.44 +#else
   11.45 +    _decoder = new (std::nothrow)ElfDecoder();
   11.46 +#endif
   11.47 +
   11.48 +  if (_decoder == NULL || _decoder->has_error()) {
   11.49 +    if (_decoder != NULL) {
   11.50 +      delete _decoder;
   11.51 +    }
   11.52 +    _decoder = &_do_nothing_decoder;
   11.53 +  }
   11.54 +  return _decoder;
   11.55 +}
   11.56 +
   11.57 +bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const char* modulepath) {
   11.58 +  assert(_decoder_lock != NULL, "Just check");
   11.59 +  MutexLockerEx locker(_decoder_lock, true);
   11.60 +  NullDecoder* decoder = get_decoder();
   11.61 +  assert(decoder != NULL, "null decoder");
   11.62 +
   11.63 +  return decoder->decode(addr, buf, buflen, offset, modulepath);
   11.64 +}
   11.65 +
   11.66 +bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
   11.67 +  assert(_decoder_lock != NULL, "Just check");
   11.68 +  MutexLockerEx locker(_decoder_lock, true);
   11.69 +  NullDecoder* decoder = get_decoder();
   11.70 +  assert(decoder != NULL, "null decoder");
   11.71 +  return decoder->demangle(symbol, buf, buflen);
   11.72 +}
   11.73  
   11.74  bool Decoder::can_decode_C_frame_in_vm() {
   11.75 -  return true;
   11.76 +  assert(_decoder_lock != NULL, "Just check");
   11.77 +  MutexLockerEx locker(_decoder_lock, true);
   11.78 +  NullDecoder* decoder = get_decoder();
   11.79 +  assert(decoder != NULL, "null decoder");
   11.80 +  return decoder->can_decode_C_frame_in_vm();
   11.81  }
   11.82  
   11.83 -void Decoder::initialize() {
   11.84 -  _initialized = true;
   11.85 +// shutdown real decoder and replace it with
   11.86 +// _do_nothing_decoder
   11.87 +void Decoder::shutdown() {
   11.88 +  assert(_decoder_lock != NULL, "Just check");
   11.89 +  MutexLockerEx locker(_decoder_lock, true);
   11.90 +
   11.91 +  if (_decoder != NULL && _decoder != &_do_nothing_decoder) {
   11.92 +    delete _decoder;
   11.93 +  }
   11.94 +
   11.95 +  _decoder = &_do_nothing_decoder;
   11.96  }
   11.97  
   11.98 -void Decoder::uninitialize() {
   11.99 -  if (_opened_elf_files != NULL) {
  11.100 -    delete _opened_elf_files;
  11.101 -    _opened_elf_files = NULL;
  11.102 -  }
  11.103 -  _initialized = false;
  11.104 -}
  11.105 -
  11.106 -Decoder::decoder_status Decoder::decode(address addr, const char* filepath, char *buf, int buflen, int *offset) {
  11.107 -  if (_decoder_status != no_error) {
  11.108 -    return _decoder_status;
  11.109 -  }
  11.110 -
  11.111 -  ElfFile* file = get_elf_file(filepath);
  11.112 -  if (_decoder_status != no_error) {
  11.113 -    return _decoder_status;
  11.114 -  }
  11.115 -
  11.116 -  const char* symbol = file->decode(addr, offset);
  11.117 -  if (file->get_status() == out_of_memory) {
  11.118 -    _decoder_status = out_of_memory;
  11.119 -    return _decoder_status;
  11.120 -  } else if (symbol != NULL) {
  11.121 -    if (!demangle(symbol, buf, buflen)) {
  11.122 -      jio_snprintf(buf, buflen, "%s", symbol);
  11.123 -    }
  11.124 -    return no_error;
  11.125 -  } else {
  11.126 -    return symbol_not_found;
  11.127 -  }
  11.128 -}
  11.129 -
  11.130 -ElfFile* Decoder::get_elf_file(const char* filepath) {
  11.131 -  if (_decoder_status != no_error) {
  11.132 -    return NULL;
  11.133 -  }
  11.134 -  ElfFile* file = _opened_elf_files;
  11.135 -  while (file != NULL) {
  11.136 -    if (file->same_elf_file(filepath)) {
  11.137 -      return file;
  11.138 -    }
  11.139 -    file = file->m_next;
  11.140 -  }
  11.141 -
  11.142 -  file = new ElfFile(filepath);
  11.143 -  if (file == NULL) {
  11.144 -    _decoder_status = out_of_memory;
  11.145 -  }
  11.146 -  if (_opened_elf_files != NULL) {
  11.147 -    file->m_next = _opened_elf_files;
  11.148 -  }
  11.149 -
  11.150 -  _opened_elf_files = file;
  11.151 -  return file;
  11.152 -}
  11.153 -
  11.154 -#endif
    12.1 --- a/src/share/vm/utilities/decoder.hpp	Wed Jan 11 17:58:26 2012 -0500
    12.2 +++ b/src/share/vm/utilities/decoder.hpp	Tue Jan 17 13:08:52 2012 -0500
    12.3 @@ -1,5 +1,5 @@
    12.4  /*
    12.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    12.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    12.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.8   *
    12.9   * This code is free software; you can redistribute it and/or modify it
   12.10 @@ -23,83 +23,78 @@
   12.11   */
   12.12  
   12.13  
   12.14 -#ifndef __DECODER_HPP
   12.15 -#define __DECODER_HPP
   12.16 +#ifndef SHARE_VM_UTILITIES_DECODER_HPP
   12.17 +#define SHARE_VM_UTILITIES_DECODER_HPP
   12.18  
   12.19  #include "memory/allocation.hpp"
   12.20 +#include "runtime/mutex.hpp"
   12.21  
   12.22 -#ifdef _WINDOWS
   12.23 -#include <windows.h>
   12.24 -#include <imagehlp.h>
   12.25 -
   12.26 -// functions needed for decoding symbols
   12.27 -typedef DWORD (WINAPI *pfn_SymSetOptions)(DWORD);
   12.28 -typedef BOOL  (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
   12.29 -typedef BOOL  (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
   12.30 -typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
   12.31 -
   12.32 -#elif defined(__APPLE__)
   12.33 -
   12.34 -#else
   12.35 -
   12.36 -class ElfFile;
   12.37 -
   12.38 -#endif // _WINDOWS
   12.39 -
   12.40 -
   12.41 -class Decoder: public StackObj {
   12.42 -
   12.43 - public:
   12.44 +class NullDecoder: public CHeapObj {
   12.45 +public:
   12.46    // status code for decoding native C frame
   12.47    enum decoder_status {
   12.48 -         no_error,             // successfully decoded frames
   12.49 +         not_available = -10,  // real decoder is not available
   12.50 +         no_error = 0,         // successfully decoded frames
   12.51           out_of_memory,        // out of memory
   12.52           file_invalid,         // invalid elf file
   12.53           file_not_found,       // could not found symbol file (on windows), such as jvm.pdb or jvm.map
   12.54           helper_not_found,     // could not load dbghelp.dll (Windows only)
   12.55           helper_func_error,    // decoding functions not found (Windows only)
   12.56 -         helper_init_error,    // SymInitialize failed (Windows only)
   12.57 -         symbol_not_found      // could not find the symbol
   12.58 +         helper_init_error     // SymInitialize failed (Windows only)
   12.59    };
   12.60  
   12.61 - public:
   12.62 -  Decoder() { initialize(); };
   12.63 -  ~Decoder() { uninitialize(); };
   12.64 +  NullDecoder() {
   12.65 +    _decoder_status = not_available;
   12.66 +  }
   12.67  
   12.68 +  ~NullDecoder() {};
   12.69 +
   12.70 +  virtual bool decode(address pc, char* buf, int buflen, int* offset,
   12.71 +    const char* modulepath = NULL) {
   12.72 +    return false;
   12.73 +  }
   12.74 +
   12.75 +  virtual bool demangle(const char* symbol, char* buf, int buflen) {
   12.76 +    return false;
   12.77 +  }
   12.78 +
   12.79 +  virtual bool can_decode_C_frame_in_vm() const {
   12.80 +    return false;
   12.81 +  }
   12.82 +
   12.83 +  virtual decoder_status status() const {
   12.84 +    return _decoder_status;
   12.85 +  }
   12.86 +
   12.87 +  virtual bool has_error() const {
   12.88 +    return is_error(_decoder_status);
   12.89 +  }
   12.90 +
   12.91 +  static bool is_error(decoder_status status) {
   12.92 +    return (status > 0);
   12.93 +  }
   12.94 +
   12.95 +protected:
   12.96 +  decoder_status  _decoder_status;
   12.97 +};
   12.98 +
   12.99 +
  12.100 +class Decoder: AllStatic {
  12.101 +public:
  12.102 +  static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
  12.103 +  static bool demangle(const char* symbol, char* buf, int buflen);
  12.104    static bool can_decode_C_frame_in_vm();
  12.105  
  12.106 -  static void initialize();
  12.107 -  static void uninitialize();
  12.108 +  static void shutdown();
  12.109 +protected:
  12.110 +  static NullDecoder* get_decoder();
  12.111  
  12.112 -#ifdef _WINDOWS
  12.113 -  static decoder_status    decode(address addr, char *buf, int buflen, int *offset);
  12.114 -#else
  12.115 -  static decoder_status    decode(address addr, const char* filepath, char *buf, int buflen, int *offset);
  12.116 -#endif
  12.117 +private:
  12.118 +  static NullDecoder*     _decoder;
  12.119 +  static NullDecoder      _do_nothing_decoder;
  12.120  
  12.121 -  static bool              demangle(const char* symbol, char *buf, int buflen);
  12.122 -
  12.123 -  static decoder_status    get_status() { return _decoder_status; };
  12.124 -
  12.125 -#if !defined(_WINDOWS) && !defined(__APPLE__)
  12.126 - private:
  12.127 -  static ElfFile*         get_elf_file(const char* filepath);
  12.128 -#endif // _WINDOWS
  12.129 -
  12.130 -
  12.131 - private:
  12.132 -  static decoder_status     _decoder_status;
  12.133 -  static bool               _initialized;
  12.134 -
  12.135 -#ifdef _WINDOWS
  12.136 -  static HMODULE                   _dbghelp_handle;
  12.137 -  static bool                      _can_decode_in_vm;
  12.138 -  static pfn_SymGetSymFromAddr64   _pfnSymGetSymFromAddr64;
  12.139 -  static pfn_UndecorateSymbolName  _pfnUndecorateSymbolName;
  12.140 -#elif __APPLE__
  12.141 -#else
  12.142 -  static ElfFile*                  _opened_elf_files;
  12.143 -#endif // _WINDOWS
  12.144 +protected:
  12.145 +  static Mutex*       _decoder_lock;
  12.146  };
  12.147  
  12.148 -#endif // __DECODER_HPP
  12.149 +#endif // SHARE_VM_UTILITIES_DECODER_HPP
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/share/vm/utilities/decoder_elf.cpp	Tue Jan 17 13:08:52 2012 -0500
    13.3 @@ -0,0 +1,76 @@
    13.4 +/*
    13.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.7 + *
    13.8 + * This code is free software; you can redistribute it and/or modify it
    13.9 + * under the terms of the GNU General Public License version 2 only, as
   13.10 + * published by the Free Software Foundation.
   13.11 + *
   13.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   13.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.15 + * version 2 for more details (a copy is included in the LICENSE file that
   13.16 + * accompanied this code).
   13.17 + *
   13.18 + * You should have received a copy of the GNU General Public License version
   13.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   13.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.21 + *
   13.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   13.23 + * or visit www.oracle.com if you need additional information or have any
   13.24 + * questions.
   13.25 + *
   13.26 + */
   13.27 +
   13.28 +#include "precompiled.hpp"
   13.29 +
   13.30 +#if !defined(_WINDOWS) && !defined(__APPLE__)
   13.31 +#include "decoder_elf.hpp"
   13.32 +
   13.33 +ElfDecoder::~ElfDecoder() {
   13.34 +  if (_opened_elf_files != NULL) {
   13.35 +    delete _opened_elf_files;
   13.36 +    _opened_elf_files = NULL;
   13.37 +  }
   13.38 +}
   13.39 +
   13.40 +bool ElfDecoder::decode(address addr, char *buf, int buflen, int* offset, const char* filepath) {
   13.41 +  assert(filepath, "null file path");
   13.42 +  assert(buf != NULL && buflen > 0, "Invalid buffer");
   13.43 +  if (has_error()) return false;
   13.44 +  ElfFile* file = get_elf_file(filepath);
   13.45 +  if (file == NULL) {
   13.46 +    return false;
   13.47 +  }
   13.48 +
   13.49 +  if (!file->decode(addr, buf, buflen, offset)) {
   13.50 +    return false;
   13.51 +  }
   13.52 +  if (buf[0] != '\0') {
   13.53 +    demangle(buf, buf, buflen);
   13.54 +  }
   13.55 +  return true;
   13.56 +}
   13.57 +
   13.58 +ElfFile* ElfDecoder::get_elf_file(const char* filepath) {
   13.59 +  ElfFile* file;
   13.60 +
   13.61 +  file = _opened_elf_files;
   13.62 +  while (file != NULL) {
   13.63 +    if (file->same_elf_file(filepath)) {
   13.64 +      return file;
   13.65 +    }
   13.66 +    file = file->next();
   13.67 +  }
   13.68 +
   13.69 +  file = new (std::nothrow)ElfFile(filepath);
   13.70 +  if (file != NULL) {
   13.71 +    if (_opened_elf_files != NULL) {
   13.72 +      file->set_next(_opened_elf_files);
   13.73 +    }
   13.74 +    _opened_elf_files = file;
   13.75 +  }
   13.76 +
   13.77 +  return file;
   13.78 +}
   13.79 +#endif
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/share/vm/utilities/decoder_elf.hpp	Tue Jan 17 13:08:52 2012 -0500
    14.3 @@ -0,0 +1,55 @@
    14.4 +/*
    14.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.
   14.11 + *
   14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 + * version 2 for more details (a copy is included in the LICENSE file that
   14.16 + * accompanied this code).
   14.17 + *
   14.18 + * You should have received a copy of the GNU General Public License version
   14.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 + *
   14.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.23 + * or visit www.oracle.com if you need additional information or have any
   14.24 + * questions.
   14.25 + *
   14.26 + */
   14.27 +
   14.28 +#ifndef SHARE_VM_UTILITIES_DECODER_ELF_HPP
   14.29 +#define SHARE_VM_UTILITIES_DECODER_ELF_HPP
   14.30 +
   14.31 +#if !defined(_WINDOWS) && !defined(__APPLE__)
   14.32 +
   14.33 +#include "utilities/decoder.hpp"
   14.34 +#include "utilities/elfFile.hpp"
   14.35 +
   14.36 +class ElfDecoder: public NullDecoder {
   14.37 +
   14.38 +public:
   14.39 +  ElfDecoder() {
   14.40 +    _opened_elf_files = NULL;
   14.41 +    _decoder_status = no_error;
   14.42 +  }
   14.43 +  ~ElfDecoder();
   14.44 +
   14.45 +  bool can_decode_C_frame_in_vm() const { return true; }
   14.46 +
   14.47 +  bool demangle(const char* symbol, char *buf, int buflen);
   14.48 +  bool decode(address addr, char *buf, int buflen, int* offset, const char* filepath = NULL);
   14.49 +
   14.50 +private:
   14.51 +  ElfFile*         get_elf_file(const char* filepath);
   14.52 +
   14.53 +private:
   14.54 +  ElfFile*         _opened_elf_files;
   14.55 +};
   14.56 +
   14.57 +#endif
   14.58 +#endif // SHARE_VM_UTILITIES_DECODER_ELF_HPP
    15.1 --- a/src/share/vm/utilities/elfFile.cpp	Wed Jan 11 17:58:26 2012 -0500
    15.2 +++ b/src/share/vm/utilities/elfFile.cpp	Tue Jan 17 13:08:52 2012 -0500
    15.3 @@ -44,7 +44,7 @@
    15.4    m_string_tables = NULL;
    15.5    m_symbol_tables = NULL;
    15.6    m_next = NULL;
    15.7 -  m_status = Decoder::no_error;
    15.8 +  m_status = NullDecoder::no_error;
    15.9  
   15.10    int len = strlen(filepath) + 1;
   15.11    m_filepath = (const char*)os::malloc(len * sizeof(char));
   15.12 @@ -54,10 +54,10 @@
   15.13      if (m_file != NULL) {
   15.14        load_tables();
   15.15      } else {
   15.16 -      m_status = Decoder::file_not_found;
   15.17 +      m_status = NullDecoder::file_not_found;
   15.18      }
   15.19    } else {
   15.20 -    m_status = Decoder::out_of_memory;
   15.21 +    m_status = NullDecoder::out_of_memory;
   15.22    }
   15.23  }
   15.24  
   15.25 @@ -96,41 +96,41 @@
   15.26  
   15.27  bool ElfFile::load_tables() {
   15.28    assert(m_file, "file not open");
   15.29 -  assert(m_status == Decoder::no_error, "already in error");
   15.30 +  assert(!NullDecoder::is_error(m_status), "already in error");
   15.31  
   15.32    // read elf file header
   15.33    if (fread(&m_elfHdr, sizeof(m_elfHdr), 1, m_file) != 1) {
   15.34 -    m_status = Decoder::file_invalid;
   15.35 +    m_status = NullDecoder::file_invalid;
   15.36      return false;
   15.37    }
   15.38  
   15.39    if (!is_elf_file(m_elfHdr)) {
   15.40 -    m_status = Decoder::file_invalid;
   15.41 +    m_status = NullDecoder::file_invalid;
   15.42      return false;
   15.43    }
   15.44  
   15.45    // walk elf file's section headers, and load string tables
   15.46    Elf_Shdr shdr;
   15.47    if (!fseek(m_file, m_elfHdr.e_shoff, SEEK_SET)) {
   15.48 -    if (m_status != Decoder::no_error) return false;
   15.49 +    if (NullDecoder::is_error(m_status)) return false;
   15.50  
   15.51      for (int index = 0; index < m_elfHdr.e_shnum; index ++) {
   15.52        if (fread((void*)&shdr, sizeof(Elf_Shdr), 1, m_file) != 1) {
   15.53 -        m_status = Decoder::file_invalid;
   15.54 +        m_status = NullDecoder::file_invalid;
   15.55          return false;
   15.56        }
   15.57        // string table
   15.58        if (shdr.sh_type == SHT_STRTAB) {
   15.59          ElfStringTable* table = new (std::nothrow) ElfStringTable(m_file, shdr, index);
   15.60          if (table == NULL) {
   15.61 -          m_status = Decoder::out_of_memory;
   15.62 +          m_status = NullDecoder::out_of_memory;
   15.63            return false;
   15.64          }
   15.65          add_string_table(table);
   15.66        } else if (shdr.sh_type == SHT_SYMTAB || shdr.sh_type == SHT_DYNSYM) {
   15.67          ElfSymbolTable* table = new (std::nothrow) ElfSymbolTable(m_file, shdr);
   15.68          if (table == NULL) {
   15.69 -          m_status = Decoder::out_of_memory;
   15.70 +          m_status = NullDecoder::out_of_memory;
   15.71            return false;
   15.72          }
   15.73          add_symbol_table(table);
   15.74 @@ -140,32 +140,33 @@
   15.75    return true;
   15.76  }
   15.77  
   15.78 -const char* ElfFile::decode(address addr, int* offset) {
   15.79 +bool ElfFile::decode(address addr, char* buf, int buflen, int* offset) {
   15.80    // something already went wrong, just give up
   15.81 -  if (m_status != Decoder::no_error) {
   15.82 -    return NULL;
   15.83 +  if (NullDecoder::is_error(m_status)) {
   15.84 +    return false;
   15.85    }
   15.86 -
   15.87    ElfSymbolTable* symbol_table = m_symbol_tables;
   15.88    int string_table_index;
   15.89    int pos_in_string_table;
   15.90    int off = INT_MAX;
   15.91    bool found_symbol = false;
   15.92    while (symbol_table != NULL) {
   15.93 -    if (Decoder::no_error == symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
   15.94 +    if (symbol_table->lookup(addr, &string_table_index, &pos_in_string_table, &off)) {
   15.95        found_symbol = true;
   15.96      }
   15.97      symbol_table = symbol_table->m_next;
   15.98    }
   15.99 -  if (!found_symbol) return NULL;
  15.100 +  if (!found_symbol) return false;
  15.101  
  15.102    ElfStringTable* string_table = get_string_table(string_table_index);
  15.103 +
  15.104    if (string_table == NULL) {
  15.105 -    m_status = Decoder::file_invalid;
  15.106 -    return NULL;
  15.107 +    m_status = NullDecoder::file_invalid;
  15.108 +    return false;
  15.109    }
  15.110    if (offset) *offset = off;
  15.111 -  return string_table->string_at(pos_in_string_table);
  15.112 +
  15.113 +  return string_table->string_at(pos_in_string_table, buf, buflen);
  15.114  }
  15.115  
  15.116  
    16.1 --- a/src/share/vm/utilities/elfFile.hpp	Wed Jan 11 17:58:26 2012 -0500
    16.2 +++ b/src/share/vm/utilities/elfFile.hpp	Tue Jan 17 13:08:52 2012 -0500
    16.3 @@ -1,5 +1,5 @@
    16.4  /*
    16.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    16.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    16.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.8   *
    16.9   * This code is free software; you can redistribute it and/or modify it
   16.10 @@ -22,8 +22,8 @@
   16.11   *
   16.12   */
   16.13  
   16.14 -#ifndef __ELF_FILE_HPP
   16.15 -#define __ELF_FILE_HPP
   16.16 +#ifndef SHARE_VM_UTILITIES_ELF_FILE_HPP
   16.17 +#define SHARE_VM_UTILITIES_ELF_FILE_HPP
   16.18  
   16.19  #if !defined(_WINDOWS) && !defined(__APPLE__)
   16.20  
   16.21 @@ -83,12 +83,12 @@
   16.22  // part of code to be very defensive, and bait out if anything went wrong.
   16.23  
   16.24  class ElfFile: public CHeapObj {
   16.25 -  friend class Decoder;
   16.26 +  friend class ElfDecoder;
   16.27   public:
   16.28    ElfFile(const char* filepath);
   16.29    ~ElfFile();
   16.30  
   16.31 -  const char* decode(address addr, int* offset);
   16.32 +  bool decode(address addr, char* buf, int buflen, int* offset);
   16.33    const char* filepath() {
   16.34      return m_filepath;
   16.35    }
   16.36 @@ -99,7 +99,7 @@
   16.37      return (m_filepath && !strcmp(filepath, m_filepath));
   16.38    }
   16.39  
   16.40 -  Decoder::decoder_status get_status() {
   16.41 +  NullDecoder::decoder_status get_status() {
   16.42      return m_status;
   16.43    }
   16.44  
   16.45 @@ -119,8 +119,9 @@
   16.46    // return a string table at specified section index
   16.47    ElfStringTable* get_string_table(int index);
   16.48  
   16.49 -  // look up an address and return the nearest symbol
   16.50 -  const char* look_up(Elf_Shdr shdr, address addr, int* offset);
   16.51 +protected:
   16.52 +   ElfFile*  next() const { return m_next; }
   16.53 +   void set_next(ElfFile* file) { m_next = file; }
   16.54  
   16.55   protected:
   16.56      ElfFile*         m_next;
   16.57 @@ -131,17 +132,17 @@
   16.58    FILE* m_file;
   16.59  
   16.60    // Elf header
   16.61 -  Elf_Ehdr            m_elfHdr;
   16.62 +  Elf_Ehdr                     m_elfHdr;
   16.63  
   16.64    // symbol tables
   16.65 -  ElfSymbolTable*     m_symbol_tables;
   16.66 +  ElfSymbolTable*              m_symbol_tables;
   16.67  
   16.68    // string tables
   16.69 -  ElfStringTable*     m_string_tables;
   16.70 +  ElfStringTable*              m_string_tables;
   16.71  
   16.72 -  Decoder::decoder_status  m_status;
   16.73 +  NullDecoder::decoder_status  m_status;
   16.74  };
   16.75  
   16.76  #endif // _WINDOWS
   16.77  
   16.78 -#endif // __ELF_FILE_HPP
   16.79 +#endif // SHARE_VM_UTILITIES_ELF_FILE_HPP
    17.1 --- a/src/share/vm/utilities/elfStringTable.cpp	Wed Jan 11 17:58:26 2012 -0500
    17.2 +++ b/src/share/vm/utilities/elfStringTable.cpp	Tue Jan 17 13:08:52 2012 -0500
    17.3 @@ -38,7 +38,7 @@
    17.4    m_index = index;
    17.5    m_next = NULL;
    17.6    m_file = file;
    17.7 -  m_status = Decoder::no_error;
    17.8 +  m_status = NullDecoder::no_error;
    17.9  
   17.10    // try to load the string table
   17.11    long cur_offset = ftell(file);
   17.12 @@ -48,7 +48,7 @@
   17.13      if (fseek(file, shdr.sh_offset, SEEK_SET) ||
   17.14        fread((void*)m_table, shdr.sh_size, 1, file) != 1 ||
   17.15        fseek(file, cur_offset, SEEK_SET)) {
   17.16 -      m_status = Decoder::file_invalid;
   17.17 +      m_status = NullDecoder::file_invalid;
   17.18        os::free((void*)m_table);
   17.19        m_table = NULL;
   17.20      }
   17.21 @@ -67,22 +67,23 @@
   17.22    }
   17.23  }
   17.24  
   17.25 -const char* ElfStringTable::string_at(int pos) {
   17.26 -  if (m_status != Decoder::no_error) {
   17.27 -    return NULL;
   17.28 +bool ElfStringTable::string_at(int pos, char* buf, int buflen) {
   17.29 +  if (NullDecoder::is_error(m_status)) {
   17.30 +    return false;
   17.31    }
   17.32    if (m_table != NULL) {
   17.33 -    return (const char*)(m_table + pos);
   17.34 +    jio_snprintf(buf, buflen, "%s", (const char*)(m_table + pos));
   17.35 +    return true;
   17.36    } else {
   17.37      long cur_pos = ftell(m_file);
   17.38      if (cur_pos == -1 ||
   17.39        fseek(m_file, m_shdr.sh_offset + pos, SEEK_SET) ||
   17.40 -      fread(m_symbol, 1, MAX_SYMBOL_LEN, m_file) <= 0 ||
   17.41 +      fread(buf, 1, buflen, m_file) <= 0 ||
   17.42        fseek(m_file, cur_pos, SEEK_SET)) {
   17.43 -      m_status = Decoder::file_invalid;
   17.44 -      return NULL;
   17.45 +      m_status = NullDecoder::file_invalid;
   17.46 +      return false;
   17.47      }
   17.48 -    return (const char*)m_symbol;
   17.49 +    return true;
   17.50    }
   17.51  }
   17.52  
    18.1 --- a/src/share/vm/utilities/elfStringTable.hpp	Wed Jan 11 17:58:26 2012 -0500
    18.2 +++ b/src/share/vm/utilities/elfStringTable.hpp	Tue Jan 17 13:08:52 2012 -0500
    18.3 @@ -1,5 +1,5 @@
    18.4  /*
    18.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    18.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    18.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    18.8   *
    18.9   * This code is free software; you can redistribute it and/or modify it
   18.10 @@ -22,8 +22,8 @@
   18.11   *
   18.12   */
   18.13  
   18.14 -#ifndef __ELF_STRING_TABLE_HPP
   18.15 -#define __ELF_STRING_TABLE_HPP
   18.16 +#ifndef SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
   18.17 +#define SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
   18.18  
   18.19  #if !defined(_WINDOWS) && !defined(__APPLE__)
   18.20  
   18.21 @@ -35,9 +35,6 @@
   18.22  // The string table represents a string table section in an elf file.
   18.23  // Whenever there is enough memory, it will load whole string table as
   18.24  // one blob. Otherwise, it will load string from file when requested.
   18.25 -
   18.26 -#define MAX_SYMBOL_LEN  256
   18.27 -
   18.28  class ElfStringTable: CHeapObj {
   18.29    friend class ElfFile;
   18.30   public:
   18.31 @@ -48,10 +45,10 @@
   18.32    int index() { return m_index; };
   18.33  
   18.34    // get string at specified offset
   18.35 -  const char* string_at(int offset);
   18.36 +  bool string_at(int offset, char* buf, int buflen);
   18.37  
   18.38    // get status code
   18.39 -  Decoder::decoder_status get_status() { return m_status; };
   18.40 +  NullDecoder::decoder_status get_status() { return m_status; };
   18.41  
   18.42   protected:
   18.43    ElfStringTable*        m_next;
   18.44 @@ -69,13 +66,10 @@
   18.45    // section header
   18.46    Elf_Shdr                 m_shdr;
   18.47  
   18.48 -  // buffer for reading individual string
   18.49 -  char                     m_symbol[MAX_SYMBOL_LEN];
   18.50 -
   18.51    // error code
   18.52 -  Decoder::decoder_status  m_status;
   18.53 +  NullDecoder::decoder_status  m_status;
   18.54  };
   18.55  
   18.56 -#endif // _WINDOWS
   18.57 +#endif // _WINDOWS and _APPLE
   18.58  
   18.59 -#endif // __ELF_STRING_TABLE_HPP
   18.60 +#endif // SHARE_VM_UTILITIES_ELF_STRING_TABLE_HPP
    19.1 --- a/src/share/vm/utilities/elfSymbolTable.cpp	Wed Jan 11 17:58:26 2012 -0500
    19.2 +++ b/src/share/vm/utilities/elfSymbolTable.cpp	Tue Jan 17 13:08:52 2012 -0500
    19.3 @@ -34,7 +34,7 @@
    19.4    m_symbols = NULL;
    19.5    m_next = NULL;
    19.6    m_file = file;
    19.7 -  m_status = Decoder::no_error;
    19.8 +  m_status = NullDecoder::no_error;
    19.9  
   19.10    // try to load the string table
   19.11    long cur_offset = ftell(file);
   19.12 @@ -45,16 +45,16 @@
   19.13        if (fseek(file, shdr.sh_offset, SEEK_SET) ||
   19.14          fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
   19.15          fseek(file, cur_offset, SEEK_SET)) {
   19.16 -        m_status = Decoder::file_invalid;
   19.17 +        m_status = NullDecoder::file_invalid;
   19.18          os::free(m_symbols);
   19.19          m_symbols = NULL;
   19.20        }
   19.21      }
   19.22 -    if (m_status == Decoder::no_error) {
   19.23 +    if (!NullDecoder::is_error(m_status)) {
   19.24        memcpy(&m_shdr, &shdr, sizeof(Elf_Shdr));
   19.25      }
   19.26    } else {
   19.27 -    m_status = Decoder::file_invalid;
   19.28 +    m_status = NullDecoder::file_invalid;
   19.29    }
   19.30  }
   19.31  
   19.32 @@ -68,13 +68,13 @@
   19.33    }
   19.34  }
   19.35  
   19.36 -Decoder::decoder_status ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
   19.37 +bool ElfSymbolTable::lookup(address addr, int* stringtableIndex, int* posIndex, int* offset) {
   19.38    assert(stringtableIndex, "null string table index pointer");
   19.39    assert(posIndex, "null string table offset pointer");
   19.40    assert(offset, "null offset pointer");
   19.41  
   19.42 -  if (m_status != Decoder::no_error) {
   19.43 -    return m_status;
   19.44 +  if (NullDecoder::is_error(m_status)) {
   19.45 +    return false;
   19.46    }
   19.47  
   19.48    address pc = 0;
   19.49 @@ -97,8 +97,8 @@
   19.50      long cur_pos;
   19.51      if ((cur_pos = ftell(m_file)) == -1 ||
   19.52        fseek(m_file, m_shdr.sh_offset, SEEK_SET)) {
   19.53 -      m_status = Decoder::file_invalid;
   19.54 -      return m_status;
   19.55 +      m_status = NullDecoder::file_invalid;
   19.56 +      return false;
   19.57      }
   19.58  
   19.59      Elf_Sym sym;
   19.60 @@ -114,13 +114,13 @@
   19.61            }
   19.62          }
   19.63        } else {
   19.64 -        m_status = Decoder::file_invalid;
   19.65 -        return m_status;
   19.66 +        m_status = NullDecoder::file_invalid;
   19.67 +        return false;
   19.68        }
   19.69      }
   19.70      fseek(m_file, cur_pos, SEEK_SET);
   19.71    }
   19.72 -  return m_status;
   19.73 +  return true;
   19.74  }
   19.75  
   19.76  #endif // _WINDOWS
    20.1 --- a/src/share/vm/utilities/elfSymbolTable.hpp	Wed Jan 11 17:58:26 2012 -0500
    20.2 +++ b/src/share/vm/utilities/elfSymbolTable.hpp	Tue Jan 17 13:08:52 2012 -0500
    20.3 @@ -1,5 +1,5 @@
    20.4  /*
    20.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
    20.6 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
    20.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.8   *
    20.9   * This code is free software; you can redistribute it and/or modify it
   20.10 @@ -22,8 +22,8 @@
   20.11   *
   20.12   */
   20.13  
   20.14 -#ifndef __ELF_SYMBOL_TABLE_HPP
   20.15 -#define __ELF_SYMBOL_TABLE_HPP
   20.16 +#ifndef SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
   20.17 +#define SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
   20.18  
   20.19  #if !defined(_WINDOWS) && !defined(__APPLE__)
   20.20  
   20.21 @@ -45,9 +45,9 @@
   20.22    ~ElfSymbolTable();
   20.23  
   20.24    // search the symbol that is nearest to the specified address.
   20.25 -  Decoder::decoder_status lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
   20.26 +  bool lookup(address addr, int* stringtableIndex, int* posIndex, int* offset);
   20.27  
   20.28 -  Decoder::decoder_status get_status() { return m_status; };
   20.29 +  NullDecoder::decoder_status get_status() { return m_status; };
   20.30  
   20.31   protected:
   20.32    ElfSymbolTable*  m_next;
   20.33 @@ -62,9 +62,9 @@
   20.34    // section header
   20.35    Elf_Shdr            m_shdr;
   20.36  
   20.37 -  Decoder::decoder_status  m_status;
   20.38 +  NullDecoder::decoder_status  m_status;
   20.39  };
   20.40  
   20.41 -#endif // _WINDOWS
   20.42 +#endif // _WINDOWS and _APPLE
   20.43  
   20.44 -#endif // __ELF_SYMBOL_TABLE_HPP
   20.45 +#endif // SHARE_VM_UTILITIES_ELF_SYMBOL_TABLE_HPP
    21.1 --- a/src/share/vm/utilities/vmError.cpp	Wed Jan 11 17:58:26 2012 -0500
    21.2 +++ b/src/share/vm/utilities/vmError.cpp	Tue Jan 17 13:08:52 2012 -0500
    21.3 @@ -571,8 +571,6 @@
    21.4         if (fr.pc()) {
    21.5            st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
    21.6  
    21.7 -          // initialize decoder to decode C frames
    21.8 -          Decoder decoder;
    21.9  
   21.10            int count = 0;
   21.11            while (count++ < StackPrintLimit) {

mercurial