1 /*
   2  * Copyright (c) 2000, 2008, 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/_methodDataKlass.cpp.incl"
  27 
  28 klassOop methodDataKlass::create_klass(TRAPS) {
  29   methodDataKlass o;
  30   KlassHandle h_this_klass(THREAD, Universe::klassKlassObj());
  31   KlassHandle k = base_create_klass(h_this_klass, header_size(),
  32                                     o.vtbl_value(), CHECK_NULL);
  33   // Make sure size calculation is right
  34   assert(k()->size() == align_object_size(header_size()),
  35          "wrong size for object");
  36   return k();
  37 }
  38 
  39 
  40 int methodDataKlass::oop_size(oop obj) const {
  41   assert(obj->is_methodData(), "must be method data oop");
  42   return methodDataOop(obj)->object_size();
  43 }
  44 
  45 
  46 bool methodDataKlass::oop_is_parsable(oop obj) const {
  47   assert(obj->is_methodData(), "must be method data oop");
  48   return methodDataOop(obj)->object_is_parsable();
  49 }
  50 
  51 
  52 methodDataOop methodDataKlass::allocate(methodHandle method, TRAPS) {
  53   int size = methodDataOopDesc::compute_allocation_size_in_words(method);
  54   KlassHandle h_k(THREAD, as_klassOop());
  55   methodDataOop mdo =
  56     (methodDataOop)CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL);
  57   assert(!mdo->is_parsable(), "not expecting parsability yet.");
  58   No_Safepoint_Verifier no_safepoint;  // init function atomic wrt GC
  59   mdo->initialize(method);
  60 
  61   assert(mdo->is_parsable(), "should be parsable here.");
  62   assert(size == mdo->object_size(), "wrong size for methodDataOop");
  63   return mdo;
  64 }
  65 
  66 
  67 void methodDataKlass::oop_follow_contents(oop obj) {
  68   assert (obj->is_methodData(), "object must be method data");
  69   methodDataOop m = methodDataOop(obj);
  70 
  71   obj->follow_header();
  72   MarkSweep::mark_and_push(m->adr_method());
  73   ResourceMark rm;
  74   for (ProfileData* data = m->first_data();
  75        m->is_valid(data);
  76        data = m->next_data(data)) {
  77     data->follow_contents();
  78   }
  79 }
  80 
  81 #ifndef SERIALGC
  82 void methodDataKlass::oop_follow_contents(ParCompactionManager* cm,
  83                                           oop obj) {
  84   assert (obj->is_methodData(), "object must be method data");
  85   methodDataOop m = methodDataOop(obj);
  86 
  87   obj->follow_header(cm);
  88   PSParallelCompact::mark_and_push(cm, m->adr_method());
  89   ResourceMark rm;
  90   for (ProfileData* data = m->first_data();
  91        m->is_valid(data);
  92        data = m->next_data(data)) {
  93     data->follow_contents(cm);
  94   }
  95 }
  96 #endif // SERIALGC
  97 
  98 
  99 int methodDataKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
 100   assert (obj->is_methodData(), "object must be method data");
 101   methodDataOop m = methodDataOop(obj);
 102   // Get size before changing pointers
 103   // Don't call size() or oop_size() since that is a virtual call.
 104   int size = m->object_size();
 105 
 106   obj->oop_iterate_header(blk);
 107   blk->do_oop(m->adr_method());
 108   ResourceMark rm;
 109   for (ProfileData* data = m->first_data();
 110        m->is_valid(data);
 111        data = m->next_data(data)) {
 112     data->oop_iterate(blk);
 113   }
 114   return size;
 115 }
 116 
 117 int methodDataKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) {
 118   assert (obj->is_methodData(), "object must be method data");
 119   methodDataOop m = methodDataOop(obj);
 120   // Get size before changing pointers
 121   // Don't call size() or oop_size() since that is a virtual call.
 122   int size = m->object_size();
 123 
 124   obj->oop_iterate_header(blk, mr);
 125   oop* adr = m->adr_method();
 126   if (mr.contains(adr)) {
 127     blk->do_oop(m->adr_method());
 128   }
 129   ResourceMark rm;
 130   for (ProfileData* data = m->first_data();
 131        m->is_valid(data);
 132        data = m->next_data(data)) {
 133     data->oop_iterate_m(blk, mr);
 134   }
 135   return size;
 136 }
 137 
 138 int methodDataKlass::oop_adjust_pointers(oop obj) {
 139   assert(obj->is_methodData(), "should be method data");
 140   methodDataOop m = methodDataOop(obj);
 141   // Get size before changing pointers
 142   // Don't call size() or oop_size() since that is a virtual call.
 143   int size = m->object_size();
 144 
 145   obj->adjust_header();
 146   MarkSweep::adjust_pointer(m->adr_method());
 147   ResourceMark rm;
 148   ProfileData* data;
 149   for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
 150     data->adjust_pointers();
 151   }
 152   return size;
 153 }
 154 
 155 
 156 #ifndef SERIALGC
 157 void methodDataKlass::oop_push_contents(PSPromotionManager* pm, oop obj) {
 158   assert (obj->is_methodData(), "object must be method data");
 159   methodDataOop m = methodDataOop(obj);
 160   // This should never point into the young gen.
 161   assert(!PSScavenge::should_scavenge(m->adr_method()), "Sanity");
 162 }
 163 
 164 int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
 165   assert(obj->is_methodData(), "should be method data");
 166   methodDataOop m = methodDataOop(obj);
 167 
 168   PSParallelCompact::adjust_pointer(m->adr_method());
 169 
 170   ResourceMark rm;
 171   ProfileData* data;
 172   for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
 173     data->update_pointers();
 174   }
 175   return m->object_size();
 176 }
 177 
 178 int
 179 methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj,
 180                                      HeapWord* beg_addr, HeapWord* end_addr) {
 181   assert(obj->is_methodData(), "should be method data");
 182 
 183   oop* p;
 184   methodDataOop m = methodDataOop(obj);
 185 
 186   p = m->adr_method();
 187   PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
 188 
 189   ResourceMark rm;
 190   ProfileData* data;
 191   for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
 192     data->update_pointers(beg_addr, end_addr);
 193   }
 194   return m->object_size();
 195 }
 196 #endif // SERIALGC
 197 
 198 #ifndef PRODUCT
 199 
 200 // Printing
 201 void methodDataKlass::oop_print_on(oop obj, outputStream* st) {
 202   assert(obj->is_methodData(), "should be method data");
 203   methodDataOop m = methodDataOop(obj);
 204   st->print("method data for ");
 205   m->method()->print_value_on(st);
 206   st->cr();
 207   m->print_data_on(st);
 208 }
 209 
 210 #endif //PRODUCT
 211 
 212 void methodDataKlass::oop_print_value_on(oop obj, outputStream* st) {
 213   assert(obj->is_methodData(), "should be method data");
 214   methodDataOop m = methodDataOop(obj);
 215   st->print("method data for ");
 216   m->method()->print_value_on(st);
 217 }
 218 
 219 const char* methodDataKlass::internal_name() const {
 220   return "{method data}";
 221 }
 222 
 223 
 224 // Verification
 225 void methodDataKlass::oop_verify_on(oop obj, outputStream* st) {
 226   Klass::oop_verify_on(obj, st);
 227   guarantee(obj->is_methodData(), "object must be method data");
 228   methodDataOop m = methodDataOop(obj);
 229   guarantee(m->is_perm(), "should be in permspace");
 230   m->verify_data_on(st);
 231 }