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

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

mercurial