src/share/vm/oops/symbolKlass.cpp

changeset 435
a61af66fc99e
child 657
2a1a77d3458f
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/oops/symbolKlass.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,232 @@
     1.4 +/*
     1.5 + * Copyright 1997-2006 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
    1.24 + * have any questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +# include "incls/_precompiled.incl"
    1.29 +# include "incls/_symbolKlass.cpp.incl"
    1.30 +
    1.31 +symbolOop symbolKlass::allocate_symbol(u1* name, int len, TRAPS) {
    1.32 +  // Don't allow symbol oops to be created which cannot fit in a symbolOop.
    1.33 +  if (len > symbolOopDesc::max_length()) {
    1.34 +    THROW_MSG_0(vmSymbols::java_lang_InternalError(),
    1.35 +                "name is too long to represent");
    1.36 +  }
    1.37 +  int size = symbolOopDesc::object_size(len);
    1.38 +  symbolKlassHandle h_k(THREAD, as_klassOop());
    1.39 +  symbolOop sym = (symbolOop)
    1.40 +    CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
    1.41 +  assert(!sym->is_parsable(), "not expecting parsability yet.");
    1.42 +  No_Safepoint_Verifier no_safepoint;
    1.43 +  sym->set_utf8_length(len);
    1.44 +  for (int i = 0; i < len; i++) {
    1.45 +    sym->byte_at_put(i, name[i]);
    1.46 +  }
    1.47 +  // Let the first emptySymbol be created and
    1.48 +  // ensure only one is ever created.
    1.49 +  assert(sym->is_parsable() || Universe::emptySymbol() == NULL,
    1.50 +         "should be parsable here.");
    1.51 +  return sym;
    1.52 +}
    1.53 +
    1.54 +bool symbolKlass::allocate_symbols(int names_count, const char** names,
    1.55 +                                   int* lengths, symbolOop* sym_oops, TRAPS) {
    1.56 +  if (UseConcMarkSweepGC || UseParallelGC) {
    1.57 +    // Concurrent GC needs to mark all the allocated symbol oops after
    1.58 +    // the remark phase which isn't done below (except the first symbol oop).
    1.59 +    // So return false which will let the symbols be allocated one by one.
    1.60 +    // The parallel collector uses an object start array to find the
    1.61 +    // start of objects on a dirty card.  The object start array is not
    1.62 +    // updated for the start of each symbol so is not precise.  During
    1.63 +    // object array verification this causes a verification failure.
    1.64 +    // In a product build this causes extra searching for the start of
    1.65 +    // a symbol.  As with the concurrent collector a return of false will
    1.66 +    // cause each symbol to be allocated separately and in the case
    1.67 +    // of the parallel collector will cause the object
    1.68 +    // start array to be updated.
    1.69 +    return false;
    1.70 +  }
    1.71 +
    1.72 +  assert(names_count > 0, "can't allocate 0 symbols");
    1.73 +
    1.74 +  int total_size = 0;
    1.75 +  int i, sizes[SymbolTable::symbol_alloc_batch_size];
    1.76 +  for (i=0; i<names_count; i++) {
    1.77 +    int len = lengths[i];
    1.78 +    if (len > symbolOopDesc::max_length()) {
    1.79 +      return false;
    1.80 +    }
    1.81 +    int sz = symbolOopDesc::object_size(len);
    1.82 +    sizes[i] = sz * HeapWordSize;
    1.83 +    total_size += sz;
    1.84 +  }
    1.85 +  symbolKlassHandle h_k(THREAD, as_klassOop());
    1.86 +  HeapWord* base = Universe::heap()->permanent_mem_allocate(total_size);
    1.87 +  if (base == NULL) {
    1.88 +    return false;
    1.89 +  }
    1.90 +
    1.91 +  // CAN'T take any safepoint during the initialization of the symbol oops !
    1.92 +  No_Safepoint_Verifier nosafepoint;
    1.93 +
    1.94 +  klassOop sk = h_k();
    1.95 +  int pos = 0;
    1.96 +  for (i=0; i<names_count; i++) {
    1.97 +    symbolOop s = (symbolOop) (((char*)base) + pos);
    1.98 +    s->set_mark(markOopDesc::prototype());
    1.99 +    s->set_klass(sk);
   1.100 +    s->set_utf8_length(lengths[i]);
   1.101 +    const char* name = names[i];
   1.102 +    for (int j=0; j<lengths[i]; j++) {
   1.103 +      s->byte_at_put(j, name[j]);
   1.104 +    }
   1.105 +
   1.106 +    assert(s->is_parsable(), "should be parsable here.");
   1.107 +
   1.108 +    sym_oops[i] = s;
   1.109 +    pos += sizes[i];
   1.110 +  }
   1.111 +  return true;
   1.112 +}
   1.113 +
   1.114 +klassOop symbolKlass::create_klass(TRAPS) {
   1.115 +  symbolKlass o;
   1.116 +  KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
   1.117 +  KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
   1.118 +  // Make sure size calculation is right
   1.119 +  assert(k()->size() == align_object_size(header_size()), "wrong size for object");
   1.120 +//  java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
   1.121 +  return k();
   1.122 +}
   1.123 +
   1.124 +int symbolKlass::oop_size(oop obj) const {
   1.125 +  assert(obj->is_symbol(),"must be a symbol");
   1.126 +  symbolOop s = symbolOop(obj);
   1.127 +  int size = s->object_size();
   1.128 +  return size;
   1.129 +}
   1.130 +
   1.131 +bool symbolKlass::oop_is_parsable(oop obj) const {
   1.132 +  assert(obj->is_symbol(),"must be a symbol");
   1.133 +  symbolOop s = symbolOop(obj);
   1.134 +  return s->object_is_parsable();
   1.135 +}
   1.136 +
   1.137 +void symbolKlass::oop_follow_contents(oop obj) {
   1.138 +  assert (obj->is_symbol(), "object must be symbol");
   1.139 +  // Performance tweak: We skip iterating over the klass pointer since we
   1.140 +  // know that Universe::symbolKlassObj never moves.
   1.141 +  // Note: do not follow next link here (see SymbolTable::follow_contents)
   1.142 +}
   1.143 +
   1.144 +#ifndef SERIALGC
   1.145 +void symbolKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) {
   1.146 +  assert (obj->is_symbol(), "object must be symbol");
   1.147 +  // Performance tweak: We skip iterating over the klass pointer since we
   1.148 +  // know that Universe::symbolKlassObj never moves.
   1.149 +  // Note: do not follow next link here (see SymbolTable::follow_contents)
   1.150 +}
   1.151 +#endif // SERIALGC
   1.152 +
   1.153 +int symbolKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
   1.154 +  assert(obj->is_symbol(), "object must be symbol");
   1.155 +  symbolOop s = symbolOop(obj);
   1.156 +  // Get size before changing pointers.
   1.157 +  // Don't call size() or oop_size() since that is a virtual call.
   1.158 +  int size = s->object_size();
   1.159 +  // Performance tweak: We skip iterating over the klass pointer since we
   1.160 +  // know that Universe::symbolKlassObj never moves.
   1.161 +  return size;
   1.162 +}
   1.163 +
   1.164 +
   1.165 +int symbolKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
   1.166 +  assert(obj->is_symbol(), "object must be symbol");
   1.167 +  symbolOop s = symbolOop(obj);
   1.168 +  // Get size before changing pointers.
   1.169 +  // Don't call size() or oop_size() since that is a virtual call.
   1.170 +  int size = s->object_size();
   1.171 +  // Performance tweak: We skip iterating over the klass pointer since we
   1.172 +  // know that Universe::symbolKlassObj never moves.
   1.173 +  return size;
   1.174 +}
   1.175 +
   1.176 +
   1.177 +int symbolKlass::oop_adjust_pointers(oop obj) {
   1.178 +  assert(obj->is_symbol(), "should be symbol");
   1.179 +  symbolOop s = symbolOop(obj);
   1.180 +  // Get size before changing pointers.
   1.181 +  // Don't call size() or oop_size() since that is a virtual call.
   1.182 +  int size = s->object_size();
   1.183 +  // Performance tweak: We skip iterating over the klass pointer since we
   1.184 +  // know that Universe::symbolKlassObj never moves.
   1.185 +  return size;
   1.186 +}
   1.187 +
   1.188 +
   1.189 +#ifndef SERIALGC
   1.190 +void symbolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
   1.191 +  assert(obj->is_symbol(), "should be symbol");
   1.192 +}
   1.193 +
   1.194 +void symbolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
   1.195 +  assert(obj->is_symbol(), "should be symbol");
   1.196 +}
   1.197 +
   1.198 +int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
   1.199 +  assert(obj->is_symbol(), "should be symbol");
   1.200 +  return symbolOop(obj)->object_size();
   1.201 +}
   1.202 +
   1.203 +int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
   1.204 +                                     HeapWord* beg_addr, HeapWord* end_addr) {
   1.205 +  assert(obj->is_symbol(), "should be symbol");
   1.206 +  return symbolOop(obj)->object_size();
   1.207 +}
   1.208 +#endif // SERIALGC
   1.209 +
   1.210 +#ifndef PRODUCT
   1.211 +// Printing
   1.212 +
   1.213 +void symbolKlass::oop_print_on(oop obj, outputStream* st) {
   1.214 +  st->print("Symbol: '");
   1.215 +  symbolOop sym = symbolOop(obj);
   1.216 +  for (int i = 0; i < sym->utf8_length(); i++) {
   1.217 +    st->print("%c", sym->byte_at(i));
   1.218 +  }
   1.219 +  st->print("'");
   1.220 +}
   1.221 +
   1.222 +void symbolKlass::oop_print_value_on(oop obj, outputStream* st) {
   1.223 +  symbolOop sym = symbolOop(obj);
   1.224 +  st->print("'");
   1.225 +  for (int i = 0; i < sym->utf8_length(); i++) {
   1.226 +    st->print("%c", sym->byte_at(i));
   1.227 +  }
   1.228 +  st->print("'");
   1.229 +}
   1.230 +
   1.231 +#endif //PRODUCT
   1.232 +
   1.233 +const char* symbolKlass::internal_name() const {
   1.234 +  return "{symbol}";
   1.235 +}

mercurial