< prev index next >

src/share/vm/oops/methodData.cpp

Print this page

        

@@ -411,17 +411,43 @@
       clear_row(row);
     }
   }
 }
 
+#if INCLUDE_JVMCI
+void VirtualCallData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
+  ReceiverTypeData::clean_weak_klass_links(is_alive_cl);
+  for (uint row = 0; row < method_row_limit(); row++) {
+    Method* p = method(row);
+    if (p != NULL && !p->method_holder()->is_loader_alive(is_alive_cl)) {
+      clear_method_row(row);
+    }
+  }
+}
+
+void VirtualCallData::clean_weak_method_links() {
+  ReceiverTypeData::clean_weak_method_links();
+  for (uint row = 0; row < method_row_limit(); row++) {
+    Method* p = method(row);
+    if (p != NULL && !p->on_stack()) {
+      clear_method_row(row);
+    }
+  }
+}
+#endif // INCLUDE_JVMCI
+
 void ReceiverTypeData::print_receiver_data_on(outputStream* st) const {
   uint row;
   int entries = 0;
   for (row = 0; row < row_limit(); row++) {
     if (receiver(row) != NULL)  entries++;
   }
+#if INCLUDE_JVMCI
+  st->print_cr("count(%u) nonprofiled_count(%u) entries(%u)", count(), nonprofiled_count(), entries);
+#else
   st->print_cr("count(%u) entries(%u)", count(), entries);
+#endif
   int total = count();
   for (row = 0; row < row_limit(); row++) {
     if (receiver(row) != NULL) {
       total += receiver_count(row);
     }

@@ -436,13 +462,40 @@
 }
 void ReceiverTypeData::print_data_on(outputStream* st, const char* extra) const {
   print_shared(st, "ReceiverTypeData", extra);
   print_receiver_data_on(st);
 }
+
+#if INCLUDE_JVMCI
+void VirtualCallData::print_method_data_on(outputStream* st) const {
+  uint row;
+  int entries = 0;
+  for (row = 0; row < method_row_limit(); row++) {
+    if (method(row) != NULL) entries++;
+  }
+  tab(st);
+  st->print_cr("method_entries(%u)", entries);
+  int total = count();
+  for (row = 0; row < method_row_limit(); row++) {
+    if (method(row) != NULL) {
+      total += method_count(row);
+    }
+  }
+  for (row = 0; row < method_row_limit(); row++) {
+    if (method(row) != NULL) {
+      tab(st);
+      method(row)->print_value_on(st);
+      st->print_cr("(%u %4.2f)", method_count(row), (float) method_count(row) / (float) total);
+    }
+  }
+}
+#endif // INCLUDE_JVMCI
+
 void VirtualCallData::print_data_on(outputStream* st, const char* extra) const {
   print_shared(st, "VirtualCallData", extra);
   print_receiver_data_on(st);
+  print_method_data_on(st);
 }
 
 // ==================================================================
 // RetData
 //

@@ -663,11 +716,11 @@
   return new (loader_data, size, false, MetaspaceObj::MethodDataType, THREAD)
     MethodData(method(), size, THREAD);
 }
 
 int MethodData::bytecode_cell_count(Bytecodes::Code code) {
-#if defined(COMPILER1) && !defined(COMPILER2)
+#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI)
   return no_profile_data;
 #else
   switch (code) {
   case Bytecodes::_checkcast:
   case Bytecodes::_instanceof:

@@ -795,10 +848,30 @@
   }
   return false;
 }
 
 int MethodData::compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps) {
+#if INCLUDE_JVMCI
+  if (ProfileTraps) {
+    // Assume that up to 30% of the possibly trapping BCIs with no MDP will need to allocate one.
+    int extra_data_count = MIN2(empty_bc_count, MAX2(4, (empty_bc_count * 30) / 100));
+
+    // Make sure we have a minimum number of extra data slots to
+    // allocate SpeculativeTrapData entries. We would want to have one
+    // entry per compilation that inlines this method and for which
+    // some type speculation assumption fails. So the room we need for
+    // the SpeculativeTrapData entries doesn't directly depend on the
+    // size of the method. Because it's hard to estimate, we reserve
+    // space for an arbitrary number of entries.
+    int spec_data_count = (needs_speculative_traps ? SpecTrapLimitExtraEntries : 0) *
+      (SpeculativeTrapData::static_cell_count() + DataLayout::header_size_in_cells());
+
+    return MAX2(extra_data_count, spec_data_count);
+  } else {
+    return 0;
+  }
+#else // INCLUDE_JVMCI
   if (ProfileTraps) {
     // Assume that up to 3% of BCIs with no MDP will need to allocate one.
     int extra_data_count = (uint)(empty_bc_count * 3) / 128 + 1;
     // If the method is large, let the extra BCIs grow numerous (to ~1%).
     int one_percent_of_data

@@ -820,10 +893,11 @@
 
     return MAX2(extra_data_count, spec_data_count);
   } else {
     return 0;
   }
+#endif // INCLUDE_JVMCI
 }
 
 // Compute the size of the MethodData* necessary to store
 // profiling information about a given method.  Size is in bytes.
 int MethodData::compute_allocation_size_in_bytes(methodHandle method) {

@@ -833,11 +907,11 @@
   int empty_bc_count = 0;  // number of bytecodes lacking data
   bool needs_speculative_traps = false;
   while ((c = stream.next()) >= 0) {
     int size_in_bytes = compute_data_size(&stream);
     data_size += size_in_bytes;
-    if (size_in_bytes == 0)  empty_bc_count += 1;
+    if (size_in_bytes == 0 JVMCI_ONLY(&& Bytecodes::can_trap(c)))  empty_bc_count += 1;
     needs_speculative_traps = needs_speculative_traps || is_speculative_trap_bytecode(c);
   }
   int object_size = in_bytes(data_offset()) + data_size;
 
   // Add some extra DataLayout cells (at least one) to track stray traps.

@@ -867,11 +941,11 @@
 
 // Initialize an individual data segment.  Returns the size of
 // the segment in bytes.
 int MethodData::initialize_data(BytecodeStream* stream,
                                        int data_index) {
-#if defined(COMPILER1) && !defined(COMPILER2)
+#if defined(COMPILER1) && !(defined(COMPILER2) || INCLUDE_JVMCI)
   return 0;
 #else
   int cell_count = -1;
   int tag = DataLayout::no_tag;
   DataLayout* data_layout = data_layout_at(data_index);

@@ -1058,30 +1132,34 @@
 
 // Initialize the MethodData* corresponding to a given method.
 MethodData::MethodData(methodHandle method, int size, TRAPS)
   : _extra_data_lock(Monitor::leaf, "MDO extra data lock"),
     _parameters_type_data_di(parameters_uninitialized) {
-  No_Safepoint_Verifier no_safepoint;  // init function atomic wrt GC
-  ResourceMark rm;
   // Set the method back-pointer.
   _method = method();
+  initialize();
+}
+
+void MethodData::initialize() {
+  No_Safepoint_Verifier no_safepoint;  // init function atomic wrt GC
+  ResourceMark rm;
 
   init();
   set_creation_mileage(mileage_of(method()));
 
   // Go through the bytecodes and allocate and initialize the
   // corresponding data cells.
   int data_size = 0;
   int empty_bc_count = 0;  // number of bytecodes lacking data
   _data[0] = 0;  // apparently not set below.
-  BytecodeStream stream(method);
+  BytecodeStream stream(method());
   Bytecodes::Code c;
   bool needs_speculative_traps = false;
   while ((c = stream.next()) >= 0) {
     int size_in_bytes = initialize_data(&stream, data_size);
     data_size += size_in_bytes;
-    if (size_in_bytes == 0)  empty_bc_count += 1;
+    if (size_in_bytes == 0 JVMCI_ONLY(&& Bytecodes::can_trap(c)))  empty_bc_count += 1;
     needs_speculative_traps = needs_speculative_traps || is_speculative_trap_bytecode(c);
   }
   _data_size = data_size;
   int object_size = in_bytes(data_offset()) + data_size;
 

@@ -1095,11 +1173,11 @@
   // Add a cell to record information about modified arguments.
   // Set up _args_modified array after traps cells so that
   // the code for traps cells works.
   DataLayout *dp = data_layout_at(data_size + extra_size);
 
-  int arg_size = method->size_of_parameters();
+  int arg_size = method()->size_of_parameters();
   dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1);
 
   int arg_data_size = DataLayout::compute_size_in_bytes(arg_size+1);
   object_size += extra_size + arg_data_size;
 

@@ -1124,10 +1202,11 @@
   // least well-defined.
   _hint_di = first_di();
 
   post_initialize(&stream);
 
+  assert(object_size == compute_allocation_size_in_bytes(methodHandle(_method)), "MethodData: computed size != initialized size");
   set_size(object_size);
 }
 
 void MethodData::init() {
   _invocation_counter.init();

@@ -1144,10 +1223,14 @@
   _tenure_traps = 0;
   _num_loops = 0;
   _num_blocks = 0;
   _would_profile = unknown;
 
+#if INCLUDE_JVMCI
+  _jvmci_ir_size = 0;
+#endif
+
 #if INCLUDE_RTM_OPT
   _rtm_state = NoRTM; // No RTM lock eliding by default
   if (UseRTMLocking &&
       !CompilerOracle::has_option_string(_method, "NoRTMLockEliding")) {
     if (CompilerOracle::has_option_string(_method, "UseRTMLockEliding") || !UseRTMDeopt) {
< prev index next >