forked from OSchip/llvm-project
83 lines
3.0 KiB
C++
83 lines
3.0 KiB
C++
//===-- ProfileObjectiveC.h -------------------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Created by Greg Clayton on 10/4/07.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef __ProfileObjectiveC_h__
|
|
#define __ProfileObjectiveC_h__
|
|
|
|
#include "DNB.h"
|
|
#include "DNBRuntimeAction.h"
|
|
#include <map>
|
|
#include <sys/time.h>
|
|
|
|
class ProfileObjectiveC : public DNBRuntimeAction
|
|
{
|
|
public:
|
|
ProfileObjectiveC();
|
|
virtual ~ProfileObjectiveC();
|
|
//------------------------------------------------------------------
|
|
// DNBRuntimeAction required functions
|
|
//------------------------------------------------------------------
|
|
virtual void Initialize(nub_process_t pid);
|
|
virtual void ProcessStateChanged(nub_state_t state);
|
|
virtual void SharedLibraryStateChanged(DNBExecutableImageInfo *image_infos, nub_size_t num_image_infos);
|
|
|
|
protected:
|
|
typedef uint32_t objc_selector_t;
|
|
typedef uint32_t objc_class_ptr_t;
|
|
void Clear();
|
|
static nub_bool_t MessageSendBreakpointCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *userData);
|
|
static nub_bool_t MessageSendSuperBreakpointCallback(nub_process_t pid, nub_thread_t tid, nub_break_t breakID, void *userData);
|
|
void DumpStats(nub_process_t pid, FILE *f);
|
|
void SetStartTime();
|
|
void SelectorHit(objc_class_ptr_t isa, objc_selector_t sel);
|
|
typedef std::map<objc_selector_t, uint32_t> SelectorHitCount;
|
|
typedef std::map<objc_class_ptr_t, SelectorHitCount> ClassStatsMap;
|
|
typedef struct Probe
|
|
{
|
|
nub_addr_t addr;
|
|
nub_break_t breakID;
|
|
Probe() : addr(INVALID_NUB_ADDRESS), breakID(INVALID_NUB_BREAK_ID) {}
|
|
void Clear()
|
|
{
|
|
addr = INVALID_NUB_ADDRESS;
|
|
breakID = INVALID_NUB_BREAK_ID;
|
|
}
|
|
bool IsValid() const
|
|
{
|
|
return (addr != INVALID_NUB_ADDRESS) && (NUB_BREAK_ID_IS_VALID(breakID));
|
|
}
|
|
};
|
|
|
|
uint32_t IncrementHitCount() { return ++m_hit_count; }
|
|
bool ShouldDumpStats() const { return m_dump_count && (m_hit_count % m_dump_count) == 0; }
|
|
|
|
nub_process_t m_pid;
|
|
Probe m_objc_msgSend;
|
|
Probe m_objc_msgSendSuper;
|
|
uint32_t m_hit_count; // Number of times we have gotten one of our breakpoints hit
|
|
uint32_t m_dump_count; // Dump stats every time the hit count reaches a multiple of this value
|
|
#if defined (__powerpc__) || defined (__ppc__)
|
|
enum
|
|
{
|
|
k_opcode_size = 4
|
|
};
|
|
uint8_t m_objc_msgSend_opcode[k_opcode_size]; // Saved copy of first opcode in objc_msgSend
|
|
Probe m_objc_msgSend_rtp; // COMM page probe info for objc_msgSend
|
|
#endif
|
|
struct timeval m_begin_time;
|
|
ClassStatsMap m_objcStats;
|
|
};
|
|
|
|
|
|
#endif // #ifndef __ProfileObjectiveC_h__
|