src/share/vm/oops/symbol.cpp

Tue, 13 Mar 2012 13:50:48 -0400

author
jiangli
date
Tue, 13 Mar 2012 13:50:48 -0400
changeset 3670
f7c4174b33ba
parent 2708
1d1603768966
child 3682
fc9d8850ab8b
permissions
-rw-r--r--

7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
Summary: Fold instanceKlass::_enclosing_method_class_index and instanceKlass::_enclosing_method_method_index into the instanceKlass::_inner_classes array.
Reviewed-by: never, coleenp
Contributed-by: Jiangli Zhou <jiangli.zhou@oracle.com>

     1 /*
     2  * Copyright (c) 1997, 2011, 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 "oops/oop.inline.hpp"
    28 #include "oops/symbol.hpp"
    29 #include "runtime/os.hpp"
    30 #include "memory/allocation.inline.hpp"
    32 Symbol::Symbol(const u1* name, int length) : _refcount(0), _length(length) {
    33   _identity_hash = os::random();
    34   for (int i = 0; i < _length; i++) {
    35     byte_at_put(i, name[i]);
    36   }
    37 }
    39 void* Symbol::operator new(size_t size, int len) {
    40   return (void *) AllocateHeap(object_size(len) * HeapWordSize, "symbol");
    41 }
    43 // ------------------------------------------------------------------
    44 // Symbol::equals
    45 //
    46 // Compares the symbol with a string of the given length.
    47 bool Symbol::equals(const char* str, int len) const {
    48   int l = utf8_length();
    49   if (l != len) return false;
    50   while (l-- > 0) {
    51     if (str[l] != (char) byte_at(l))
    52       return false;
    53   }
    54   assert(l == -1, "we should be at the beginning");
    55   return true;
    56 }
    59 // ------------------------------------------------------------------
    60 // Symbol::starts_with
    61 //
    62 // Tests if the symbol starts with the specified prefix of the given
    63 // length.
    64 bool Symbol::starts_with(const char* prefix, int len) const {
    65   if (len > utf8_length()) return false;
    66   while (len-- > 0) {
    67     if (prefix[len] != (char) byte_at(len))
    68       return false;
    69   }
    70   assert(len == -1, "we should be at the beginning");
    71   return true;
    72 }
    75 // ------------------------------------------------------------------
    76 // Symbol::index_of
    77 //
    78 // Finds if the given string is a substring of this symbol's utf8 bytes.
    79 // Return -1 on failure.  Otherwise return the first index where str occurs.
    80 int Symbol::index_of_at(int i, const char* str, int len) const {
    81   assert(i >= 0 && i <= utf8_length(), "oob");
    82   if (len <= 0)  return 0;
    83   char first_char = str[0];
    84   address bytes = (address) ((Symbol*)this)->base();
    85   address limit = bytes + utf8_length() - len;  // inclusive limit
    86   address scan = bytes + i;
    87   if (scan > limit)
    88     return -1;
    89   for (;;) {
    90     scan = (address) memchr(scan, first_char, (limit + 1 - scan));
    91     if (scan == NULL)
    92       return -1;  // not found
    93     assert(scan >= bytes+i && scan <= limit, "scan oob");
    94     if (memcmp(scan, str, len) == 0)
    95       return (int)(scan - bytes);
    96   }
    97 }
   100 char* Symbol::as_C_string(char* buf, int size) const {
   101   if (size > 0) {
   102     int len = MIN2(size - 1, utf8_length());
   103     for (int i = 0; i < len; i++) {
   104       buf[i] = byte_at(i);
   105     }
   106     buf[len] = '\0';
   107   }
   108   return buf;
   109 }
   111 char* Symbol::as_C_string() const {
   112   int len = utf8_length();
   113   char* str = NEW_RESOURCE_ARRAY(char, len + 1);
   114   return as_C_string(str, len + 1);
   115 }
   117 char* Symbol::as_C_string_flexible_buffer(Thread* t,
   118                                                  char* buf, int size) const {
   119   char* str;
   120   int len = utf8_length();
   121   int buf_len = len + 1;
   122   if (size < buf_len) {
   123     str = NEW_RESOURCE_ARRAY(char, buf_len);
   124   } else {
   125     str = buf;
   126   }
   127   return as_C_string(str, buf_len);
   128 }
   130 void Symbol::print_symbol_on(outputStream* st) const {
   131   st = st ? st : tty;
   132   int length = UTF8::unicode_length((const char*)bytes(), utf8_length());
   133   const char *ptr = (const char *)bytes();
   134   jchar value;
   135   for (int index = 0; index < length; index++) {
   136     ptr = UTF8::next(ptr, &value);
   137     if (value >= 32 && value < 127 || value == '\'' || value == '\\') {
   138       st->put(value);
   139     } else {
   140       st->print("\\u%04x", value);
   141     }
   142   }
   143 }
   145 jchar* Symbol::as_unicode(int& length) const {
   146   Symbol* this_ptr = (Symbol*)this;
   147   length = UTF8::unicode_length((char*)this_ptr->bytes(), utf8_length());
   148   jchar* result = NEW_RESOURCE_ARRAY(jchar, length);
   149   if (length > 0) {
   150     UTF8::convert_to_unicode((char*)this_ptr->bytes(), result, length);
   151   }
   152   return result;
   153 }
   155 const char* Symbol::as_klass_external_name(char* buf, int size) const {
   156   if (size > 0) {
   157     char* str    = as_C_string(buf, size);
   158     int   length = (int)strlen(str);
   159     // Turn all '/'s into '.'s (also for array klasses)
   160     for (int index = 0; index < length; index++) {
   161       if (str[index] == '/') {
   162         str[index] = '.';
   163       }
   164     }
   165     return str;
   166   } else {
   167     return buf;
   168   }
   169 }
   171 const char* Symbol::as_klass_external_name() const {
   172   char* str    = as_C_string();
   173   int   length = (int)strlen(str);
   174   // Turn all '/'s into '.'s (also for array klasses)
   175   for (int index = 0; index < length; index++) {
   176     if (str[index] == '/') {
   177       str[index] = '.';
   178     }
   179   }
   180   return str;
   181 }
   184 void Symbol::print_on(outputStream* st) const {
   185   if (this == NULL) {
   186     st->print_cr("NULL");
   187   } else {
   188     st->print("Symbol: '");
   189     print_symbol_on(st);
   190     st->print("'");
   191     st->print(" count %d", refcount());
   192   }
   193 }
   195 // The print_value functions are present in all builds, to support the
   196 // disassembler and error reporting.
   197 void Symbol::print_value_on(outputStream* st) const {
   198   if (this == NULL) {
   199     st->print("NULL");
   200   } else {
   201     st->print("'");
   202     for (int i = 0; i < utf8_length(); i++) {
   203       st->print("%c", byte_at(i));
   204     }
   205     st->print("'");
   206   }
   207 }
   209 void Symbol::increment_refcount() {
   210   // Only increment the refcount if positive.  If negative either
   211   // overflow has occurred or it is a permanent symbol in a read only
   212   // shared archive.
   213   if (_refcount >= 0) {
   214     Atomic::inc(&_refcount);
   215     NOT_PRODUCT(Atomic::inc(&_total_count);)
   216   }
   217 }
   219 void Symbol::decrement_refcount() {
   220   if (_refcount >= 0) {
   221     Atomic::dec(&_refcount);
   222 #ifdef ASSERT
   223     if (_refcount < 0) {
   224       print();
   225       assert(false, "reference count underflow for symbol");
   226     }
   227 #endif
   228   }
   229 }
   231 NOT_PRODUCT(int Symbol::_total_count = 0;)

mercurial