00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "../prof/prof.h"
00036 #include "../prof/synchronized.h"
00037 #include "../alloc/allocThreadObject.h"
00038 #include "../alloc/allocObject.h"
00039 #include "../alloc/allocThreadObjectMethod.h"
00040 #include "../alloc/allocObjectMethod.h"
00041 #include "../alloc/allocThreadObjectTrace.h"
00042 #include "../alloc/allocObjectTrace.h"
00043 #include "../alloc/allocInstance.h"
00044 #include "../alloc/allocArena.h"
00045
00046 void Prof::event_objectAlloc( JVMPI_Event* event) {
00047
00048 Synchronized sync(dataLock, 0);
00049 if (!(event->event_type & JVMPI_REQUESTED_EVENT)) sync.enter();
00050
00051 JNIEnv* envId = event->env_id;
00052 jint arenaId = event->u.obj_alloc.arena_id;
00053 jobjectID classId = event->u.obj_alloc.class_id;
00054 jint isArray = event->u.obj_alloc.is_array;
00055 jint size = event->u.obj_alloc.size;
00056 jobjectID objId = event->u.obj_alloc.obj_id;
00057
00058 if (!envId) return;
00059 if (!objId) return;
00060
00061 AllocAbstractStatThreadObject* stat;
00062
00063 if (setup.alloc.level == Setup::LEVEL_OBJECT) {
00064
00065 if (setup.alloc.threadsEnabled) {
00066
00067 if (!(stat = getAllocThreadObject(envId, classId, isArray))) {
00068 PROF_ERROR("OBJECT ALLOC", "Cannot get AllocThreadObject");
00069 return;
00070 }
00071 }
00072 else {
00073
00074 if (!(stat = getAllocObject(classId, isArray))) {
00075 PROF_ERROR("OBJECT ALLOC", "Cannot get AllocObject");
00076 return;
00077 }
00078 }
00079 }
00080 else if (setup.alloc.level == Setup::LEVEL_METHOD) {
00081
00082 JVMPI_CallTrace trace;
00083 JVMPI_CallFrame frame;
00084
00085 trace.env_id = envId;
00086 trace.num_frames = (jint)1;
00087 trace.frames = &frame;
00088
00089 jvmpiInterface->GetCallTrace(&trace, (jint)1);
00090 if (trace.num_frames == (jint)0) {
00091 PROF_ERROR("OBJECT ALLOC", "GetCallTrace failed");
00092 return;
00093 }
00094
00095 jmethodID methodId = frame.method_id;
00096
00097 if (setup.alloc.threadsEnabled) {
00098
00099 if (!(stat = getAllocThreadObjectMethod(envId, classId, isArray, methodId))) {
00100 PROF_ERROR("OBJECT ALLOC", "Cannot get AllocThreadObjectMethod");
00101 return;
00102 }
00103 }
00104 else {
00105
00106 if (!(stat = getAllocObjectMethod(classId, isArray, methodId))) {
00107 PROF_ERROR("OBJECT ALLOC", "Cannot get AllocObjectMethod");
00108 return;
00109 }
00110 }
00111 }
00112 else {
00113 JVMPI_CallTrace trace;
00114 JVMPI_CallFrame frames[MAX_TRACE];
00115
00116 trace.env_id = envId;
00117 trace.num_frames = setup.alloc.traceDepth;
00118 trace.frames = frames;
00119
00120 jvmpiInterface->GetCallTrace(&trace, setup.alloc.traceDepth);
00121 if (trace.num_frames == (jint)0) {
00122 PROF_ERROR("OBJECT ALLOC", "GetCallTrace failed");
00123 return;
00124 }
00125
00126 int numFrames = trace.num_frames;
00127
00128 if (setup.alloc.threadsEnabled) {
00129
00130 if (!(stat = getAllocThreadObjectTrace(envId, classId, isArray, numFrames, frames))) {
00131 PROF_ERROR("OBJECT ALLOC", "Cannot get AllocThreadObjectTrace");
00132 return;
00133 }
00134 }
00135 else {
00136
00137 if (!(stat = getAllocObjectTrace(classId, isArray, numFrames, frames))) {
00138 PROF_ERROR("OBJECT ALLOC", "Cannot get AllocObjectTrace");
00139 return;
00140 }
00141 }
00142 }
00143
00144 static int firstTime = 1;
00145 if( firstTime) {
00146
00147 jvmpiInterface->EnableEvent( JVMPI_EVENT_GC_START, NULL);
00148
00149 jvmpiInterface->EnableEvent( JVMPI_EVENT_JNI_GLOBALREF_ALLOC, NULL);
00150 jvmpiInterface->EnableEvent( JVMPI_EVENT_JNI_WEAK_GLOBALREF_ALLOC, NULL);
00151
00152 firstTime = 0;
00153 }
00154
00155 AllocInstance* instance = unusedInstances.first();
00156 if (instance) unusedInstances.remove(instance);
00157 else instance = new AllocInstance;
00158
00159 instance->objId = objId;
00160 instance->size = size;
00161 instance->objectMethodTraceThread = stat;
00162
00163 AllocArena* arena = arenas.first();
00164 while (arena && (!arena->active || arena->arenaId != arenaId))
00165 arena = arenas.next(arena);
00166
00167 instance->arena = arena;
00168 if (arena) arena->instances.add(instance);
00169
00170 instances.add(instance);
00171
00172 stat->addMemoryStat(size);
00173 }
00174
00175 void Prof::event_objectFree( JVMPI_Event* event) {
00176
00177 jobjectID obj_id = event->u.obj_free.obj_id;
00178
00179 AllocInstance* ins = instances.get( obj_id);
00180 if( !ins) return;
00181
00182 ins->objectMethodTraceThread->subMemoryStat( ins->size);
00183
00184 instances.removeNoRehash( ins);
00185 if( ins->arena) ins->arena->instances.remove( ins);
00186
00187 unusedInstances.add( ins);
00188 }
00189
00190 void Prof::event_objectMove( JVMPI_Event* event) {
00191
00192 jobjectID obj_id = event->u.obj_move.obj_id;
00193 AllocInstance* ins = instances.get( obj_id);
00194
00195 if( !ins) {
00196
00197 Class* c = activeClasses.get(obj_id);
00198 if( !c) return;
00199
00200 activeClasses.removeNoRehash(c);
00201 c->classId = event->u.obj_move.new_obj_id;
00202 activeClasses.addNoRehash(c);
00203
00204 AllocObject* o;
00205
00206 if (o = c->allocObject) {
00207 activeAllocObjects.removeNoRehash(o);
00208 o->classId = event->u.obj_move.new_obj_id;
00209 activeAllocObjects.addNoRehash(o);
00210 }
00211
00212 if (o = c->allocObjectArray) {
00213 activeAllocObjects.removeNoRehash(o);
00214 o->classId = event->u.obj_move.new_obj_id;
00215 activeAllocObjects.addNoRehash(o);
00216 }
00217
00218 return;
00219 }
00220
00221 instances.removeNoRehash(ins);
00222 if( ins->arena) ins->arena->instances.remove( ins);
00223
00224 ins->objId = event->u.obj_move.new_obj_id;
00225
00226 jint new_arena_id = event->u.obj_move.new_arena_id;
00227 AllocArena* a = arenas.first();
00228
00229 while( a && ( !a->active || a->arenaId != new_arena_id))
00230 a = arenas.next(a);
00231
00232 ins->arena = a;
00233 if( a) a->instances.add( ins);
00234
00235 instances.addNoRehash( ins);
00236 }