1 /*
   2  * Copyright (c) 1997, 2006, 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  */
  24 
  25 # include "incls/_precompiled.incl"
  26 # include "incls/_symbolKlass.cpp.incl"
  27 
  28 symbolOop symbolKlass::allocate_symbol(u1* name, int len, TRAPS) {
  29   // Don't allow symbol oops to be created which cannot fit in a symbolOop.
  30   if (len > symbolOopDesc::max_length()) {
  31     THROW_MSG_0(vmSymbols::java_lang_InternalError(),
  32                 "name is too long to represent");
  33   }
  34   int size = symbolOopDesc::object_size(len);
  35   symbolKlassHandle h_k(THREAD, as_klassOop());
  36   symbolOop sym = (symbolOop)
  37     CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
  38   assert(!sym->is_parsable(), "not expecting parsability yet.");
  39   No_Safepoint_Verifier no_safepoint;
  40   sym->set_utf8_length(len);
  41   for (int i = 0; i < len; i++) {
  42     sym->byte_at_put(i, name[i]);
  43   }
  44   // Let the first emptySymbol be created and
  45   // ensure only one is ever created.
  46   assert(sym->is_parsable() || Universe::emptySymbol() == NULL,
  47          "should be parsable here.");
  48   return sym;
  49 }
  50 
  51 bool symbolKlass::allocate_symbols(int names_count, const char** names,
  52                                    int* lengths, symbolOop* sym_oops, TRAPS) {
  53   if (UseConcMarkSweepGC || UseParallelGC) {
  54     // Concurrent GC needs to mark all the allocated symbol oops after
  55     // the remark phase which isn't done below (except the first symbol oop).
  56     // So return false which will let the symbols be allocated one by one.
  57     // The parallel collector uses an object start array to find the
  58     // start of objects on a dirty card.  The object start array is not
  59     // updated for the start of each symbol so is not precise.  During
  60     // object array verification this causes a verification failure.
  61     // In a product build this causes extra searching for the start of
  62     // a symbol.  As with the concurrent collector a return of false will
  63     // cause each symbol to be allocated separately and in the case
  64     // of the parallel collector will cause the object
  65     // start array to be updated.
  66     return false;
  67   }
  68 
  69   assert(names_count > 0, "can't allocate 0 symbols");
  70 
  71   int total_size = 0;
  72   int i, sizes[SymbolTable::symbol_alloc_batch_size];
  73   for (i=0; i<names_count; i++) {
  74     int len = lengths[i];
  75     if (len > symbolOopDesc::max_length()) {
  76       return false;
  77     }
  78     int sz = symbolOopDesc::object_size(len);
  79     sizes[i] = sz * HeapWordSize;
  80     total_size += sz;
  81   }
  82   symbolKlassHandle h_k(THREAD, as_klassOop());
  83   HeapWord* base = Universe::heap()->permanent_mem_allocate(total_size);
  84   if (base == NULL) {
  85     return false;
  86   }
  87 
  88   // CAN'T take any safepoint during the initialization of the symbol oops !
  89   No_Safepoint_Verifier nosafepoint;
  90 
  91   klassOop sk = h_k();
  92   int pos = 0;
  93   for (i=0; i<names_count; i++) {
  94     symbolOop s = (symbolOop) (((char*)base) + pos);
  95     s->set_mark(markOopDesc::prototype());
  96     s->set_klass(sk);
  97     s->set_utf8_length(lengths[i]);
  98     const char* name = names[i];
  99     for (int j=0; j<lengths[i]; j++) {
 100       s->byte_at_put(j, name[j]);
 101     }
 102 
 103     assert(s->is_parsable(), "should be parsable here.");
 104 
 105     sym_oops[i] = s;
 106     pos += sizes[i];
 107   }
 108   return true;
 109 }
 110 
 111 klassOop symbolKlass::create_klass(TRAPS) {
 112   symbolKlass o;
 113   KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
 114   KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
 115   // Make sure size calculation is right
 116   assert(k()->size() == align_object_size(header_size()), "wrong size for object");
 117 //  java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
 118   return k();
 119 }
 120 
 121 int symbolKlass::oop_size(oop obj) const {
 122   assert(obj->is_symbol(),"must be a symbol");
 123   symbolOop s = symbolOop(obj);
 124   int size = s->object_size();
 125   return size;
 126 }
 127 
 128 bool symbolKlass::oop_is_parsable(oop obj) const {
 129   assert(obj->is_symbol(),"must be a symbol");
 130   symbolOop s = symbolOop(obj);
 131   return s->object_is_parsable();
 132 }
 133 
 134 void symbolKlass::oop_follow_contents(oop obj) {
 135   assert (obj->is_symbol(), "object must be symbol");
 136   // Performance tweak: We skip iterating over the klass pointer since we
 137   // know that Universe::symbolKlassObj never moves.
 138   // Note: do not follow next link here (see SymbolTable::follow_contents)
 139 }
 140 
 141 #ifndef SERIALGC
 142 void symbolKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) {
 143   assert (obj->is_symbol(), "object must be symbol");
 144   // Performance tweak: We skip iterating over the klass pointer since we
 145   // know that Universe::symbolKlassObj never moves.
 146   // Note: do not follow next link here (see SymbolTable::follow_contents)
 147 }
 148 #endif // SERIALGC
 149 
 150 int symbolKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
 151   assert(obj->is_symbol(), "object must be symbol");
 152   symbolOop s = symbolOop(obj);
 153   // Get size before changing pointers.
 154   // Don't call size() or oop_size() since that is a virtual call.
 155   int size = s->object_size();
 156   // Performance tweak: We skip iterating over the klass pointer since we
 157   // know that Universe::symbolKlassObj never moves.
 158   return size;
 159 }
 160 
 161 
 162 int symbolKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
 163   assert(obj->is_symbol(), "object must be symbol");
 164   symbolOop s = symbolOop(obj);
 165   // Get size before changing pointers.
 166   // Don't call size() or oop_size() since that is a virtual call.
 167   int size = s->object_size();
 168   // Performance tweak: We skip iterating over the klass pointer since we
 169   // know that Universe::symbolKlassObj never moves.
 170   return size;
 171 }
 172 
 173 
 174 int symbolKlass::oop_adjust_pointers(oop obj) {
 175   assert(obj->is_symbol(), "should be symbol");
 176   symbolOop s = symbolOop(obj);
 177   // Get size before changing pointers.
 178   // Don't call size() or oop_size() since that is a virtual call.
 179   int size = s->object_size();
 180   // Performance tweak: We skip iterating over the klass pointer since we
 181   // know that Universe::symbolKlassObj never moves.
 182   return size;
 183 }
 184 
 185 
 186 #ifndef SERIALGC
 187 void symbolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
 188   assert(obj->is_symbol(), "should be symbol");
 189 }
 190 
 191 int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
 192   assert(obj->is_symbol(), "should be symbol");
 193   return symbolOop(obj)->object_size();
 194 }
 195 
 196 int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
 197                                      HeapWord* beg_addr, HeapWord* end_addr) {
 198   assert(obj->is_symbol(), "should be symbol");
 199   return symbolOop(obj)->object_size();
 200 }
 201 #endif // SERIALGC
 202 
 203 #ifndef PRODUCT
 204 // Printing
 205 
 206 void symbolKlass::oop_print_on(oop obj, outputStream* st) {
 207   st->print("Symbol: '");
 208   symbolOop(obj)->print_symbol_on(st);
 209   st->print("'");
 210 }
 211 
 212 #endif //PRODUCT
 213 
 214 void symbolKlass::oop_print_value_on(oop obj, outputStream* st) {
 215   symbolOop sym = symbolOop(obj);
 216   st->print("'");
 217   for (int i = 0; i < sym->utf8_length(); i++) {
 218     st->print("%c", sym->byte_at(i));
 219   }
 220   st->print("'");
 221 }
 222 
 223 const char* symbolKlass::internal_name() const {
 224   return "{symbol}";
 225 }