void ciMethodData::load_extra_data() {
  MethodData* mdo = get_MethodData();

  MutexLocker(mdo->extra_data_lock());

  // speculative trap entries also hold a pointer to a Method so need to be translated
  DataLayout* dp_src  = mdo->extra_data_base();
  DataLayout* end_src = mdo->args_data_limit();
  DataLayout* dp_dst  = extra_data_base();
  for (;; dp_src = MethodData::next_extra(dp_src), dp_dst = MethodData::next_extra(dp_dst)) {
    assert(dp_src < end_src, "moved past end of extra data");
    assert(((intptr_t)dp_dst) - ((intptr_t)extra_data_base()) == ((intptr_t)dp_src) - ((intptr_t)mdo->extra_data_base()), "source and destination don't match");

    // New traps in the MDO may have been added since we copied the
    // data (concurrent deoptimizations before we acquired
    // extra_data_lock above) or can be removed (a safepoint may occur
    // in the translate_from call below) as we translate the copy:
    // update the copy as we go.
    int tag = dp_src->tag();
    if (tag != DataLayout::arg_info_data_tag) {
      memcpy(dp_dst, dp_src, ((intptr_t)MethodData::next_extra(dp_src)) - ((intptr_t)dp_src));
    }

    switch(tag) {
    case DataLayout::speculative_trap_data_tag: {
      ciSpeculativeTrapData* data_dst = new ciSpeculativeTrapData(dp_dst);
      SpeculativeTrapData* data_src = new SpeculativeTrapData(dp_src);

      data_dst->translate_from(data_src);

#ifdef ASSERT
      SpeculativeTrapData* data_src2 = new SpeculativeTrapData(dp_src);
      assert(data_src2->method() == data_src->method() && data_src2->bci() == data_src->bci(), "entries changed while translating");
#endif

      break;
    }
    case DataLayout::bit_data_tag:
      break;
    case DataLayout::no_tag:
    case DataLayout::arg_info_data_tag:
      // An empty slot or ArgInfoData entry marks the end of the trap data
      return;
    default:
      fatal(err_msg("bad tag = %d", dp_dst->tag()));
    }
  }
}
Example #2
0
void methodDataOopDesc::print_data_on(outputStream* st) {
  ResourceMark rm;
  ProfileData* data = first_data();
  for ( ; is_valid(data); data = next_data(data)) {
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
  }
  st->print_cr("--- Extra data:");
  DataLayout* dp    = extra_data_base();
  DataLayout* end   = extra_data_limit();
  for (; dp < end; dp = next_extra(dp)) {
    // No need for "OrderAccess::load_acquire" ops,
    // since the data structure is monotonic.
    if (dp->tag() == DataLayout::no_tag)  continue;
    if (dp->tag() == DataLayout::bit_data_tag) {
      data = new BitData(dp);
    } else {
      assert(dp->tag() == DataLayout::arg_info_data_tag, "must be BitData or ArgInfo");
      data = new ArgInfoData(dp);
      dp = end; // ArgInfoData is at the end of extra data section.
    }
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
  }
}
Example #3
0
// Translate a bci to its corresponding extra data, or NULL.
ProfileData* methodDataOopDesc::bci_to_extra_data(int bci, bool create_if_missing) {
  DataLayout* dp    = extra_data_base();
  DataLayout* end   = extra_data_limit();
  DataLayout* avail = NULL;
  for (; dp < end; dp = next_extra(dp)) {
    // No need for "OrderAccess::load_acquire" ops,
    // since the data structure is monotonic.
    if (dp->tag() == DataLayout::no_tag)  break;
    if (dp->tag() == DataLayout::arg_info_data_tag) {
      dp = end; // ArgInfoData is at the end of extra data section.
      break;
    }
    if (dp->bci() == bci) {
      assert(dp->tag() == DataLayout::bit_data_tag, "sane");
      return new BitData(dp);
    }
  }
  if (create_if_missing && dp < end) {
    // Allocate this one.  There is no mutual exclusion,
    // so two threads could allocate different BCIs to the
    // same data layout.  This means these extra data
    // records, like most other MDO contents, must not be
    // trusted too much.
    DataLayout temp;
    temp.initialize(DataLayout::bit_data_tag, bci, 0);
    dp->release_set_header(temp.header());
    assert(dp->tag() == DataLayout::bit_data_tag, "sane");
    //NO: assert(dp->bci() == bci, "no concurrent allocation");
    return new BitData(dp);
  }
  return NULL;
}
void ciMethodData::dump_replay_data_extra_data_helper(outputStream* out, int round, int& count) {
  DataLayout* dp  = extra_data_base();
  DataLayout* end = args_data_limit();

  for (;dp < end; dp = MethodData::next_extra(dp)) {
    switch(dp->tag()) {
    case DataLayout::no_tag:
    case DataLayout::arg_info_data_tag:
      return;
    case DataLayout::bit_data_tag:
      break;
    case DataLayout::speculative_trap_data_tag: {
      ciSpeculativeTrapData* data = new ciSpeculativeTrapData(dp);
      ciMethod* m = data->method();
      if (m != NULL) {
        if (round == 0) {
          count++;
        } else {
          out->print(" %d ", (int)(dp_to_di(((address)dp) + in_bytes(ciSpeculativeTrapData::method_offset())) / sizeof(intptr_t)));
          m->dump_name_as_ascii(out);
        }
      }
      break;
    }
    default:
      fatal(err_msg("bad tag = %d", dp->tag()));
    }
  }
}
ciProfileData* ciMethodData::bci_to_extra_data(int bci, ciMethod* m, bool& two_free_slots) {
  DataLayout* dp  = extra_data_base();
  DataLayout* end = args_data_limit();
  two_free_slots = false;
  for (;dp < end; dp = MethodData::next_extra(dp)) {
    switch(dp->tag()) {
    case DataLayout::no_tag:
      _saw_free_extra_data = true;  // observed an empty slot (common case)
      two_free_slots = (MethodData::next_extra(dp)->tag() == DataLayout::no_tag);
      return NULL;
    case DataLayout::arg_info_data_tag:
      return NULL; // ArgInfoData is at the end of extra data section.
    case DataLayout::bit_data_tag:
      if (m == NULL && dp->bci() == bci) {
        return new ciBitData(dp);
      }
      break;
    case DataLayout::speculative_trap_data_tag: {
      ciSpeculativeTrapData* data = new ciSpeculativeTrapData(dp);
      // data->method() might be null if the MDO is snapshotted
      // concurrently with a trap
      if (m != NULL && data->method() == m && dp->bci() == bci) {
        return data;
      }
      break;
    }
    default:
      fatal(err_msg("bad tag = %d", dp->tag()));
    }
  }
  return NULL;
}
Example #6
0
ArgInfoData *methodDataOopDesc::arg_info() {
  DataLayout* dp    = extra_data_base();
  DataLayout* end   = extra_data_limit();
  for (; dp < end; dp = next_extra(dp)) {
    if (dp->tag() == DataLayout::arg_info_data_tag)
      return new ArgInfoData(dp);
  }
  return NULL;
}
ciArgInfoData *ciMethodData::arg_info() const {
  // Should be last, have to skip all traps.
  DataLayout* dp  = extra_data_base();
  DataLayout* end = args_data_limit();
  for (; dp < end; dp = MethodData::next_extra(dp)) {
    if (dp->tag() == DataLayout::arg_info_data_tag)
      return new ciArgInfoData(dp);
  }
  return NULL;
}
Example #8
0
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());
  Bytecodes::Code c;
  while ((c = stream.next()) >= 0) {
    int size_in_bytes = initialize_data(&stream, data_size);
    data_size += size_in_bytes;

    if (is_empty_data(size_in_bytes, c)) empty_bc_count++;
  }
  _data_size = data_size;
  int object_size = in_bytes(data_offset()) + data_size;

  // Add some extra DataLayout cells (at least one) to track stray traps.
  int extra_data_count = compute_extra_data_count(data_size, empty_bc_count);
  int extra_size = extra_data_count * DataLayout::compute_size_in_bytes(0);
  object_size += extra_size;

  Copy::zero_to_bytes((HeapWord*) extra_data_base(), extra_size);

#ifndef GRAALVM
  // 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();
  dp->initialize(DataLayout::arg_info_data_tag, 0, arg_size+1);

  object_size += DataLayout::compute_size_in_bytes(arg_size+1);
#endif

  // Set an initial hint. Don't use set_hint_di() because
  // first_di() may be out of bounds if data_size is 0.
  // In that situation, _hint_di is never used, but at
  // least well-defined.
  _hint_di = first_di();

  post_initialize(&stream);

  set_size(object_size);
}
void methodDataOopDesc::print_data_on(outputStream* st) {
  ResourceMark rm;
  ProfileData* data = first_data();
  for ( ; is_valid(data); data = next_data(data)) {
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
  }
  DataLayout* dp    = extra_data_base();
  DataLayout* end   = extra_data_limit();
  for (; dp < end; dp = next_extra(dp)) {
    // No need for "OrderAccess::load_acquire" ops,
    // since the data structure is monotonic.
    if (dp->tag() == DataLayout::no_tag)  break;
    if (dp == extra_data_base())
      st->print_cr("--- Extra data:");
    data = new BitData(dp);
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
  }
}
Example #10
0
void ciMethodData::print_data_on(outputStream* st) {
  ResourceMark rm;
  ciParametersTypeData* parameters = parameters_type_data();
  if (parameters != NULL) {
    parameters->print_data_on(st);
  }
  ciProfileData* data;
  for (data = first_data(); is_valid(data); data = next_data(data)) {
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
  }
  st->print_cr("--- Extra data:");
  DataLayout* dp  = extra_data_base();
  DataLayout* end = args_data_limit();
  for (;; dp = MethodData::next_extra(dp)) {
    assert(dp < end, "moved past end of extra data");
    switch (dp->tag()) {
    case DataLayout::no_tag:
      continue;
    case DataLayout::bit_data_tag:
      data = new BitData(dp);
      break;
    case DataLayout::arg_info_data_tag:
      data = new ciArgInfoData(dp);
      dp = end; // ArgInfoData is at the end of extra data section.
      break;
    case DataLayout::speculative_trap_data_tag:
      data = new ciSpeculativeTrapData(dp);
      break;
    default:
      fatal(err_msg("unexpected tag %d", dp->tag()));
    }
    st->print("%d", dp_to_di(data->dp()));
    st->fill_to(6);
    data->print_data_on(st);
    if (dp >= end) return;
  }
}