src/share/vm/ci/ciMethodData.cpp

Thu, 27 May 2010 19:08:38 -0700

author
trims
date
Thu, 27 May 2010 19:08:38 -0700
changeset 1907
c18cbe5936b8
parent 631
d1605aabd0a1
child 2138
d5d065957597
permissions
-rw-r--r--

6941466: Oracle rebranding changes for Hotspot repositories
Summary: Change all the Sun copyrights to Oracle copyright
Reviewed-by: ohair

     1 /*
     2  * Copyright (c) 2001, 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  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_ciMethodData.cpp.incl"
    28 // ciMethodData
    30 // ------------------------------------------------------------------
    31 // ciMethodData::ciMethodData
    32 //
    33 ciMethodData::ciMethodData(methodDataHandle h_md) : ciObject(h_md) {
    34   assert(h_md() != NULL, "no null method data");
    35   Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
    36   _data = NULL;
    37   _data_size = 0;
    38   _extra_data_size = 0;
    39   _current_mileage = 0;
    40   _state = empty_state;
    41   _saw_free_extra_data = false;
    42   // Set an initial hint. Don't use set_hint_di() because
    43   // first_di() may be out of bounds if data_size is 0.
    44   _hint_di = first_di();
    45   // Initialize the escape information (to "don't know.");
    46   _eflags = _arg_local = _arg_stack = _arg_returned = 0;
    47 }
    49 // ------------------------------------------------------------------
    50 // ciMethodData::ciMethodData
    51 //
    52 // No methodDataOop.
    53 ciMethodData::ciMethodData() : ciObject() {
    54   Copy::zero_to_words((HeapWord*) &_orig, sizeof(_orig) / sizeof(HeapWord));
    55   _data = NULL;
    56   _data_size = 0;
    57   _extra_data_size = 0;
    58   _current_mileage = 0;
    59   _state = empty_state;
    60   _saw_free_extra_data = false;
    61   // Set an initial hint. Don't use set_hint_di() because
    62   // first_di() may be out of bounds if data_size is 0.
    63   _hint_di = first_di();
    64   // Initialize the escape information (to "don't know.");
    65   _eflags = _arg_local = _arg_stack = _arg_returned = 0;
    66 }
    68 void ciMethodData::load_data() {
    69   methodDataOop mdo = get_methodDataOop();
    70   if (mdo == NULL) return;
    72   // To do: don't copy the data if it is not "ripe" -- require a minimum #
    73   // of invocations.
    75   // Snapshot the data -- actually, take an approximate snapshot of
    76   // the data.  Any concurrently executing threads may be changing the
    77   // data as we copy it.
    78   int skip_header = oopDesc::header_size();
    79   Copy::disjoint_words((HeapWord*) mdo              + skip_header,
    80                        (HeapWord*) &_orig           + skip_header,
    81                        sizeof(_orig) / HeapWordSize - skip_header);
    82   DEBUG_ONLY(*_orig.adr_method() = NULL);  // no dangling oops, please
    83   Arena* arena = CURRENT_ENV->arena();
    84   _data_size = mdo->data_size();
    85   _extra_data_size = mdo->extra_data_size();
    86   int total_size = _data_size + _extra_data_size;
    87   _data = (intptr_t *) arena->Amalloc(total_size);
    88   Copy::disjoint_words((HeapWord*) mdo->data_base(), (HeapWord*) _data, total_size / HeapWordSize);
    90   // Traverse the profile data, translating any oops into their
    91   // ci equivalents.
    92   ResourceMark rm;
    93   ciProfileData* ci_data = first_data();
    94   ProfileData* data = mdo->first_data();
    95   while (is_valid(ci_data)) {
    96     ci_data->translate_from(data);
    97     ci_data = next_data(ci_data);
    98     data = mdo->next_data(data);
    99   }
   100   // Note:  Extra data are all BitData, and do not need translation.
   101   _current_mileage = methodDataOopDesc::mileage_of(mdo->method());
   102   _state = mdo->is_mature()? mature_state: immature_state;
   104   _eflags = mdo->eflags();
   105   _arg_local = mdo->arg_local();
   106   _arg_stack = mdo->arg_stack();
   107   _arg_returned  = mdo->arg_returned();
   108 }
   110 void ciReceiverTypeData::translate_receiver_data_from(ProfileData* data) {
   111   for (uint row = 0; row < row_limit(); row++) {
   112     klassOop k = data->as_ReceiverTypeData()->receiver(row);
   113     if (k != NULL) {
   114       ciKlass* klass = CURRENT_ENV->get_object(k)->as_klass();
   115       set_receiver(row, klass);
   116     }
   117   }
   118 }
   121 // Get the data at an arbitrary (sort of) data index.
   122 ciProfileData* ciMethodData::data_at(int data_index) {
   123   if (out_of_bounds(data_index)) {
   124     return NULL;
   125   }
   126   DataLayout* data_layout = data_layout_at(data_index);
   128   switch (data_layout->tag()) {
   129   case DataLayout::no_tag:
   130   default:
   131     ShouldNotReachHere();
   132     return NULL;
   133   case DataLayout::bit_data_tag:
   134     return new ciBitData(data_layout);
   135   case DataLayout::counter_data_tag:
   136     return new ciCounterData(data_layout);
   137   case DataLayout::jump_data_tag:
   138     return new ciJumpData(data_layout);
   139   case DataLayout::receiver_type_data_tag:
   140     return new ciReceiverTypeData(data_layout);
   141   case DataLayout::virtual_call_data_tag:
   142     return new ciVirtualCallData(data_layout);
   143   case DataLayout::ret_data_tag:
   144     return new ciRetData(data_layout);
   145   case DataLayout::branch_data_tag:
   146     return new ciBranchData(data_layout);
   147   case DataLayout::multi_branch_data_tag:
   148     return new ciMultiBranchData(data_layout);
   149   case DataLayout::arg_info_data_tag:
   150     return new ciArgInfoData(data_layout);
   151   };
   152 }
   154 // Iteration over data.
   155 ciProfileData* ciMethodData::next_data(ciProfileData* current) {
   156   int current_index = dp_to_di(current->dp());
   157   int next_index = current_index + current->size_in_bytes();
   158   ciProfileData* next = data_at(next_index);
   159   return next;
   160 }
   162 // Translate a bci to its corresponding data, or NULL.
   163 ciProfileData* ciMethodData::bci_to_data(int bci) {
   164   ciProfileData* data = data_before(bci);
   165   for ( ; is_valid(data); data = next_data(data)) {
   166     if (data->bci() == bci) {
   167       set_hint_di(dp_to_di(data->dp()));
   168       return data;
   169     } else if (data->bci() > bci) {
   170       break;
   171     }
   172   }
   173   // bci_to_extra_data(bci) ...
   174   DataLayout* dp  = data_layout_at(data_size());
   175   DataLayout* end = data_layout_at(data_size() + extra_data_size());
   176   for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) {
   177     if (dp->tag() == DataLayout::no_tag) {
   178       _saw_free_extra_data = true;  // observed an empty slot (common case)
   179       return NULL;
   180     }
   181     if (dp->tag() == DataLayout::arg_info_data_tag) {
   182       break; // ArgInfoData is at the end of extra data section.
   183     }
   184     if (dp->bci() == bci) {
   185       assert(dp->tag() == DataLayout::bit_data_tag, "sane");
   186       return new ciBitData(dp);
   187     }
   188   }
   189   return NULL;
   190 }
   192 // Conservatively decode the trap_state of a ciProfileData.
   193 int ciMethodData::has_trap_at(ciProfileData* data, int reason) {
   194   typedef Deoptimization::DeoptReason DR_t;
   195   int per_bc_reason
   196     = Deoptimization::reason_recorded_per_bytecode_if_any((DR_t) reason);
   197   if (trap_count(reason) == 0) {
   198     // Impossible for this trap to have occurred, regardless of trap_state.
   199     // Note:  This happens if the MDO is empty.
   200     return 0;
   201   } else if (per_bc_reason == Deoptimization::Reason_none) {
   202     // We cannot conclude anything; a trap happened somewhere, maybe here.
   203     return -1;
   204   } else if (data == NULL) {
   205     // No profile here, not even an extra_data record allocated on the fly.
   206     // If there are empty extra_data records, and there had been a trap,
   207     // there would have been a non-null data pointer.  If there are no
   208     // free extra_data records, we must return a conservative -1.
   209     if (_saw_free_extra_data)
   210       return 0;                 // Q.E.D.
   211     else
   212       return -1;                // bail with a conservative answer
   213   } else {
   214     return Deoptimization::trap_state_has_reason(data->trap_state(), per_bc_reason);
   215   }
   216 }
   218 int ciMethodData::trap_recompiled_at(ciProfileData* data) {
   219   if (data == NULL) {
   220     return (_saw_free_extra_data? 0: -1);  // (see previous method)
   221   } else {
   222     return Deoptimization::trap_state_is_recompiled(data->trap_state())? 1: 0;
   223   }
   224 }
   226 void ciMethodData::clear_escape_info() {
   227   VM_ENTRY_MARK;
   228   methodDataOop mdo = get_methodDataOop();
   229   if (mdo != NULL) {
   230     mdo->clear_escape_info();
   231     ArgInfoData *aid = arg_info();
   232     int arg_count = (aid == NULL) ? 0 : aid->number_of_args();
   233     for (int i = 0; i < arg_count; i++) {
   234       set_arg_modified(i, 0);
   235     }
   236   }
   237   _eflags = _arg_local = _arg_stack = _arg_returned = 0;
   238 }
   240 // copy our escape info to the methodDataOop if it exists
   241 void ciMethodData::update_escape_info() {
   242   VM_ENTRY_MARK;
   243   methodDataOop mdo = get_methodDataOop();
   244   if ( mdo != NULL) {
   245     mdo->set_eflags(_eflags);
   246     mdo->set_arg_local(_arg_local);
   247     mdo->set_arg_stack(_arg_stack);
   248     mdo->set_arg_returned(_arg_returned);
   249     int arg_count = mdo->method()->size_of_parameters();
   250     for (int i = 0; i < arg_count; i++) {
   251       mdo->set_arg_modified(i, arg_modified(i));
   252     }
   253   }
   254 }
   256 bool ciMethodData::has_escape_info() {
   257   return eflag_set(methodDataOopDesc::estimated);
   258 }
   260 void ciMethodData::set_eflag(methodDataOopDesc::EscapeFlag f) {
   261   set_bits(_eflags, f);
   262 }
   264 void ciMethodData::clear_eflag(methodDataOopDesc::EscapeFlag f) {
   265   clear_bits(_eflags, f);
   266 }
   268 bool ciMethodData::eflag_set(methodDataOopDesc::EscapeFlag f) const {
   269   return mask_bits(_eflags, f) != 0;
   270 }
   272 void ciMethodData::set_arg_local(int i) {
   273   set_nth_bit(_arg_local, i);
   274 }
   276 void ciMethodData::set_arg_stack(int i) {
   277   set_nth_bit(_arg_stack, i);
   278 }
   280 void ciMethodData::set_arg_returned(int i) {
   281   set_nth_bit(_arg_returned, i);
   282 }
   284 void ciMethodData::set_arg_modified(int arg, uint val) {
   285   ArgInfoData *aid = arg_info();
   286   if (aid == NULL)
   287     return;
   288   assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
   289   aid->set_arg_modified(arg, val);
   290 }
   292 bool ciMethodData::is_arg_local(int i) const {
   293   return is_set_nth_bit(_arg_local, i);
   294 }
   296 bool ciMethodData::is_arg_stack(int i) const {
   297   return is_set_nth_bit(_arg_stack, i);
   298 }
   300 bool ciMethodData::is_arg_returned(int i) const {
   301   return is_set_nth_bit(_arg_returned, i);
   302 }
   304 uint ciMethodData::arg_modified(int arg) const {
   305   ArgInfoData *aid = arg_info();
   306   if (aid == NULL)
   307     return 0;
   308   assert(arg >= 0 && arg < aid->number_of_args(), "valid argument number");
   309   return aid->arg_modified(arg);
   310 }
   312 ByteSize ciMethodData::offset_of_slot(ciProfileData* data, ByteSize slot_offset_in_data) {
   313   // Get offset within methodDataOop of the data array
   314   ByteSize data_offset = methodDataOopDesc::data_offset();
   316   // Get cell offset of the ProfileData within data array
   317   int cell_offset = dp_to_di(data->dp());
   319   // Add in counter_offset, the # of bytes into the ProfileData of counter or flag
   320   int offset = in_bytes(data_offset) + cell_offset + in_bytes(slot_offset_in_data);
   322   return in_ByteSize(offset);
   323 }
   325 ciArgInfoData *ciMethodData::arg_info() const {
   326   // Should be last, have to skip all traps.
   327   DataLayout* dp  = data_layout_at(data_size());
   328   DataLayout* end = data_layout_at(data_size() + extra_data_size());
   329   for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) {
   330     if (dp->tag() == DataLayout::arg_info_data_tag)
   331       return new ciArgInfoData(dp);
   332   }
   333   return NULL;
   334 }
   337 // Implementation of the print method.
   338 void ciMethodData::print_impl(outputStream* st) {
   339   ciObject::print_impl(st);
   340 }
   342 #ifndef PRODUCT
   343 void ciMethodData::print() {
   344   print_data_on(tty);
   345 }
   347 void ciMethodData::print_data_on(outputStream* st) {
   348   ResourceMark rm;
   349   ciProfileData* data;
   350   for (data = first_data(); is_valid(data); data = next_data(data)) {
   351     st->print("%d", dp_to_di(data->dp()));
   352     st->fill_to(6);
   353     data->print_data_on(st);
   354   }
   355   st->print_cr("--- Extra data:");
   356   DataLayout* dp  = data_layout_at(data_size());
   357   DataLayout* end = data_layout_at(data_size() + extra_data_size());
   358   for (; dp < end; dp = methodDataOopDesc::next_extra(dp)) {
   359     if (dp->tag() == DataLayout::no_tag)  continue;
   360     if (dp->tag() == DataLayout::bit_data_tag) {
   361       data = new BitData(dp);
   362     } else {
   363       assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");
   364       data = new ciArgInfoData(dp);
   365       dp = end; // ArgInfoData is at the end of extra data section.
   366     }
   367     st->print("%d", dp_to_di(data->dp()));
   368     st->fill_to(6);
   369     data->print_data_on(st);
   370   }
   371 }
   373 void ciReceiverTypeData::print_receiver_data_on(outputStream* st) {
   374   uint row;
   375   int entries = 0;
   376   for (row = 0; row < row_limit(); row++) {
   377     if (receiver(row) != NULL)  entries++;
   378   }
   379   st->print_cr("count(%u) entries(%u)", count(), entries);
   380   for (row = 0; row < row_limit(); row++) {
   381     if (receiver(row) != NULL) {
   382       tab(st);
   383       receiver(row)->print_name_on(st);
   384       st->print_cr("(%u)", receiver_count(row));
   385     }
   386   }
   387 }
   389 void ciReceiverTypeData::print_data_on(outputStream* st) {
   390   print_shared(st, "ciReceiverTypeData");
   391   print_receiver_data_on(st);
   392 }
   394 void ciVirtualCallData::print_data_on(outputStream* st) {
   395   print_shared(st, "ciVirtualCallData");
   396   rtd_super()->print_receiver_data_on(st);
   397 }
   398 #endif

mercurial