diff src/share/vm/oops/symbolKlass.cpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children 2a1a77d3458f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/oops/symbolKlass.cpp	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,232 @@
+/*
+ * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+# include "incls/_precompiled.incl"
+# include "incls/_symbolKlass.cpp.incl"
+
+symbolOop symbolKlass::allocate_symbol(u1* name, int len, TRAPS) {
+  // Don't allow symbol oops to be created which cannot fit in a symbolOop.
+  if (len > symbolOopDesc::max_length()) {
+    THROW_MSG_0(vmSymbols::java_lang_InternalError(),
+                "name is too long to represent");
+  }
+  int size = symbolOopDesc::object_size(len);
+  symbolKlassHandle h_k(THREAD, as_klassOop());
+  symbolOop sym = (symbolOop)
+    CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
+  assert(!sym->is_parsable(), "not expecting parsability yet.");
+  No_Safepoint_Verifier no_safepoint;
+  sym->set_utf8_length(len);
+  for (int i = 0; i < len; i++) {
+    sym->byte_at_put(i, name[i]);
+  }
+  // Let the first emptySymbol be created and
+  // ensure only one is ever created.
+  assert(sym->is_parsable() || Universe::emptySymbol() == NULL,
+         "should be parsable here.");
+  return sym;
+}
+
+bool symbolKlass::allocate_symbols(int names_count, const char** names,
+                                   int* lengths, symbolOop* sym_oops, TRAPS) {
+  if (UseConcMarkSweepGC || UseParallelGC) {
+    // Concurrent GC needs to mark all the allocated symbol oops after
+    // the remark phase which isn't done below (except the first symbol oop).
+    // So return false which will let the symbols be allocated one by one.
+    // The parallel collector uses an object start array to find the
+    // start of objects on a dirty card.  The object start array is not
+    // updated for the start of each symbol so is not precise.  During
+    // object array verification this causes a verification failure.
+    // In a product build this causes extra searching for the start of
+    // a symbol.  As with the concurrent collector a return of false will
+    // cause each symbol to be allocated separately and in the case
+    // of the parallel collector will cause the object
+    // start array to be updated.
+    return false;
+  }
+
+  assert(names_count > 0, "can't allocate 0 symbols");
+
+  int total_size = 0;
+  int i, sizes[SymbolTable::symbol_alloc_batch_size];
+  for (i=0; i<names_count; i++) {
+    int len = lengths[i];
+    if (len > symbolOopDesc::max_length()) {
+      return false;
+    }
+    int sz = symbolOopDesc::object_size(len);
+    sizes[i] = sz * HeapWordSize;
+    total_size += sz;
+  }
+  symbolKlassHandle h_k(THREAD, as_klassOop());
+  HeapWord* base = Universe::heap()->permanent_mem_allocate(total_size);
+  if (base == NULL) {
+    return false;
+  }
+
+  // CAN'T take any safepoint during the initialization of the symbol oops !
+  No_Safepoint_Verifier nosafepoint;
+
+  klassOop sk = h_k();
+  int pos = 0;
+  for (i=0; i<names_count; i++) {
+    symbolOop s = (symbolOop) (((char*)base) + pos);
+    s->set_mark(markOopDesc::prototype());
+    s->set_klass(sk);
+    s->set_utf8_length(lengths[i]);
+    const char* name = names[i];
+    for (int j=0; j<lengths[i]; j++) {
+      s->byte_at_put(j, name[j]);
+    }
+
+    assert(s->is_parsable(), "should be parsable here.");
+
+    sym_oops[i] = s;
+    pos += sizes[i];
+  }
+  return true;
+}
+
+klassOop symbolKlass::create_klass(TRAPS) {
+  symbolKlass o;
+  KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
+  KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL);
+  // Make sure size calculation is right
+  assert(k()->size() == align_object_size(header_size()), "wrong size for object");
+//  java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror
+  return k();
+}
+
+int symbolKlass::oop_size(oop obj) const {
+  assert(obj->is_symbol(),"must be a symbol");
+  symbolOop s = symbolOop(obj);
+  int size = s->object_size();
+  return size;
+}
+
+bool symbolKlass::oop_is_parsable(oop obj) const {
+  assert(obj->is_symbol(),"must be a symbol");
+  symbolOop s = symbolOop(obj);
+  return s->object_is_parsable();
+}
+
+void symbolKlass::oop_follow_contents(oop obj) {
+  assert (obj->is_symbol(), "object must be symbol");
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::symbolKlassObj never moves.
+  // Note: do not follow next link here (see SymbolTable::follow_contents)
+}
+
+#ifndef SERIALGC
+void symbolKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) {
+  assert (obj->is_symbol(), "object must be symbol");
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::symbolKlassObj never moves.
+  // Note: do not follow next link here (see SymbolTable::follow_contents)
+}
+#endif // SERIALGC
+
+int symbolKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
+  assert(obj->is_symbol(), "object must be symbol");
+  symbolOop s = symbolOop(obj);
+  // Get size before changing pointers.
+  // Don't call size() or oop_size() since that is a virtual call.
+  int size = s->object_size();
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::symbolKlassObj never moves.
+  return size;
+}
+
+
+int symbolKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
+  assert(obj->is_symbol(), "object must be symbol");
+  symbolOop s = symbolOop(obj);
+  // Get size before changing pointers.
+  // Don't call size() or oop_size() since that is a virtual call.
+  int size = s->object_size();
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::symbolKlassObj never moves.
+  return size;
+}
+
+
+int symbolKlass::oop_adjust_pointers(oop obj) {
+  assert(obj->is_symbol(), "should be symbol");
+  symbolOop s = symbolOop(obj);
+  // Get size before changing pointers.
+  // Don't call size() or oop_size() since that is a virtual call.
+  int size = s->object_size();
+  // Performance tweak: We skip iterating over the klass pointer since we
+  // know that Universe::symbolKlassObj never moves.
+  return size;
+}
+
+
+#ifndef SERIALGC
+void symbolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
+  assert(obj->is_symbol(), "should be symbol");
+}
+
+void symbolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
+  assert(obj->is_symbol(), "should be symbol");
+}
+
+int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
+  assert(obj->is_symbol(), "should be symbol");
+  return symbolOop(obj)->object_size();
+}
+
+int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
+                                     HeapWord* beg_addr, HeapWord* end_addr) {
+  assert(obj->is_symbol(), "should be symbol");
+  return symbolOop(obj)->object_size();
+}
+#endif // SERIALGC
+
+#ifndef PRODUCT
+// Printing
+
+void symbolKlass::oop_print_on(oop obj, outputStream* st) {
+  st->print("Symbol: '");
+  symbolOop sym = symbolOop(obj);
+  for (int i = 0; i < sym->utf8_length(); i++) {
+    st->print("%c", sym->byte_at(i));
+  }
+  st->print("'");
+}
+
+void symbolKlass::oop_print_value_on(oop obj, outputStream* st) {
+  symbolOop sym = symbolOop(obj);
+  st->print("'");
+  for (int i = 0; i < sym->utf8_length(); i++) {
+    st->print("%c", sym->byte_at(i));
+  }
+  st->print("'");
+}
+
+#endif //PRODUCT
+
+const char* symbolKlass::internal_name() const {
+  return "{symbol}";
+}