1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)methodDataKlass.cpp  1.36 07/05/29 09:44:22 JVM"
   3 #endif
   4 /*
   5  * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  
  26  */
  27 
  28 # include "incls/_precompiled.incl"
  29 # include "incls/_methodDataKlass.cpp.incl"
  30 
  31 klassOop methodDataKlass::create_klass(TRAPS) {
  32   methodDataKlass o;
  33   KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());  
  34   KlassHandle k = base_create_klass(h_this_klass, header_size(),
  35                                     o.vtbl_value(), CHECK_NULL);
  36   // Make sure size calculation is right
  37   assert(k()->size() == align_object_size(header_size()),
  38          "wrong size for object");
  39   return k();
  40 }
  41 
  42 
  43 int methodDataKlass::oop_size(oop obj) const {
  44   assert(obj->is_methodData(), "must be method data oop");
  45   return methodDataOop(obj)->object_size();
  46 }
  47 
  48 
  49 bool methodDataKlass::oop_is_parsable(oop obj) const {
  50   assert(obj->is_methodData(), "must be method data oop");
  51   return methodDataOop(obj)->object_is_parsable();
  52 }
  53 
  54 
  55 methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) {
  56   int size = methodDataOopDesc::compute_allocation_size_in_words(method);
  57   KlassHandle h_k(THREAD, as_klassOop());
  58   methodDataOop mdo =
  59     (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
  60   assert(!mdo->is_parsable(), "not expecting parsability yet.");
  61   No_Safepoint_Verifier no_safepoint;  // init function atomic wrt GC
  62   mdo->initialize(method);
  63 
  64   assert(mdo->is_parsable(), "should be parsable here.");
  65   assert(size == mdo->object_size(), "wrong size for methodDataOop");
  66   return mdo;
  67 }
  68 
  69 
  70 void methodDataKlass::oop_follow_contents(oop obj) {
  71   assert (obj->is_methodData(), "object must be method data");
  72   methodDataOop m = methodDataOop(obj);
  73 
  74   obj->follow_header();
  75   MarkSweep::mark_and_push(m->adr_method());
  76   ResourceMark rm;
  77   for (ProfileData* data = m->first_data(); 
  78        m->is_valid(data); 
  79        data = m->next_data(data)) {
  80     data->follow_contents();
  81   }
  82 }
  83 
  84 #ifndef SERIALGC
  85 void methodDataKlass::oop_follow_contents(ParCompactionManager* cm,
  86                                           oop obj) {
  87   assert (obj->is_methodData(), "object must be method data");
  88   methodDataOop m = methodDataOop(obj);
  89 
  90   obj->follow_header(cm);
  91   PSParallelCompact::mark_and_push(cm, m->adr_method());
  92   ResourceMark rm;
  93   for (ProfileData* data = m->first_data(); 
  94        m->is_valid(data); 
  95        data = m->next_data(data)) {
  96     data->follow_contents(cm);
  97   }
  98 }
  99 #endif // SERIALGC
 100 
 101 int methodDataKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
 102   assert (obj->is_methodData(), "object must be method data");
 103   methodDataOop m = methodDataOop(obj);
 104   // Get size before changing pointers
 105   // Don't call size() or oop_size() since that is a virtual call.
 106   int size = m->object_size();
 107 
 108   obj->oop_iterate_header(blk);
 109   blk->do_oop(m->adr_method());
 110   ResourceMark rm;
 111   for (ProfileData* data = m->first_data(); 
 112        m->is_valid(data);
 113        data = m->next_data(data)) {
 114     data->oop_iterate(blk);
 115   }
 116   return size;
 117 }
 118 
 119 
 120 int methodDataKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
 121   assert (obj->is_methodData(), "object must be method data");
 122   methodDataOop m = methodDataOop(obj);
 123   // Get size before changing pointers
 124   // Don't call size() or oop_size() since that is a virtual call.
 125   int size = m->object_size();
 126 
 127   obj->oop_iterate_header(blk, mr);
 128   oop* adr = m->adr_method();
 129   if (mr.contains(adr)) {
 130     blk->do_oop(m->adr_method());
 131   }
 132   ResourceMark rm;
 133   for (ProfileData* data = m->first_data(); 
 134        m->is_valid(data);
 135        data = m->next_data(data)) {
 136     data->oop_iterate_m(blk, mr);
 137   }
 138   return size;
 139 }
 140 
 141 int methodDataKlass::oop_adjust_pointers(oop obj) {
 142   assert(obj->is_methodData(), "should be method data");
 143   methodDataOop m = methodDataOop(obj);
 144   // Get size before changing pointers
 145   // Don't call size() or oop_size() since that is a virtual call.
 146   int size = m->object_size();
 147 
 148   obj->adjust_header();
 149   MarkSweep::adjust_pointer(m->adr_method());
 150   ResourceMark rm;
 151   ProfileData* data;
 152   for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
 153     data->adjust_pointers();
 154   }
 155   return size;
 156 }
 157 
 158 
 159 #ifndef SERIALGC
 160 void methodDataKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) {
 161   assert (obj->is_methodData(), "object must be method data");
 162   methodDataOop m = methodDataOop(obj);  
 163   // This should never point into the young gen.
 164   assert(!PSScavenge::should_scavenge(oop(*m->adr_method())), "Sanity");
 165 }
 166 
 167 void methodDataKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
 168   assert (obj->is_methodData(), "object must be method data");
 169   methodDataOop m = methodDataOop(obj);  
 170   // This should never point into the young gen.
 171   assert(!PSScavenge::should_scavenge(oop(*m->adr_method())), "Sanity");
 172 }
 173 
 174 int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
 175   assert(obj->is_methodData(), "should be method data");
 176   methodDataOop m = methodDataOop(obj);
 177 
 178   PSParallelCompact::adjust_pointer(m->adr_method());
 179 
 180   ResourceMark rm;
 181   ProfileData* data;
 182   for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
 183     data->update_pointers();
 184   }
 185   return m->object_size();
 186 }
 187 
 188 int
 189 methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
 190                                      HeapWord* beg_addr, HeapWord* end_addr) {
 191   assert(obj->is_methodData(), "should be method data");
 192 
 193   oop* p;
 194   methodDataOop m = methodDataOop(obj);
 195 
 196   p = m->adr_method();
 197   PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
 198 
 199   ResourceMark rm;
 200   ProfileData* data;
 201   for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
 202     data->update_pointers(beg_addr, end_addr);
 203   }
 204   return m->object_size();
 205 }
 206 #endif // SERIALGC
 207 
 208 #ifndef PRODUCT
 209 
 210 // Printing
 211 void methodDataKlass::oop_print_on(oop obj, outputStream* st) {
 212   assert(obj->is_methodData(), "should be method data");
 213   methodDataOop m = methodDataOop(obj);
 214   st->print("method data for ");
 215   m->method()->print_value_on(st);
 216   st->cr();
 217   m->print_data_on(st);
 218 }
 219 
 220 void methodDataKlass::oop_print_value_on(oop obj, outputStream* st) {
 221   assert(obj->is_methodData(), "should be method data");
 222   methodDataOop m = methodDataOop(obj);
 223   st->print("method data for ");
 224   m->method()->print_value_on(st);
 225 }
 226 
 227 #endif // !PRODUCT
 228 
 229 const char* methodDataKlass::internal_name() const {
 230   return "{method data}";
 231 }
 232 
 233 
 234 // Verification
 235 void methodDataKlass::oop_verify_on(oop obj, outputStream* st) {
 236   Klass::oop_verify_on(obj, st);
 237   guarantee(obj->is_methodData(), "object must be method data");
 238   methodDataOop m = methodDataOop(obj);
 239   guarantee(m->is_perm(), "should be in permspace");
 240   m->verify_data_on(st);
 241 }
 242