void ProfileDataContainer::switchStorageToAshmem(int ashmemfd) {
    int regionSize = ashmem_get_size_region(ashmemfd);
    if (regionSize < 0) {
        int err = errno;
        ALOGW("Failed to get ashmem region size from fd %d, err %d %s", ashmemfd, err,
              strerror(err));
        return;
    }
    if (regionSize < static_cast<int>(sizeof(ProfileData))) {
        ALOGW("Ashmem region is too small! Received %d, required %u", regionSize,
              static_cast<unsigned int>(sizeof(ProfileData)));
        return;
    }
    ProfileData* newData = reinterpret_cast<ProfileData*>(
            mmap(NULL, sizeof(ProfileData), PROT_READ | PROT_WRITE, MAP_SHARED, ashmemfd, 0));
    if (newData == MAP_FAILED) {
        int err = errno;
        ALOGW("Failed to move profile data to ashmem fd %d, error = %d", ashmemfd, err);
        return;
    }

    newData->mergeWith(*mData);
    freeData();
    mData = newData;
    mIsMapped = true;
}
Ejemplo n.º 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);
  }
}
Ejemplo n.º 3
0
// Give each of the data entries a chance to perform specific
// data initialization.
void methodDataOopDesc::post_initialize(BytecodeStream* stream) {
  ResourceMark rm;
  ProfileData* data;
  for (data = first_data(); is_valid(data); data = next_data(data)) {
    stream->set_start(data->bci());
    stream->next();
    data->post_initialize(stream, this);
  }
}
Ejemplo n.º 4
0
void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) {
  MethodData* mdo = method()->method_data();
  if (mdo != NULL) {
    ProfileData* data = mdo->bci_to_data(bci);
    if (data != NULL) {
      st->print("  %d", mdo->dp_to_di(data->dp()));
      st->fill_to(6);
      data->print_data_on(st);
    }
  }
}
Ejemplo n.º 5
0
// Translate a bci to its corresponding data, or NULL.
ProfileData* methodDataOopDesc::bci_to_data(int bci) {
  ProfileData* data = data_before(bci);
  for ( ; is_valid(data); data = next_data(data)) {
    if (data->bci() == bci) {
      set_hint_di(dp_to_di(data->dp()));
      return data;
    } else if (data->bci() > bci) {
      break;
    }
  }
  return bci_to_extra_data(bci, false);
}
Ejemplo n.º 6
0
void methodDataKlass::oop_follow_contents(oop obj) {
  assert (obj->is_methodData(), "object must be method data");
  methodDataOop m = methodDataOop(obj);

  obj->follow_header();
  MarkSweep::mark_and_push(m->adr_method());
  ResourceMark rm;
  for (ProfileData* data = m->first_data(); 
       m->is_valid(data); 
       data = m->next_data(data)) {
    data->follow_contents();
  }
}
Ejemplo n.º 7
0
void ciMethodData::set_return_type(int bci, ciKlass* k) {
  VM_ENTRY_MARK;
  MethodData* mdo = get_MethodData();
  if (mdo != NULL) {
    ProfileData* data = mdo->bci_to_data(bci);
    if (data->is_CallTypeData()) {
      data->as_CallTypeData()->set_return_type(k->get_Klass());
    } else {
      assert(data->is_VirtualCallTypeData(), "no arguments!");
      data->as_VirtualCallTypeData()->set_return_type(k->get_Klass());
    }
  }
}
Ejemplo n.º 8
0
int methodDataKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) {
  assert(obj->is_methodData(), "should be method data");
  methodDataOop m = methodDataOop(obj);

  PSParallelCompact::adjust_pointer(m->adr_method());

  ResourceMark rm;
  ProfileData* data;
  for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
    data->update_pointers();
  }
  return m->object_size();
}
Ejemplo n.º 9
0
void BytecodePrinter::bytecode_epilog(int bci) {
#ifndef CORE
  methodDataOop mdo = method()->method_data();
  if (mdo != NULL) {
    ProfileData* data = mdo->bci_to_data(bci);
    if (data != NULL) {
      tty->print("  %d", mdo->dp_to_di(data->dp()));
      tty->fill_to(6);
      data->print_data_on(tty);
    }
  }
#endif
}
/// readEdge - Take the value from a profile counter and assign it to an edge.
void ProfileMetadataLoaderPass::readEdge(unsigned ReadCount,
                                         ProfileData &PB, ProfileData::Edge e,
                                         ArrayRef<unsigned> Counters) {
  if (ReadCount >= Counters.size()) return;

  unsigned weight = Counters[ReadCount];
  assert(weight != ProfileDataLoader::Uncounted);
  PB.addEdgeWeight(e, weight);

  DEBUG(dbgs() << "-- Read Edge Counter for " << e
               << " (# "<< (ReadCount) << "): "
               << PB.getEdgeWeight(e) << "\n");
}
Ejemplo n.º 11
0
void methodDataKlass::oop_follow_contents(ParCompactionManager* cm,
                                          oop obj) {
  assert (obj->is_methodData(), "object must be method data");
  methodDataOop m = methodDataOop(obj);

  obj->follow_header(cm);
  PSParallelCompact::mark_and_push(cm, m->adr_method());
  ResourceMark rm;
  for (ProfileData* data = m->first_data();
       m->is_valid(data);
       data = m->next_data(data)) {
    data->follow_contents(cm);
  }
}
Ejemplo n.º 12
0
int methodDataKlass::oop_adjust_pointers(oop obj) {
  assert(obj->is_methodData(), "should be method data");
  methodDataOop m = methodDataOop(obj);
  // Get size before changing pointers
  // Don't call size() or oop_size() since that is a virtual call.
  int size = m->object_size();

  obj->adjust_header();
  MarkSweep::adjust_pointer(m->adr_method());
  ResourceMark rm;
  ProfileData* data;
  for (data = m->first_data(); m->is_valid(data); data = m->next_data(data)) {
    data->adjust_pointers();
  }
  return size;
}
Ejemplo n.º 13
0
int methodDataKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
  assert (obj->is_methodData(), "object must be method data");
  methodDataOop m = methodDataOop(obj);
  // Get size before changing pointers
  // Don't call size() or oop_size() since that is a virtual call.
  int size = m->object_size();

  obj->oop_iterate_header(blk);
  blk->do_oop(m->adr_method());
  ResourceMark rm;
  for (ProfileData* data = m->first_data(); 
       m->is_valid(data);
       data = m->next_data(data)) {
    data->oop_iterate(blk);
  }
  return size;
}
/// matchEdges - Link every profile counter with an edge.
unsigned ProfileMetadataLoaderPass::matchEdges(Module &M, ProfileData &PB,
                                               ArrayRef<unsigned> Counters) {
  if (Counters.size() == 0) return 0;

  unsigned ReadCount = 0;

  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    DEBUG(dbgs() << "Loading edges in '" << F->getName() << "'\n");
    readEdge(ReadCount++, PB, PB.getEdge(0, &F->getEntryBlock()), Counters);
    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      TerminatorInst *TI = BB->getTerminator();
      for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) {
        readEdge(ReadCount++, PB, PB.getEdge(BB,TI->getSuccessor(s)),
                 Counters);
      }
    }
  }

  return ReadCount;
}
Ejemplo n.º 15
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);
  }
  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);
  }
}
Ejemplo n.º 16
0
	void _printData(char *dest, const ProfileData &a_data, float a_topercent) {
		float totalTicksAvg = a_data.totalTicksAvg();
		const TimeUnit *selfUnit = GetTimeUnit(a_data.selfTicks.avg);
		const TimeUnit *totalUnit = GetTimeUnit(totalTicksAvg);

		snprintf(dest, OUTPUT_WIDTH_DATA + TRAILING,
			" %*.1f %*.0f %-2s %*.0f%% %*.0f %-2s %*.0f%%",
			OUTPUT_WIDTH_HIT, a_data.entryCount.avg,
			OUTPUT_WIDTH_TIME, a_data.selfTicks.avg * selfUnit->invTickFreq, selfUnit->suffix,
			OUTPUT_WIDTH_PERC, a_data.selfTicks.avg * a_topercent,
			OUTPUT_WIDTH_TIME, totalTicksAvg * totalUnit->invTickFreq, totalUnit->suffix,
			OUTPUT_WIDTH_PERC, totalTicksAvg * a_topercent);
	}
/// setBranchWeightMetadata - Translate the counter values associated with each
/// edge into branch weights for each conditional branch (a branch with 2 or
/// more desinations).
void ProfileMetadataLoaderPass::setBranchWeightMetadata(Module &M,
                                                        ProfileData &PB) {
  for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
    if (F->isDeclaration()) continue;
    DEBUG(dbgs() << "Setting branch metadata in '" << F->getName() << "'\n");

    for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
      TerminatorInst *TI = BB->getTerminator();
      unsigned NumSuccessors = TI->getNumSuccessors();

      // If there is only one successor then we can not set a branch
      // probability as the target is certain.
      if (NumSuccessors < 2) continue;

      // Load the weights of all edges leading from this terminator.
      DEBUG(dbgs() << "-- Terminator with " << NumSuccessors
                   << " successors:\n");
      SmallVector<uint32_t, 4> Weights(NumSuccessors);
      for (unsigned s = 0 ; s < NumSuccessors ; ++s) {
          ProfileData::Edge edge = PB.getEdge(BB, TI->getSuccessor(s));
          Weights[s] = (uint32_t)PB.getEdgeWeight(edge);
          DEBUG(dbgs() << "---- Edge '" << edge << "' has weight "
                       << Weights[s] << "\n");
      }

      // Set branch weight metadata.  This will set branch probabilities of
      // 100%/0% if that is true of the dynamic execution.
      // BranchProbabilityInfo can account for this when it loads this metadata
      // (it gives the unexectuted branch a weight of 1 for the purposes of
      // probability calculations).
      MDBuilder MDB(TI->getContext());
      MDNode *Node = MDB.createBranchWeights(Weights);
      TI->setMetadata(LLVMContext::MD_prof, Node);
      NumTermsAnnotated++;
    }
  }
}
Ejemplo n.º 18
0
// Translate a bci to its corresponding data index (di).
address methodDataOopDesc::bci_to_dp(int bci) {
  ResourceMark rm;
  ProfileData* data = data_before(bci);
  ProfileData* prev = NULL;
  for ( ; is_valid(data); data = next_data(data)) {
    if (data->bci() >= bci) {
      if (data->bci() == bci)  set_hint_di(dp_to_di(data->dp()));
      else if (prev != NULL)   set_hint_di(dp_to_di(prev->dp()));
      return data->dp();
    }
    prev = data;
  }
  return (address)limit_data_position();
}
Ejemplo n.º 19
0
void StackTrace::trace(ProfileData &data){
	CaptureStackBackTrace(0, backtraceSize, backtrace, &hash);
	auto stk = data.stacks.find(hash);
	if (stk != data.stacks.end()) { idx = stk->second; return; };
	HANDLE process = GetCurrentProcess();

	const int MAXSYMBOLNAME = 128 - sizeof(IMAGEHLP_SYMBOL);
	char symbol64_buf[sizeof(IMAGEHLP_SYMBOL) + MAXSYMBOLNAME] = { 0 };
	IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL*>(symbol64_buf);
	symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
	symbol->MaxNameLength = MAXSYMBOLNAME - 1;
	IMAGEHLP_MODULE module;
	module.SizeOfStruct = sizeof(IMAGEHLP_MODULE);

	for (size_t i = backtraceSize - 1; i > 0; --i){
		int fileidx = 0;
		int linenum = 0;
		int symidx = 0;
		int modidx = 0;

		if (backtrace[i]){
			// Output stack frame symbols if available.
			if (SymGetSymFromAddr(process, (DWORD64)backtrace[i], 0, symbol)){
				std::string symbol_name = symbol->Name;
				if (strncmp("mallocHook<", symbol->Name, 11) == 0)
				{
					symbol_name = "malloc";
				}
				if (strncmp("freeHook<", symbol->Name, 9) == 0)
				{
					symbol_name = "free";
				}

				symidx =  data.intern(symbol_name);

				if (SymGetModuleInfo(process, (DWORD64)backtrace[i], &module))
				{
					modidx = data.intern(module.ModuleName);
				}
				
				// Output filename + line info if available.
				IMAGEHLP_LINE lineSymbol = { 0 };
				lineSymbol.SizeOfStruct = sizeof(IMAGEHLP_LINE);
				DWORD displacement;
				if (SymGetLineFromAddr(process, (DWORD64)backtrace[i], &displacement, &lineSymbol)){
					fileidx = data.intern(lineSymbol.FileName);
					linenum = lineSymbol.LineNumber;
				}
			}
			fprintf(data.output, "i %lx %lx", symbol->Address, modidx);
			if (symidx || fileidx)
			{
				fprintf(data.output, " %lx", symidx);
				if (fileidx) fprintf(data.output, " %lx %lx", fileidx, linenum);
			}
			fprintf(data.output, "\n");
		}
		else{
			continue;
		}
	}
	idx = data.instGraph.index((intptr_t*)backtrace, data.output);
	data.stacks.insert(std::make_pair(hash, idx));
}
Ejemplo n.º 20
0
void ciMethodData::dump_replay_data(outputStream* out) {
  ResourceMark rm;
  MethodData* mdo = get_MethodData();
  Method* method = mdo->method();
  Klass* holder = method->method_holder();
  out->print("ciMethodData %s %s %s %d %d",
             holder->name()->as_quoted_ascii(),
             method->name()->as_quoted_ascii(),
             method->signature()->as_quoted_ascii(),
             _state,
             current_mileage());

  // dump the contents of the MDO header as raw data
  unsigned char* orig = (unsigned char*)&_orig;
  int length = sizeof(_orig);
  out->print(" orig %d", length);
  for (int i = 0; i < length; i++) {
    out->print(" %d", orig[i]);
  }

  // dump the MDO data as raw data
  int elements = (data_size() + extra_data_size()) / sizeof(intptr_t);
  out->print(" data %d", elements);
  for (int i = 0; i < elements; i++) {
    // We could use INTPTR_FORMAT here but that's a zero justified
    // which makes comparing it with the SA version of this output
    // harder.
#ifdef _LP64
    out->print(" 0x%" FORMAT64_MODIFIER "x", data()[i]);
#else
    out->print(" 0x%x", data()[i]);
#endif
  }

  // The MDO contained oop references as ciObjects, so scan for those
  // and emit pairs of offset and klass name so that they can be
  // reconstructed at runtime.  The first round counts the number of
  // oop references and the second actually emits them.
  ciParametersTypeData* parameters = parameters_type_data();
  for (int count = 0, round = 0; round < 2; round++) {
    if (round == 1) out->print(" oops %d", count);
    ProfileData* pdata = first_data();
    for ( ; is_valid(pdata); pdata = next_data(pdata)) {
      if (pdata->is_VirtualCallData()) {
        ciVirtualCallData* vdata = (ciVirtualCallData*)pdata;
        dump_replay_data_receiver_type_helper<ciVirtualCallData>(out, round, count, vdata);
        if (pdata->is_VirtualCallTypeData()) {
          ciVirtualCallTypeData* call_type_data = (ciVirtualCallTypeData*)pdata;
          dump_replay_data_call_type_helper<ciVirtualCallTypeData>(out, round, count, call_type_data);
        }
      } else if (pdata->is_ReceiverTypeData()) {
        ciReceiverTypeData* vdata = (ciReceiverTypeData*)pdata;
        dump_replay_data_receiver_type_helper<ciReceiverTypeData>(out, round, count, vdata);
      } else if (pdata->is_CallTypeData()) {
          ciCallTypeData* call_type_data = (ciCallTypeData*)pdata;
          dump_replay_data_call_type_helper<ciCallTypeData>(out, round, count, call_type_data);
      }
    }
    if (parameters != NULL) {
      for (int i = 0; i < parameters->number_of_parameters(); i++) {
        dump_replay_data_type_helper(out, round, count, parameters, ParametersTypeData::type_offset(i), parameters->valid_parameter_type(i));
      }
    }
  }
  for (int count = 0, round = 0; round < 2; round++) {
    if (round == 1) out->print(" methods %d", count);
    dump_replay_data_extra_data_helper(out, round, count);
  }
  out->cr();
}