GSdx: vtune JIT code profiling support (somebody should implement this in pcsx2 too, see iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, ...), plzkthx :P) and other minor fixes/optimizations.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@570 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
gabest11 2009-02-22 16:28:39 +00:00
parent 0f6f310c71
commit e934016121
15 changed files with 253 additions and 94 deletions

View File

@ -43,7 +43,6 @@ void GPUDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f)
m_env.sel = p->sel;
m_env.vm = m_state->m_mem.GetPixelAddress(0, 0);
m_env.fbw = 10 + m_state->m_mem.GetScale().cx;
if(m_env.sel.tme)
{
@ -96,7 +95,8 @@ void GPUDrawScanline::EndDraw(const GSRasterizerStats& stats)
//
GPUDrawScanline::GPUSetupPrimMap::GPUSetupPrimMap(GPUScanlineEnvironment& env)
: m_env(env)
: GSCodeGeneratorFunctionMap("GPUSetupPrim")
, m_env(env)
{
}
@ -108,7 +108,8 @@ GPUSetupPrimCodeGenerator* GPUDrawScanline::GPUSetupPrimMap::Create(DWORD key, v
//
GPUDrawScanline::GPUDrawScanlineMap::GPUDrawScanlineMap(GPUScanlineEnvironment& env)
: m_env(env)
: GSCodeGeneratorFunctionMap("GPUDrawScanline")
, m_env(env)
{
}

View File

@ -57,7 +57,10 @@ L("loop");
movdqa(xmm7, xmmword[edx + (size_t)&m_test[7]]);
movdqu(xmm1, xmmword[edi]);
// movdqu(xmm1, xmmword[edi]);
movq(xmm1, qword[edi]);
movhps(xmm1, qword[edi + 8]);
// ecx = steps
// esi = tex (tme)
@ -106,42 +109,37 @@ L("exit");
pop(edi);
pop(esi);
ret();
ret(8);
}
void GPUDrawScanlineCodeGenerator::Init(int params)
{
const int _top = params + 4;
const int _left = params + 8;
const int _right = params + 12;
const int _v = params + 16;
const int _v = params + 8;
mov(edx, dword[esp + _top]);
mov(eax, dword[esp + _left]);
mov(eax, dword[esp + _top]);
// WORD* fb = &m_env.vm[(top << m_env.fbw) + left];
// WORD* fb = &m_env.vm[(top << (10 + m_env.sel.scalex)) + left];
mov(ecx, dword[&m_env.fbw]);
mov(edi, edx);
shl(edi, cl);
add(edi, eax);
mov(edi, eax);
shl(edi, 10 + m_env.sel.scalex);
add(edi, edx);
lea(edi, ptr[edi * 2 + (size_t)m_env.vm]);
// int steps = right - left - 8;
mov(ecx, dword[esp + _right]);
sub(ecx, eax);
sub(ecx, edx);
sub(ecx, 8);
if(m_env.sel.dtd)
{
// dither = GSVector4i::load<false>(&s_dither[top & 3][left & 3]);
and(edx, 3);
shl(edx, 5);
and(eax, 3);
shl(eax, 1);
movdqu(xmm0, xmmword[edx + eax + (size_t)m_dither]);
shl(eax, 5);
and(edx, 3);
shl(edx, 1);
movdqu(xmm0, xmmword[eax + edx + (size_t)m_dither]);
movdqa(xmmword[&m_env.temp.dither], xmm0);
}
@ -299,10 +297,6 @@ void GPUDrawScanlineCodeGenerator::SampleTexture()
{
if(!m_env.sel.tme)
{
// c[3] = GSVector4i::zero();
pxor(xmm3, xmm3);
return;
}
@ -888,11 +882,11 @@ void GPUDrawScanlineCodeGenerator::Dither()
void GPUDrawScanlineCodeGenerator::WriteFrame()
{
// GSVector4i fs = r | g | b | (m_env.sel.md ? GSVector4i(0x80008000) : a);
// GSVector4i fs = r | g | b | (m_env.sel.md ? GSVector4i(0x80008000) : m_env.sel.tme ? a : 0);
pcmpeqd(xmm0, xmm0);
if(m_env.sel.md)
if(m_env.sel.md || m_env.sel.tme)
{
movdqa(xmm2, xmm0);
psllw(xmm2, 15);
@ -927,7 +921,7 @@ void GPUDrawScanlineCodeGenerator::WriteFrame()
por(xmm4, xmm2);
}
else
else if(m_env.sel.tme)
{
// GSVector4i a = (c[3] << 8) & 0x80008000;
@ -943,7 +937,10 @@ void GPUDrawScanlineCodeGenerator::WriteFrame()
// GSVector4i::store<false>(fb, fs);
movdqu(xmmword[edi], xmm4);
// movdqu(xmmword[edi], xmm4);
movq(qword[edi], xmm4);
movhps(qword[edi + 8], xmm4);
}
void GPUDrawScanlineCodeGenerator::ReadTexel(const Xmm& dst, const Xmm& addr)

View File

@ -155,6 +155,7 @@ protected:
p.sel.dtd = m_dither ? env.STATUS.DTD : 0;
p.sel.md = env.STATUS.MD;
p.sel.sprite = env.PRIM.TYPE == GPU_SPRITE;
p.sel.scalex = m_mem.GetScale().cx;
//

View File

@ -40,6 +40,7 @@ union GPUScanlineSelector
DWORD ltf:1; // 10
DWORD md:1; // 11
DWORD sprite:1; // 12
DWORD scalex:2; // 13
};
struct
@ -71,7 +72,6 @@ __declspec(align(16)) struct GPUScanlineEnvironment
void* vm;
const void* tex;
const WORD* clut;
DWORD fbw; // 10 + m_scale.cx
// GSVector4i md; // similar to gs fba

View File

@ -40,12 +40,6 @@ void GPUSetupPrimCodeGenerator::Generate()
{
const int params = 0;
const int _vertices = params + 4;
const int _dscan = params + 8;
mov(ecx, dword[esp + _vertices]);
mov(edx, dword[esp + _dscan]);
if(m_env.sel.tme && !m_env.sel.twin)
{
pcmpeqd(xmm0, xmm0);

View File

@ -346,7 +346,8 @@ void GSDrawScanline::FillBlock(const GSVector4i* row, int* col, const GSVector4i
//
GSDrawScanline::GSSetupPrimMap::GSSetupPrimMap(GSScanlineEnvironment& env)
: m_env(env)
: GSCodeGeneratorFunctionMap("GSSetupPrim")
, m_env(env)
{
}
@ -358,7 +359,8 @@ GSSetupPrimCodeGenerator* GSDrawScanline::GSSetupPrimMap::Create(UINT64 key, voi
//
GSDrawScanline::GSDrawScanlineMap::GSDrawScanlineMap(GSScanlineEnvironment& env)
: m_env(env)
: GSCodeGeneratorFunctionMap("GSDrawScanline")
, m_env(env)
{
}

View File

@ -184,7 +184,7 @@ L("loop");
por(xmm4, xmm7);
}
// int fzm = ~(fm == GSVector4i::xffffffff()).ps32(zm == GSVector4i::xffffffff()).ps32().mask();
// int fzm = ~(fm == GSVector4i::xffffffff()).ps32(zm == GSVector4i::xffffffff()).mask();
pcmpeqd(xmm1, xmm1);
@ -267,45 +267,41 @@ L("exit");
pop(esi);
pop(ebx);
ret();
ret(8);
}
void GSDrawScanlineCodeGenerator::Init(int params)
{
const int _top = params + 4;
const int _left = params + 8;
const int _right = params + 12;
const int _v = params + 16;
const int _v = params + 8;
// int skip = left & 3;
mov(eax, dword[esp + _left]);
mov(ebx, eax);
and(eax, 3);
mov(ebx, edx);
and(edx, 3);
// left -= skip;
sub(ebx, eax);
sub(ebx, edx);
// int steps = right - left - 4;
mov(ecx, dword[esp + _right]);
sub(ecx, ebx);
sub(ecx, 4);
// GSVector4i test = m_test[skip] | m_test[7 + (steps & (steps >> 31))];
shl(eax, 4);
movdqa(xmm7, xmmword[eax + (size_t)&m_test[0]]);
mov(edx, ecx);
sar(edx, 31);
and(edx, ecx);
shl(edx, 4);
por(xmm7, xmmword[edx + (size_t)&m_test[7]]);
movdqa(xmm7, xmmword[edx + (size_t)&m_test[0]]);
mov(eax, ecx);
sar(eax, 31);
and(eax, ecx);
shl(eax, 4);
por(xmm7, xmmword[eax + (size_t)&m_test[7]]);
// GSVector2i* fza_base = &m_env.fzbr[top];
mov(esi, dword[esp + _top]);
@ -319,10 +315,10 @@ void GSDrawScanlineCodeGenerator::Init(int params)
if(!m_env.sel.sprite && (m_env.sel.fwrite && m_env.sel.fge || m_env.sel.zb) || m_env.sel.fb && (m_env.sel.tfx != TFX_NONE || m_env.sel.iip))
{
// eax = &m_env.d[skip]
// edx = &m_env.d[skip]
shl(eax, 4);
lea(eax, ptr[eax + (size_t)m_env.d]);
shl(edx, 4);
lea(edx, ptr[edx + (size_t)m_env.d]);
// ebx = &v
@ -342,7 +338,7 @@ void GSDrawScanlineCodeGenerator::Init(int params)
cvttps2dq(xmm1, xmm0);
pshufhw(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2));
pshufd(xmm1, xmm1, _MM_SHUFFLE(2, 2, 2, 2));
paddw(xmm1, xmmword[eax + 16 * 6]);
paddw(xmm1, xmmword[edx + 16 * 6]);
movdqa(xmmword[&m_env.temp.f], xmm1);
}
@ -352,7 +348,7 @@ void GSDrawScanlineCodeGenerator::Init(int params)
// z = vp.zzzz() + m_env.d[skip].z;
shufps(xmm0, xmm0, _MM_SHUFFLE(2, 2, 2, 2));
addps(xmm0, xmmword[eax]);
addps(xmm0, xmmword[edx]);
movaps(xmmword[&m_env.temp.z], xmm0);
}
@ -384,11 +380,11 @@ void GSDrawScanlineCodeGenerator::Init(int params)
pshufd(xmm2, xmm4, _MM_SHUFFLE(0, 0, 0, 0));
pshufd(xmm3, xmm4, _MM_SHUFFLE(1, 1, 1, 1));
paddd(xmm2, xmmword[eax + 16 * 7]);
paddd(xmm2, xmmword[edx + 16 * 7]);
if(!m_env.sel.sprite)
{
paddd(xmm3, xmmword[eax + 16 * 8]);
paddd(xmm3, xmmword[edx + 16 * 8]);
}
else
{
@ -418,9 +414,9 @@ void GSDrawScanlineCodeGenerator::Init(int params)
shufps(xmm3, xmm3, _MM_SHUFFLE(1, 1, 1, 1));
shufps(xmm4, xmm4, _MM_SHUFFLE(2, 2, 2, 2));
addps(xmm2, xmmword[eax + 16 * 1]);
addps(xmm3, xmmword[eax + 16 * 2]);
addps(xmm4, xmmword[eax + 16 * 3]);
addps(xmm2, xmmword[edx + 16 * 1]);
addps(xmm3, xmmword[edx + 16 * 2]);
addps(xmm4, xmmword[edx + 16 * 3]);
movaps(xmmword[&m_env.temp.s], xmm2);
movaps(xmmword[&m_env.temp.t], xmm3);
@ -451,8 +447,8 @@ void GSDrawScanlineCodeGenerator::Init(int params)
pshufd(xmm5, xmm6, _MM_SHUFFLE(0, 0, 0, 0));
pshufd(xmm6, xmm6, _MM_SHUFFLE(2, 2, 2, 2));
paddw(xmm5, xmmword[eax + 16 * 4]);
paddw(xmm6, xmmword[eax + 16 * 5]);
paddw(xmm5, xmmword[edx + 16 * 4]);
paddw(xmm6, xmmword[edx + 16 * 5]);
movdqa(xmmword[&m_env.temp.rb], xmm5);
movdqa(xmmword[&m_env.temp.ga], xmm6);
@ -1521,6 +1517,8 @@ void GSDrawScanlineCodeGenerator::AlphaBlend()
/*
if(m_env.sel.aa1)
{
// hmm, the playstation logo does not look good...
printf("aa1 %016I64x\n", m_env.sel.key);
if(m_env.sel.fpsm != 1) // TODO: fm == 0xffxxxxxx
@ -1529,6 +1527,7 @@ void GSDrawScanlineCodeGenerator::AlphaBlend()
pcmpeqd(xmm0, xmm0);
psllw(xmm0, 15);
psrlw(xmm0, 8);
mix16(xmm6, xmm0, xmm1);
}

View File

@ -161,10 +161,13 @@ public:
};
#include "GSCodeBuffer.h"
#include "vtune/JITProfiling.h"
template<class CG, class KEY, class VALUE>
class GSCodeGeneratorFunctionMap : public GSFunctionMap<KEY, VALUE>
{
DWORD m_id;
CStringA m_name;
CRBMap<UINT64, CG*> m_cgmap;
GSCodeBuffer m_cb;
@ -174,7 +177,9 @@ protected:
virtual CG* Create(KEY key, void* ptr, size_t maxsize = MAX_SIZE) = 0;
public:
GSCodeGeneratorFunctionMap()
GSCodeGeneratorFunctionMap(LPCSTR name)
: m_id(0x100000)
, m_name(name)
{
}
@ -203,6 +208,23 @@ public:
m_cb.ReleaseBuffer(cg->getSize());
m_cgmap.SetAt(key, cg);
// vtune method registration
CStringA name;
name.Format("%s<%016I64x>()", m_name, (UINT64)key);
iJIT_Method_Load ml;
memset(&ml, 0, sizeof(ml));
ml.method_id = m_id++;
ml.method_name = (LPSTR)(LPCSTR)name;
ml.method_load_address = (void*)cg->getCode();
ml.method_size = cg->getSize();
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &ml);
}
return (VALUE)cg->getCode();

View File

@ -99,7 +99,7 @@ void GSRasterizer::DrawPoint(const GSVertexSW* v, const GSVector4i& scissor)
{
m_dsf.ssp(v, *v);
m_dsf.ssl(p.y, p.x, p.x + 1, *v);
m_dsf.ssl(p.x + 1, p.x, p.y, *v);
m_stats.pixels++;
}
@ -439,7 +439,7 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& l, const
scan = l;
}
m_dsf.ssl(top, left, right, scan);
m_dsf.ssl(right, left, top, scan);
}
}
}
@ -494,7 +494,7 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& l, const
scan = l;
}
m_dsf.ssl(top, left, right, scan);
m_dsf.ssl(right, left, top, scan);
}
}
}
@ -583,7 +583,7 @@ void GSRasterizer::DrawSprite(const GSVertexSW* vertices, const GSVector4i& scis
{
if((top % m_threads) == m_id)
{
m_dsf.ssl(top, left, right, scan);
m_dsf.ssl(right, left, top, scan);
m_stats.pixels += right - left;
}
@ -665,9 +665,11 @@ DWORD GSRasterizerMT::ThreadProc()
GSRasterizerList::GSRasterizerList()
{
// get a whole cache line (twice the size for future cpus ;)
// User/Source Coding Rule 24. (M impact, ML generality) Place each
// synchronization variable alone, separated by 128 bytes or in a separate cache
// line.
m_sync = (long*)_aligned_malloc(sizeof(*m_sync), 128);
m_sync = (long*)_aligned_malloc(128, 64);
*m_sync = 0;
}

View File

@ -49,8 +49,8 @@ class IDrawScanline
{
public:
typedef void (IDrawScanline::*DrawSolidRectPtr)(const GSVector4i& r, const GSVertexSW& v);
typedef void (*DrawScanlineStaticPtr)(int top, int left, int right, const GSVertexSW& v);
typedef void (*SetupPrimStaticPtr)(const GSVertexSW* vertices, const GSVertexSW& dscan);
typedef void (__fastcall *DrawScanlineStaticPtr)(int right, int left, int top, const GSVertexSW& v);
typedef void (__fastcall *SetupPrimStaticPtr)(const GSVertexSW* vertices, const GSVertexSW& dscan);
struct Functions
{

View File

@ -44,12 +44,6 @@ void GSSetupPrimCodeGenerator::Generate()
{
const int params = 0;
const int _vertices = params + 4;
const int _dscan = params + 8;
mov(ecx, dword[esp + _vertices]);
mov(edx, dword[esp + _dscan]);
if((m_en.z || m_en.f) && !m_env.sel.sprite || m_en.t || m_en.c && m_env.sel.iip)
{
for(int i = 0; i < 5; i++)

View File

@ -230,7 +230,7 @@ __declspec(align(16)) class GSVertexTrace
class GSVertexTraceMap : public GSCodeGeneratorFunctionMap<GSVertexTraceCodeGenerator, DWORD, VertexTracePtr>
{
public:
GSVertexTraceMap() {}
GSVertexTraceMap() : GSCodeGeneratorFunctionMap("VertexTrace") {}
GSVertexTraceCodeGenerator* Create(DWORD key, void* ptr, size_t maxsize) {return new GSVertexTraceCodeGenerator(key, ptr, maxsize);}
} m_map;

View File

@ -18,8 +18,9 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="d3d10.lib d3dx10.lib d3d9.lib d3dx9.lib ddraw.lib dxguid.lib winmm.lib strmiids.lib xinput.lib"
AdditionalDependencies="JITProfiling.lib d3d10.lib d3dx10.lib d3d9.lib d3dx9.lib ddraw.lib dxguid.lib winmm.lib strmiids.lib xinput.lib"
OutputFile="..\..\bin\plugins\$(ProjectName).dll"
AdditionalLibraryDirectories="./vtune"
DelayLoadDLLs="d3d9.dll;d3dx9_40.dll;d3d10.dll;d3dx10_40.dll"
GenerateDebugInformation="true"
SubSystem="2"
@ -29,12 +30,4 @@
Name="VCPreBuildEventTool"
CommandLine=".\vsprops\preBuild.cmd &quot;$(ProjectDir)\&quot; &quot;$(ProjectDir)vsprops&quot;"
/>
<!--
<Tool
Name="VCPostBuildEventTool"
CommandLine=".\vsprops\postBuild.cmd &quot;$(TargetPath)&quot; &quot;$(SolutionDir)&quot; &quot;$(TargetName)&quot; $(TargetExt)"
/>
-->
</VisualStudioPropertySheet>

View File

@ -0,0 +1,154 @@
/*************************************************************************
*
* INTEL CORPORATION PROPRIETARY INFORMATION
* This software is supplied under the terms of a license agreement or
* nondisclosure agreement with Intel Corporation and may not be copied
* or disclosed except in accordance with the terms of that agreement.
*
* Copyright(c) 2008 Intel Corporation. All Rights Reserved.
*
************************************************************************/
#ifndef __JITPROFILING_H__
#define __JITPROFILING_H__
/***************************************
* Various constants used by functions *
***************************************/
// event notification
typedef enum iJIT_jvm_event
{
// shutdown
iJVM_EVENT_TYPE_SHUTDOWN = 2, // Program exiting
// EventSpecificData NA
// JIT profiling
iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED=13, // issued after method code jitted
// into memory but before code is executed
// EventSpecificData is an iJIT_Method_Load
iJVM_EVENT_TYPE_METHOD_UNLOAD_START, // issued before unload. Method code will no
// longer be executed, but code and info
// are still in memory. The VTune profiler
// may capture method code only at this point.
// EventSpecificData is iJIT_Method_Id
// Method Profiling
// method name, Id and stack is supplied
iJVM_EVENT_TYPE_ENTER_NIDS = 19, // issued when a method is about to be entered
// EventSpecificData is iJIT_Method_NIDS
// method name, Id and stack is supplied
iJVM_EVENT_TYPE_LEAVE_NIDS, // issued when a method is about to be left
// EventSpecificData is iJIT_Method_NIDS
} iJIT_JVM_EVENT;
typedef enum _iJIT_ModeFlags
{
iJIT_NO_NOTIFICATIONS = 0x0000, // No need to Notify VTune, Since VTune is not running.
iJIT_BE_NOTIFY_ON_LOAD = 0x0001, // when turned on the jit must call iJIT_NotifyEvent( iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, ...) for all the method already jitted.
iJIT_BE_NOTIFY_ON_UNLOAD = 0x0002, // when turned on the jit must call iJIT_NotifyEvent( iJVM_EVENT_TYPE_METHOD_UNLOAD_FINISHED, ...) for all the method that are unloaded
iJIT_BE_NOTIFY_ON_METHOD_ENTRY = 0x0004, // when turned on the jit must instrument all the currently jited code with calls on method entries
iJIT_BE_NOTIFY_ON_METHOD_EXIT = 0x0008, // when turned on the jit must instrument all the currently jited code with calls on method exit
} iJIT_ModeFlags;
// Flags used by iJIT_IsProfilingActive()
typedef enum _iJIT_IsProfilingActiveFlags
{
iJIT_NOTHING_RUNNING = 0x0000, // No profiler is running. Currently not used.
iJIT_SAMPLING_ON = 0x0001, // Sampling is running. This is the default value returned by iJIT_IsProfilingActive()
iJIT_CALLGRAPH_ON = 0x0002 // Call Graph is running
} iJIT_IsProfilingActiveFlags;
// Enumerator for the environment of methods
typedef enum _iJDEnvironmentType
{
iJDE_JittingAPI = 2
} iJDEnvironmentType;
/**********************************
* Data structures for the events *
**********************************/
// structure for the events:
// iJVM_EVENT_TYPE_METHOD_UNLOAD_START
typedef struct _iJIT_Method_Id
{
unsigned int method_id; // Id of the method (same as the one passed in the iJIT_Method_Load struct
} *piJIT_Method_Id, iJIT_Method_Id;
// structure for the events:
// iJVM_EVENT_TYPE_ENTER_NIDS,
// iJVM_EVENT_TYPE_LEAVE_NIDS,
// iJVM_EVENT_TYPE_EXCEPTION_OCCURRED_NIDS
typedef struct _iJIT_Method_NIDS
{
unsigned int method_id; // unique method ID
unsigned int stack_id; // NOTE: no need to fill this field, it's filled by VTune
char* method_name; // method name (just the method, without the class)
} *piJIT_Method_NIDS, iJIT_Method_NIDS;
// structures for the events:
// iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED
typedef struct _LineNumberInfo
{
unsigned int Offset; // x86 Offset from the begining of the method
unsigned int LineNumber; // source line number from the begining of the source file.
} *pLineNumberInfo, LineNumberInfo;
typedef struct _iJIT_Method_Load
{
unsigned int method_id; // unique method ID - can be any unique value, (except 0 - 999)
char* method_name; // method name (can be with or without the class and signature, in any case the class name will be added to it)
void* method_load_address; // virtual address of that method - This determines the method range for the iJVM_EVENT_TYPE_ENTER/LEAVE_METHOD_ADDR events
unsigned int method_size; // Size in memory - Must be exact
unsigned int line_number_size; // Line Table size in number of entries - Zero if none
pLineNumberInfo line_number_table; // Pointer to the begining of the line numbers info array
unsigned int class_id; // unique class ID
char* class_file_name; // class file name
char* source_file_name; // source file name
void* user_data; // bits supplied by the user for saving in the JIT file...
unsigned int user_data_size; // the size of the user data buffer
iJDEnvironmentType env; // NOTE: no need to fill this field, it's filled by VTune
} *piJIT_Method_Load, iJIT_Method_Load;
//API Functions
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*iJIT_ModeChangedEx)(void *UserData, iJIT_ModeFlags Flags); // called when the settings are changed with new settings
int iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData);
void iJIT_RegisterCallbackEx(void *userdata, iJIT_ModeChangedEx NewModeCallBackFuncEx); // The new mode call back routine
iJIT_IsProfilingActiveFlags iJIT_IsProfilingActive();
void FinalizeThread();
void FinalizeProcess();
unsigned int iJIT_GetNewMethodID();
#ifdef __cplusplus
}
#endif
#endif //__JITPROFILING_H__

Binary file not shown.