src/share/vm/oops/symbol.cpp

Mon, 12 Nov 2012 14:03:53 -0800

author
minqi
date
Mon, 12 Nov 2012 14:03:53 -0800
changeset 4267
bd7a7ce2e264
parent 4037
da91efe96a93
child 4531
fcc9e7681d63
permissions
-rw-r--r--

6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com

     1 /*
     2  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    26 #include "precompiled.hpp"
    27 #include "classfile/altHashing.hpp"
    28 #include "classfile/classLoaderData.hpp"
    29 #include "oops/symbol.hpp"
    30 #include "runtime/os.hpp"
    31 #include "memory/allocation.inline.hpp"
    32 #include "memory/resourceArea.hpp"
    34 Symbol::Symbol(const u1* name, int length, int refcount) : _refcount(refcount), _length(length) {
    35   _identity_hash = os::random();
    36   for (int i = 0; i < _length; i++) {
    37     byte_at_put(i, name[i]);
    38   }
    39 }
    41 void* Symbol::operator new(size_t sz, int len, TRAPS) {
    42   int alloc_size = size(len)*HeapWordSize;
    43   address res = (address) AllocateHeap(alloc_size, mtSymbol);
    44   return res;
    45 }
    47 void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) {
    48   int alloc_size = size(len)*HeapWordSize;
    49   address res = (address)arena->Amalloc(alloc_size);
    50   return res;
    51 }
    53 void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRAPS) {
    54   address res;
    55   int alloc_size = size(len)*HeapWordSize;
    56   res = (address) Metaspace::allocate(loader_data, size(len), true,
    57                                       Metaspace::NonClassType, CHECK_NULL);
    58   return res;
    59 }
    61 void Symbol::operator delete(void *p) {
    62   assert(((Symbol*)p)->refcount() == 0, "should not call this");
    63   FreeHeap(p);
    64 }
    66 // ------------------------------------------------------------------
    67 // Symbol::equals
    68 //
    69 // Compares the symbol with a string of the given length.
    70 bool Symbol::equals(const char* str, int len) const {
    71   int l = utf8_length();
    72   if (l != len) return false;
    73   while (l-- > 0) {
    74     if (str[l] != (char) byte_at(l))
    75       return false;
    76   }
    77   assert(l == -1, "we should be at the beginning");
    78   return true;
    79 }
    82 // ------------------------------------------------------------------
    83 // Symbol::starts_with
    84 //
    85 // Tests if the symbol starts with the specified prefix of the given
    86 // length.
    87 bool Symbol::starts_with(const char* prefix, int len) const {
    88   if (len > utf8_length()) return false;
    89   while (len-- > 0) {
    90     if (prefix[len] != (char) byte_at(len))
    91       return false;
    92   }
    93   assert(len == -1, "we should be at the beginning");
    94   return true;
    95 }
    98 // ------------------------------------------------------------------
    99 // Symbol::index_of
   100 //
   101 // Finds if the given string is a substring of this symbol's utf8 bytes.
   102 // Return -1 on failure.  Otherwise return the first index where str occurs.
   103 int Symbol::index_of_at(int i, const char* str, int len) const {
   104   assert(i >= 0 && i <= utf8_length(), "oob");
   105   if (len <= 0)  return 0;
   106   char first_char = str[0];
   107   address bytes = (address) ((Symbol*)this)->base();
   108   address limit = bytes + utf8_length() - len;  // inclusive limit
   109   address scan = bytes + i;
   110   if (scan > limit)
   111     return -1;
   112   for (; scan <= limit; scan++) {
   113     scan = (address) memchr(scan, first_char, (limit + 1 - scan));
   114     if (scan == NULL)
   115       return -1;  // not found
   116     assert(scan >= bytes+i && scan <= limit, "scan oob");
   117     if (memcmp(scan, str, len) == 0)
   118       return (int)(scan - bytes);
   119   }
   120   return -1;
   121 }
   124 char* Symbol::as_C_string(char* buf, int size) const {
   125   if (size > 0) {
   126     int len = MIN2(size - 1, utf8_length());
   127     for (int i = 0; i < len; i++) {
   128       buf[i] = byte_at(i);
   129     }
   130     buf[len] = '\0';
   131   }
   132   return buf;
   133 }
   135 char* Symbol::as_C_string() const {
   136   int len = utf8_length();
   137   char* str = NEW_RESOURCE_ARRAY(char, len + 1);
   138   return as_C_string(str, len + 1);
   139 }
   141 char* Symbol::as_C_string_flexible_buffer(Thread* t,
   142                                                  char* buf, int size) const {
   143   char* str;
   144   int len = utf8_length();
   145   int buf_len = len + 1;
   146   if (size < buf_len) {
   147     str = NEW_RESOURCE_ARRAY(char, buf_len);
   148   } else {
   149     str = buf;
   150   }
   151   return as_C_string(str, buf_len);
   152 }
   154 void Symbol::print_symbol_on(outputStream* st) const {
   155   st = st ? st : tty;
   156   st->print("%s", as_quoted_ascii());
   157 }
   159 char* Symbol::as_quoted_ascii() const {
   160   const char *ptr = (const char *)&_body[0];
   161   int quoted_length = UTF8::quoted_ascii_length(ptr, utf8_length());
   162   char* result = NEW_RESOURCE_ARRAY(char, quoted_length + 1);
   163   UTF8::as_quoted_ascii(ptr, result, quoted_length + 1);
   164   return result;
   165 }
   167 jchar* Symbol::as_unicode(int& length) const {
   168   Symbol* this_ptr = (Symbol*)this;
   169   length = UTF8::unicode_length((char*)this_ptr->bytes(), utf8_length());
   170   jchar* result = NEW_RESOURCE_ARRAY(jchar, length);
   171   if (length > 0) {
   172     UTF8::convert_to_unicode((char*)this_ptr->bytes(), result, length);
   173   }
   174   return result;
   175 }
   177 const char* Symbol::as_klass_external_name(char* buf, int size) const {
   178   if (size > 0) {
   179     char* str    = as_C_string(buf, size);
   180     int   length = (int)strlen(str);
   181     // Turn all '/'s into '.'s (also for array klasses)
   182     for (int index = 0; index < length; index++) {
   183       if (str[index] == '/') {
   184         str[index] = '.';
   185       }
   186     }
   187     return str;
   188   } else {
   189     return buf;
   190   }
   191 }
   193 const char* Symbol::as_klass_external_name() const {
   194   char* str    = as_C_string();
   195   int   length = (int)strlen(str);
   196   // Turn all '/'s into '.'s (also for array klasses)
   197   for (int index = 0; index < length; index++) {
   198     if (str[index] == '/') {
   199       str[index] = '.';
   200     }
   201   }
   202   return str;
   203 }
   205 // Alternate hashing for unbalanced symbol tables.
   206 unsigned int Symbol::new_hash(jint seed) {
   207   ResourceMark rm;
   208   // Use alternate hashing algorithm on this symbol.
   209   return AltHashing::murmur3_32(seed, (const jbyte*)as_C_string(), utf8_length());
   210 }
   212 void Symbol::print_on(outputStream* st) const {
   213   if (this == NULL) {
   214     st->print_cr("NULL");
   215   } else {
   216     st->print("Symbol: '");
   217     print_symbol_on(st);
   218     st->print("'");
   219     st->print(" count %d", refcount());
   220   }
   221 }
   223 // The print_value functions are present in all builds, to support the
   224 // disassembler and error reporting.
   225 void Symbol::print_value_on(outputStream* st) const {
   226   if (this == NULL) {
   227     st->print("NULL");
   228   } else {
   229     st->print("'");
   230     for (int i = 0; i < utf8_length(); i++) {
   231       st->print("%c", byte_at(i));
   232     }
   233     st->print("'");
   234   }
   235 }
   237 // SymbolTable prints this in its statistics
   238 NOT_PRODUCT(int Symbol::_total_count = 0;)

mercurial