12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627 |
- // jvmti.cc - JVMTI implementation
- /* Copyright (C) 2006, 2007, 2010 Free Software Foundation
- This file is part of libgcj.
- This software is copyrighted work licensed under the terms of the
- Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
- details. */
- #include <config.h>
- #include <platform.h>
- #include <jvm.h>
- #include <java-threads.h>
- #include <java-gc.h>
- #include <java-interp.h>
- #include <jvmti.h>
- #include "jvmti-int.h"
- #include <gcj/method.h>
- #include <gnu/classpath/SystemProperties.h>
- #include <gnu/gcj/runtime/BootClassLoader.h>
- #include <gnu/gcj/jvmti/Breakpoint.h>
- #include <gnu/gcj/jvmti/BreakpointManager.h>
- #include <java/lang/Class.h>
- #include <java/lang/ClassLoader.h>
- #include <java/lang/OutOfMemoryError.h>
- #include <java/lang/Thread.h>
- #include <java/lang/ThreadGroup.h>
- #include <java/lang/Thread$State.h>
- #include <java/lang/Throwable.h>
- #include <java/lang/VMClassLoader.h>
- #include <java/lang/reflect/Field.h>
- #include <java/lang/reflect/Modifier.h>
- #include <java/util/Collection.h>
- #include <java/util/HashMap.h>
- #include <java/util/concurrent/locks/Lock.h>
- #include <java/util/concurrent/locks/ReentrantReadWriteLock.h>
- #include <java/net/URL.h>
- static void check_enabled_events (void);
- static void check_enabled_event (jvmtiEvent);
- namespace JVMTI
- {
- // Is JVMTI enabled? (i.e., any jvmtiEnv created?)
- bool enabled;
- // Event notifications
- bool VMInit = false;
- bool VMDeath = false;
- bool ThreadStart = false;
- bool ThreadEnd = false;
- bool ClassFileLoadHook = false;
- bool ClassLoad = false;
- bool ClassPrepare = false;
- bool VMStart = false;
- bool Exception = false;
- bool ExceptionCatch = false;
- bool SingleStep = false;
- bool FramePop = false;
- bool Breakpoint = false;
- bool FieldAccess = false;
- bool FieldModification = false;
- bool MethodEntry = false;
- bool MethodExit = false;
- bool NativeMethodBind = false;
- bool CompiledMethodLoad = false;
- bool CompiledMethodUnload = false;
- bool DynamicCodeGenerated = false;
- bool DataDumpRequest = false;
- bool reserved72 = false;
- bool MonitorWait = false;
- bool MonitorWaited = false;
- bool MonitorContendedEnter = false;
- bool MonitorContendedEntered = false;
- bool reserved77 = false;
- bool reserved78 = false;
- bool reserved79 = false;
- bool reserved80 = false;
- bool GarbageCollectionStart = false;
- bool GarbageCollectionFinish = false;
- bool ObjectFree = false;
- bool VMObjectAlloc = false;
- };
- extern struct JNINativeInterface _Jv_JNIFunctions;
- struct _Jv_rawMonitorID
- {
- _Jv_Mutex_t mutex;
- _Jv_ConditionVariable_t condition;
- };
- /* A simple linked list of all JVMTI environments. Since
- events must be delivered to environments in the order
- in which the environments were created, new environments
- are added to the end of the list. */
- struct jvmti_env_list
- {
- jvmtiEnv *env;
- struct jvmti_env_list *next;
- };
- static struct jvmti_env_list *_jvmtiEnvironments = NULL;
- static java::util::concurrent::locks::
- ReentrantReadWriteLock *_envListLock = NULL;
- #define FOREACH_ENVIRONMENT(Ele) \
- for (Ele = _jvmtiEnvironments; Ele != NULL; Ele = Ele->next)
- // Some commonly-used checks
- #define THREAD_DEFAULT_TO_CURRENT(Ajthread) \
- do \
- { \
- if (Ajthread == NULL) \
- Ajthread = java::lang::Thread::currentThread (); \
- } \
- while (0)
- #define THREAD_CHECK_VALID(Athread) \
- do \
- { \
- if (!java::lang::Thread::class$.isAssignableFrom (&(Athread->class$))) \
- return JVMTI_ERROR_INVALID_THREAD; \
- } \
- while (0)
- #define THREAD_CHECK_IS_ALIVE(Athread) \
- do \
- { \
- if (!Athread->isAlive ()) \
- return JVMTI_ERROR_THREAD_NOT_ALIVE; \
- } \
- while (0)
- // FIXME: if current phase is not set in Phases,
- // return JVMTI_ERROR_WRONG_PHASE
- #define REQUIRE_PHASE(Env, Phases)
- #define NULL_CHECK(Ptr) \
- do \
- { \
- if (Ptr == NULL) \
- return JVMTI_ERROR_NULL_POINTER; \
- } \
- while (0)
- #define ILLEGAL_ARGUMENT(Cond) \
- do \
- { \
- if ((Cond)) \
- return JVMTI_ERROR_ILLEGAL_ARGUMENT; \
- } \
- while (0)
- #define CHECK_FOR_NATIVE_METHOD(AjmethodID) \
- do \
- { \
- jboolean is_native; \
- jvmtiError jerr = env->IsMethodNative (AjmethodID, &is_native); \
- if (jerr != JVMTI_ERROR_NONE) \
- return jerr; \
- if (is_native) \
- return JVMTI_ERROR_NATIVE_METHOD; \
- } \
- while (0)
- static jvmtiError JNICALL
- _Jv_JVMTI_SuspendThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
- {
- using namespace java::lang;
- THREAD_DEFAULT_TO_CURRENT (thread);
- THREAD_CHECK_VALID (thread);
- THREAD_CHECK_IS_ALIVE (thread);
- _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
- _Jv_SuspendThread (data);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_ResumeThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
- {
- using namespace java::lang;
- THREAD_DEFAULT_TO_CURRENT (thread);
- THREAD_CHECK_VALID (thread);
- THREAD_CHECK_IS_ALIVE (thread);
- _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
- _Jv_ResumeThread (data);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_InterruptThread (MAYBE_UNUSED jvmtiEnv *env, jthread thread)
- {
- using namespace java::lang;
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- // FIXME: capability handling? 'can_signal_thread'
- if (thread == NULL)
- return JVMTI_ERROR_INVALID_THREAD;
- THREAD_CHECK_VALID (thread);
- THREAD_CHECK_IS_ALIVE (thread);
- thread->interrupt();
- return JVMTI_ERROR_NONE;
- }
- // This method performs the common tasks to get and set variables of all types.
- // It is called by the _Jv_JVMTI_Get/SetLocalInt/Object/.... methods.
- static jvmtiError
- getLocalFrame (jvmtiEnv *env, jthread thread, jint depth, jint slot, char type,
- _Jv_InterpFrame **iframe)
- {
- using namespace java::lang;
-
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
-
- ILLEGAL_ARGUMENT (depth < 0);
-
- THREAD_DEFAULT_TO_CURRENT (thread);
- THREAD_CHECK_VALID (thread);
- THREAD_CHECK_IS_ALIVE (thread);
-
- _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
-
- for (int i = 0; i < depth; i++)
- {
- frame = frame->next;
-
- if (frame == NULL)
- return JVMTI_ERROR_NO_MORE_FRAMES;
- }
-
- if (frame->frame_type == frame_native)
- return JVMTI_ERROR_OPAQUE_FRAME;
-
- jint max_locals;
- jvmtiError jerr = env->GetMaxLocals (reinterpret_cast<jmethodID>
- (frame->self->get_method ()),
- &max_locals);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- _Jv_InterpFrame *tmp_iframe = reinterpret_cast<_Jv_InterpFrame *> (frame);
-
- // The second slot taken up by a long type is marked as type 'x' meaning it
- // is not valid for access since it holds only the 4 low bytes of the value.
- if (tmp_iframe->locals_type[slot] == 'x')
- return JVMTI_ERROR_INVALID_SLOT;
-
- if (tmp_iframe->locals_type[slot] != type)
- return JVMTI_ERROR_TYPE_MISMATCH;
-
- // Check for invalid slots, if the type is a long type, we must check that
- // the next slot is valid as well.
- if (slot < 0 || slot >= max_locals
- || ((type == 'l' || type == 'd') && slot + 1 >= max_locals))
- return JVMTI_ERROR_INVALID_SLOT;
-
- *iframe = tmp_iframe;
-
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jobject *value)
- {
- NULL_CHECK (value);
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- *value = frame->locals[slot].o;
-
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetLocalObject (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jobject value)
- {
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'o', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- frame->locals[slot].o = value;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jint *value)
- {
- NULL_CHECK (value);
-
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- *value = frame->locals[slot].i;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetLocalInt (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jint value)
- {
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'i', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- frame->locals[slot].i = value;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jlong *value)
- {
- NULL_CHECK (value);
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- #if SIZEOF_VOID_P==8
- *value = frame->locals[slot].l;
- #else
- _Jv_word2 val;
- val.ia[0] = frame->locals[slot].ia[0];
- val.ia[1] = frame->locals[slot + 1].ia[0];
- *value = val.l;
- #endif
-
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetLocalLong (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jlong value)
- {
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'l', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- #if SIZEOF_VOID_P==8
- frame->locals[slot].l = value;
- #else
- _Jv_word2 val;
- val.l = value;
- frame->locals[slot].ia[0] = val.ia[0];
- frame->locals[slot + 1].ia[0] = val.ia[1];
- #endif
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jfloat *value)
- {
- NULL_CHECK (value);
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- *value = frame->locals[slot].f;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetLocalFloat (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jfloat value)
- {
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'f', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- frame->locals[slot].f = value;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jdouble *value)
- {
- NULL_CHECK (value);
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- #if SIZEOF_VOID_P==8
- *value = frame->locals[slot].d;
- #else
- _Jv_word2 val;
- val.ia[0] = frame->locals[slot].ia[0];
- val.ia[1] = frame->locals[slot + 1].ia[0];
- *value = val.d;
- #endif
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetLocalDouble (jvmtiEnv *env, jthread thread, jint depth, jint slot,
- jdouble value)
- {
- _Jv_InterpFrame *frame;
- jvmtiError jerr = getLocalFrame (env, thread, depth, slot, 'd', &frame);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- #if SIZEOF_VOID_P==8
- frame->locals[slot].d = value;
- #else
- _Jv_word2 val;
- val.d = value;
- frame->locals[slot].ia[0] = val.ia[0];
- frame->locals[slot + 1].ia[0] = val.ia[1];
- #endif
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetAllThreads(MAYBE_UNUSED jvmtiEnv *env, jint *thread_cnt,
- jthread **threads)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- NULL_CHECK (thread_cnt);
- NULL_CHECK (threads);
-
- using namespace java::lang;
-
- ThreadGroup *root_grp = ThreadGroup::root;
- jint estimate = root_grp->activeCount ();
- JArray<Thread *> *thr_arr;
- // Allocate some extra space since threads can be created between calls
- try
- {
- thr_arr = reinterpret_cast<JArray<Thread *> *> (JvNewObjectArray
- ((estimate * 2),
- &Thread::class$, NULL));
- }
- catch (java::lang::OutOfMemoryError *err)
- {
- return JVMTI_ERROR_OUT_OF_MEMORY;
- }
-
- *thread_cnt = root_grp->enumerate (thr_arr);
-
- jvmtiError jerr = env->Allocate ((jlong) ((*thread_cnt) * sizeof (jthread)),
- (unsigned char **) threads);
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- // Transfer the threads to the result array
- jthread *tmp_arr = reinterpret_cast<jthread *> (elements (thr_arr));
-
- memcpy ((*threads), tmp_arr, (*thread_cnt));
-
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetFrameCount (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
- jint *frame_count)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
-
- NULL_CHECK (frame_count);
-
- using namespace java::lang;
-
- THREAD_DEFAULT_TO_CURRENT (thread);
- THREAD_CHECK_VALID (thread);
- THREAD_CHECK_IS_ALIVE (thread);
-
- _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
- (*frame_count) = frame->depth ();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetThreadState (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
- jint *thread_state_ptr)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- THREAD_DEFAULT_TO_CURRENT (thread);
- THREAD_CHECK_VALID (thread);
- NULL_CHECK (thread_state_ptr);
- jint state = 0;
- if (thread->isAlive ())
- {
- state |= JVMTI_THREAD_STATE_ALIVE;
- _Jv_Thread_t *data = _Jv_ThreadGetData (thread);
- if (_Jv_IsThreadSuspended (data))
- state |= JVMTI_THREAD_STATE_SUSPENDED;
- if (thread->isInterrupted ())
- state |= JVMTI_THREAD_STATE_INTERRUPTED;
- _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
- if (frame != NULL && frame->frame_type == frame_native)
- state |= JVMTI_THREAD_STATE_IN_NATIVE;
- using namespace java::lang;
- Thread$State *ts = thread->getState ();
- if (ts == Thread$State::RUNNABLE)
- state |= JVMTI_THREAD_STATE_RUNNABLE;
- else if (ts == Thread$State::BLOCKED)
- state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
- else if (ts == Thread$State::TIMED_WAITING
- || ts == Thread$State::WAITING)
- {
- state |= JVMTI_THREAD_STATE_WAITING;
- state |= ((ts == Thread$State::WAITING)
- ? JVMTI_THREAD_STATE_WAITING_INDEFINITELY
- : JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT);
- /* FIXME: We don't have a way to tell
- the caller why the thread is suspended,
- i.e., JVMTI_THREAD_STATE_SLEEPING,
- JVMTI_THREAD_STATE_PARKED, and
- JVMTI_THREAD_STATE_IN_OBJECT_WAIT
- are never set. */
- }
- }
- else
- {
- using namespace java::lang;
- Thread$State *ts = thread->getState ();
- if (ts == Thread$State::TERMINATED)
- state |= JVMTI_THREAD_STATE_TERMINATED;
- }
- *thread_state_ptr = state;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_CreateRawMonitor (MAYBE_UNUSED jvmtiEnv *env, const char *name,
- jrawMonitorID *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
- NULL_CHECK (name);
- NULL_CHECK (result);
- *result = (jrawMonitorID) _Jv_MallocUnchecked (sizeof (_Jv_rawMonitorID));
- if (*result == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- _Jv_MutexInit (&(*result)->mutex);
- _Jv_CondInit (&(*result)->condition);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_DestroyRawMonitor (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
- // Note we have no better way of knowing whether this object is
- // really a raw monitor.
- if (monitor == NULL)
- return JVMTI_ERROR_INVALID_MONITOR;
- // FIXME: perform checks on monitor, release it if this thread owns
- // it.
- #ifdef _Jv_HaveMutexDestroy
- _Jv_MutexDestroy (&monitor->mutex);
- #endif
- _Jv_Free (monitor);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_RawMonitorEnter (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
- {
- if (monitor == NULL)
- return JVMTI_ERROR_INVALID_MONITOR;
- _Jv_MutexLock (&monitor->mutex);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_RawMonitorExit (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
- {
- if (monitor == NULL)
- return JVMTI_ERROR_INVALID_MONITOR;
- if (_Jv_MutexUnlock (&monitor->mutex))
- return JVMTI_ERROR_NOT_MONITOR_OWNER;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_RawMonitorWait (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor,
- jlong millis)
- {
- if (monitor == NULL)
- return JVMTI_ERROR_INVALID_MONITOR;
- int r = _Jv_CondWait (&monitor->condition, &monitor->mutex, millis, 0);
- if (r == _JV_NOT_OWNER)
- return JVMTI_ERROR_NOT_MONITOR_OWNER;
- if (r == _JV_INTERRUPTED)
- return JVMTI_ERROR_INTERRUPT;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_RawMonitorNotify (MAYBE_UNUSED jvmtiEnv *env, jrawMonitorID monitor)
- {
- if (monitor == NULL)
- return JVMTI_ERROR_INVALID_MONITOR;
- if (_Jv_CondNotify (&monitor->condition, &monitor->mutex) == _JV_NOT_OWNER)
- return JVMTI_ERROR_NOT_MONITOR_OWNER;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_RawMonitorNotifyAll (MAYBE_UNUSED jvmtiEnv *env,
- jrawMonitorID monitor)
- {
- if (monitor == NULL)
- return JVMTI_ERROR_INVALID_MONITOR;
- if (_Jv_CondNotifyAll (&monitor->condition, &monitor->mutex)
- == _JV_NOT_OWNER)
- return JVMTI_ERROR_NOT_MONITOR_OWNER;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetBreakpoint (jvmtiEnv *env, jmethodID method, jlocation location)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- using namespace gnu::gcj::jvmti;
- Breakpoint *bp
- = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
- location);
- if (bp == NULL)
- {
- jclass klass;
- jvmtiError err = env->GetMethodDeclaringClass (method, &klass);
- if (err != JVMTI_ERROR_NONE)
- return err;
- if (!_Jv_IsInterpretedClass (klass))
- return JVMTI_ERROR_INVALID_CLASS;
- _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
- if (base == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
- jint flags;
- err = env->GetMethodModifiers (method, &flags);
- if (err != JVMTI_ERROR_NONE)
- return err;
- if (flags & java::lang::reflect::Modifier::NATIVE)
- return JVMTI_ERROR_NATIVE_METHOD;
- _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
- if (imeth->get_insn (location) == NULL)
- return JVMTI_ERROR_INVALID_LOCATION;
- // Now the breakpoint can be safely installed
- bp = BreakpointManager::newBreakpoint (reinterpret_cast<jlong> (method),
- location);
- }
- else
- {
- // Duplicate breakpoints are not permitted by JVMTI
- return JVMTI_ERROR_DUPLICATE;
- }
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_ClearBreakpoint (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
- jlocation location)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- using namespace gnu::gcj::jvmti;
- Breakpoint *bp
- = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
- location);
- if (bp == NULL)
- return JVMTI_ERROR_NOT_FOUND;
- BreakpointManager::deleteBreakpoint (reinterpret_cast<jlong> (method), location);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_Allocate (MAYBE_UNUSED jvmtiEnv *env, jlong size,
- unsigned char **result)
- {
- ILLEGAL_ARGUMENT (size < 0);
- NULL_CHECK (result);
- if (size == 0)
- *result = NULL;
- else
- {
- *result = (unsigned char *) _Jv_MallocUnchecked (size);
- if (*result == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- }
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_Deallocate (MAYBE_UNUSED jvmtiEnv *env, unsigned char *mem)
- {
- if (mem != NULL)
- _Jv_Free (mem);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetClassStatus (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jint *status_ptr)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- NULL_CHECK (status_ptr);
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- if (klass->isArray ())
- *status_ptr = JVMTI_CLASS_STATUS_ARRAY;
- else if (klass->isPrimitive ())
- *status_ptr = JVMTI_CLASS_STATUS_PRIMITIVE;
- else
- {
- jbyte state = _Jv_GetClassState (klass);
- *status_ptr = 0;
- if (state >= JV_STATE_LINKED)
- (*status_ptr) |= JVMTI_CLASS_STATUS_VERIFIED;
- if (state >= JV_STATE_PREPARED)
- (*status_ptr) |= JVMTI_CLASS_STATUS_PREPARED;
- if (state == JV_STATE_ERROR || state == JV_STATE_PHANTOM)
- (*status_ptr) |= JVMTI_CLASS_STATUS_ERROR;
- else if (state == JV_STATE_DONE)
- (*status_ptr) |= JVMTI_CLASS_STATUS_INITIALIZED;
- }
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetClassModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jint *mods)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- // Don't bother checking KLASS' type.
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- NULL_CHECK (mods);
- *mods = klass->getModifiers();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetClassMethods (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jint *count_ptr, jmethodID **methods_ptr)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- // FIXME: capability can_maintain_original_method_order
- // Don't bother checking KLASS' type.
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- NULL_CHECK (count_ptr);
- NULL_CHECK (methods_ptr);
- *count_ptr = JvNumMethods(klass);
- *methods_ptr
- = (jmethodID *) _Jv_MallocUnchecked (*count_ptr * sizeof (jmethodID));
- if (*methods_ptr == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- jmethodID start = JvGetFirstMethod (klass);
- for (jint i = 0; i < *count_ptr; ++i)
- // FIXME: correct?
- (*methods_ptr)[i] = start + i;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_IsInterface (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jboolean *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- NULL_CHECK (result);
- *result = klass->isInterface();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_IsArrayClass (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jboolean *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- NULL_CHECK (result);
- *result = klass->isArray();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetClassLoader (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jobject *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- NULL_CHECK (result);
- *result = klass->getClassLoaderInternal();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetObjectHashCode (MAYBE_UNUSED jvmtiEnv *env, jobject obj,
- jint *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (obj == NULL)
- return JVMTI_ERROR_INVALID_OBJECT;
- NULL_CHECK (result);
- *result = _Jv_HashCode (obj);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetFieldModifiers (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jfieldID field, jint *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- if (field == NULL)
- return JVMTI_ERROR_INVALID_FIELDID;
- NULL_CHECK (result);
- *result = field->getModifiers();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_IsFieldSynthetic (MAYBE_UNUSED jvmtiEnv *env, jclass klass,
- jfieldID field, jboolean *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (klass == NULL)
- return JVMTI_ERROR_INVALID_CLASS;
- if (field == NULL)
- return JVMTI_ERROR_INVALID_FIELDID;
- NULL_CHECK (result);
- // FIXME: capability can_get_synthetic_attribute
- *result = ((field->getModifiers() & java::lang::reflect::Modifier::SYNTHETIC)
- != 0);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetMethodName (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
- char **name_ptr, char **signature_ptr,
- char **generic_ptr)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (method == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
- if (name_ptr != NULL)
- {
- int len = static_cast<int> (method->name->len ());
- *name_ptr = (char *) _Jv_MallocUnchecked (len + 1);
- if (*name_ptr == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- strncpy (*name_ptr, method->name->chars (), len);
- (*name_ptr)[len] = '\0';
- }
- if (signature_ptr != NULL)
- {
- int len = static_cast<int> (method->signature->len ());
- *signature_ptr = (char *) _Jv_MallocUnchecked (len + 1);
- if (*signature_ptr == NULL)
- {
- if (name_ptr != NULL)
- _Jv_Free (*name_ptr);
- return JVMTI_ERROR_OUT_OF_MEMORY;
- }
- strncpy (*signature_ptr, method->signature->chars (), len);
- (*signature_ptr)[len] = '\0';
- }
- if (generic_ptr != NULL)
- {
- *generic_ptr = NULL;
- }
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetMethodModifiers (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
- jint *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (method == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
- NULL_CHECK (result);
- // FIXME: mask off some internal bits...
- *result = method->accflags;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetLineNumberTable (jvmtiEnv *env, jmethodID method,
- jint *entry_count_ptr,
- jvmtiLineNumberEntry **table_ptr)
- {
- NULL_CHECK (entry_count_ptr);
- NULL_CHECK (table_ptr);
- jclass klass;
- jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- _Jv_MethodBase *base = _Jv_FindInterpreterMethod (klass, method);
- if (base == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
- if (java::lang::reflect::Modifier::isNative (method->accflags)
- || !_Jv_IsInterpretedClass (klass))
- return JVMTI_ERROR_NATIVE_METHOD;
- _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *> (base);
- jlong start, end;
- jintArray lines = NULL;
- jlongArray indices = NULL;
- imeth->get_line_table (start, end, lines, indices);
- if (lines == NULL)
- return JVMTI_ERROR_ABSENT_INFORMATION;
- jvmtiLineNumberEntry *table;
- jsize len = lines->length * sizeof (jvmtiLineNumberEntry);
- table = (jvmtiLineNumberEntry *) _Jv_MallocUnchecked (len);
- if (table == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
-
- jint *line = elements (lines);
- jlong *index = elements (indices);
- for (int i = 0; i < lines->length; ++i)
- {
- table[i].start_location = index[i];
- table[i].line_number = line[i];
- }
- *table_ptr = table;
- *entry_count_ptr = lines->length;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetLocalVariableTable (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
- jint *num_locals,
- jvmtiLocalVariableEntry **locals)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- NULL_CHECK (num_locals);
- NULL_CHECK (locals);
-
- CHECK_FOR_NATIVE_METHOD(method);
-
- jclass klass;
- jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
- (_Jv_FindInterpreterMethod (klass, method));
-
- if (imeth == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
-
- jerr = env->GetMaxLocals (method, num_locals);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- jerr = env->Allocate (static_cast<jlong>
- ((*num_locals) * sizeof (jvmtiLocalVariableEntry)),
- reinterpret_cast<unsigned char **> (locals));
-
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- //the slot in the methods local_var_table to get
- int table_slot = 0;
- char *name;
- char *sig;
- char *generic_sig;
-
- while (table_slot < *num_locals
- && imeth->get_local_var_table (&name, &sig, &generic_sig,
- &((((*locals)[table_slot].start_location))),
- &((*locals)[table_slot].length),
- &((*locals)[table_slot].slot),
- table_slot)
- >= 0)
- {
- char **str_ptr = &(*locals)[table_slot].name;
- jerr = env->Allocate (static_cast<jlong> (strlen (name) + 1),
- reinterpret_cast<unsigned char **> (str_ptr));
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- strcpy ((*locals)[table_slot].name, name);
-
- str_ptr = &(*locals)[table_slot].signature;
- jerr = env->Allocate (static_cast<jlong> (strlen (sig) + 1),
- reinterpret_cast<unsigned char **> (str_ptr));
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- strcpy ((*locals)[table_slot].signature, sig);
-
- str_ptr = &(*locals)[table_slot].generic_signature;
- jerr = env->Allocate (static_cast<jlong> (strlen (generic_sig) + 1),
- reinterpret_cast<unsigned char **> (str_ptr));
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- strcpy ((*locals)[table_slot].generic_signature, generic_sig);
-
- table_slot++;
- }
- if (table_slot == 0)
- return JVMTI_ERROR_ABSENT_INFORMATION;
-
- // If there are double or long variables in the table, the the table will be
- // smaller than the max number of slots, so correct for this here.
- if ((table_slot) < *num_locals)
- *num_locals = table_slot;
-
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_IsMethodNative (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
- jboolean *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (method == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
- NULL_CHECK (result);
- *result = ((method->accflags & java::lang::reflect::Modifier::NATIVE) != 0);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_IsMethodSynthetic (MAYBE_UNUSED jvmtiEnv *env, jmethodID method,
- jboolean *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (method == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
- NULL_CHECK (result);
- // FIXME capability can_get_synthetic_attribute
- *result = ((method->accflags & java::lang::reflect::Modifier::SYNTHETIC)
- != 0);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetMaxLocals (jvmtiEnv *env, jmethodID method, jint *max_locals)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- NULL_CHECK (max_locals);
-
- CHECK_FOR_NATIVE_METHOD (method);
-
- jclass klass;
- jvmtiError jerr = env->GetMethodDeclaringClass (method, &klass);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
- _Jv_InterpMethod *imeth = reinterpret_cast<_Jv_InterpMethod *>
- (_Jv_FindInterpreterMethod (klass, method));
-
- if (imeth == NULL)
- return JVMTI_ERROR_INVALID_METHODID;
-
- *max_locals = imeth->get_max_locals ();
-
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetArgumentsSize (jvmtiEnv *env, jmethodID method, jint *size)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- NULL_CHECK (size);
-
- CHECK_FOR_NATIVE_METHOD (method);
-
- jvmtiError jerr;
- char *sig;
- jint num_slots = 0;
-
- jerr = env->GetMethodName (method, NULL, &sig, NULL);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- // If the method is non-static add a slot for the "this" pointer.
- if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
- num_slots++;
-
- for (int i = 0; sig[i] != ')'; i++)
- {
- if (sig[i] == 'Z' || sig[i] == 'B' || sig[i] == 'C' || sig[i] == 'S'
- || sig[i] == 'I' || sig[i] == 'F')
- num_slots++;
- else if (sig[i] == 'J' || sig[i] == 'D')
- {
- // If this is an array of wide types it uses a single slot
- if (i > 0 && sig[i - 1] == '[')
- num_slots++;
- else
- num_slots += 2;
- }
- else if (sig[i] == 'L')
- {
- num_slots++;
- while (sig[i] != ';')
- i++;
- }
- }
-
- *size = num_slots;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetMethodDeclaringClass (MAYBE_UNUSED jvmtiEnv *env,
- jmethodID method,
- jclass *declaring_class_ptr)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- NULL_CHECK (declaring_class_ptr);
- jclass klass = _Jv_GetMethodDeclaringClass (method);
- if (klass != NULL)
- {
- *declaring_class_ptr = klass;
- return JVMTI_ERROR_NONE;
- }
- return JVMTI_ERROR_INVALID_METHODID;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetClassLoaderClasses (MAYBE_UNUSED jvmtiEnv *env,
- jobject init_loader,
- jint *count_ptr,
- jclass **result_ptr)
- {
- using namespace java::lang;
- using namespace java::util;
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- NULL_CHECK (count_ptr);
- NULL_CHECK (result_ptr);
- ClassLoader *loader = (ClassLoader *) init_loader;
- if (loader == NULL)
- loader = VMClassLoader::bootLoader;
- Collection *values = loader->loadedClasses->values();
- jobjectArray array = values->toArray();
- *count_ptr = array->length;
- jobject *elts = elements (array);
- jclass *result
- = (jclass *) _Jv_MallocUnchecked (*count_ptr * sizeof (jclass));
- if (result == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- // FIXME: JNI references...
- memcpy (result, elts, *count_ptr * sizeof (jclass));
- *result_ptr = result;
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetStackTrace (MAYBE_UNUSED jvmtiEnv *env, jthread thread,
- jint start_depth, jint max_frames,
- jvmtiFrameInfo *frames, jint *frame_count)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- ILLEGAL_ARGUMENT (max_frames < 0);
-
- NULL_CHECK (frames);
- NULL_CHECK (frame_count);
-
- using namespace java::lang;
-
- THREAD_DEFAULT_TO_CURRENT (thread);
- THREAD_CHECK_VALID (thread);
- THREAD_CHECK_IS_ALIVE (thread);
-
- jvmtiError jerr = env->GetFrameCount (thread, frame_count);
- if (jerr != JVMTI_ERROR_NONE)
- return jerr;
-
- // start_depth can be either a positive number, indicating the depth of the
- // stack at which to begin the trace, or a negative number indicating the
- // number of frames at the bottom of the stack to exclude. These checks
- // ensure that it is a valid value in either case
-
- ILLEGAL_ARGUMENT (start_depth >= (*frame_count));
- ILLEGAL_ARGUMENT (start_depth < (-(*frame_count)));
-
- _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
- // If start_depth is negative use this to determine at what depth to start
- // the trace by adding it to the length of the call stack. This allows the
- // use of the same frame "discarding" mechanism as for a positive start_depth
- if (start_depth < 0)
- start_depth = *frame_count + start_depth;
-
- // If start_depth > 0 "remove" start_depth frames from the beginning
- // of the stack before beginning the trace by moving along the frame list.
- while (start_depth > 0)
- {
- frame = frame->next;
- start_depth--;
- (*frame_count)--;
- }
-
- // Now check to see if the array supplied by the agent is large enough to
- // hold frame_count frames, after adjustment for start_depth.
- if ((*frame_count) > max_frames)
- (*frame_count) = max_frames;
-
- for (int i = 0; i < (*frame_count); i++)
- {
- frames[i].method = frame->self->get_method ();
-
- // Set the location in the frame, native frames have location = -1
- if (frame->frame_type == frame_interpreter)
- {
- _Jv_InterpMethod *imeth
- = static_cast<_Jv_InterpMethod *> (frame->self);
- _Jv_InterpFrame *interp_frame
- = static_cast<_Jv_InterpFrame *> (frame);
- frames[i].location = imeth->insn_index (interp_frame->get_pc ());
- }
- else
- frames[i].location = -1;
-
- frame = frame->next;
- }
-
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_ForceGarbageCollection (MAYBE_UNUSED jvmtiEnv *env)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_LIVE);
- _Jv_RunGC();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
- const jniNativeInterface *function_table)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- NULL_CHECK (function_table);
- memcpy (&_Jv_JNIFunctions, function_table, sizeof (jniNativeInterface));
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetJNIFunctionTable (MAYBE_UNUSED jvmtiEnv *env,
- jniNativeInterface **function_table)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- NULL_CHECK (function_table);
- *function_table
- = (jniNativeInterface *) _Jv_MallocUnchecked (sizeof (jniNativeInterface));
- if (*function_table == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- memcpy (*function_table, &_Jv_JNIFunctions, sizeof (jniNativeInterface));
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_DisposeEnvironment (jvmtiEnv *env)
- {
- NULL_CHECK (env);
- if (_jvmtiEnvironments == NULL)
- return JVMTI_ERROR_INVALID_ENVIRONMENT;
- else
- {
- _envListLock->writeLock ()->lock ();
- if (_jvmtiEnvironments->env == env)
- {
- struct jvmti_env_list *next = _jvmtiEnvironments->next;
- _Jv_Free (_jvmtiEnvironments);
- _jvmtiEnvironments = next;
- }
- else
- {
- struct jvmti_env_list *e = _jvmtiEnvironments;
- while (e->next != NULL && e->next->env != env)
- e = e->next;
- if (e->next == NULL)
- {
- _envListLock->writeLock ()->unlock ();
- return JVMTI_ERROR_INVALID_ENVIRONMENT;
- }
- struct jvmti_env_list *next = e->next->next;
- _Jv_Free (e->next);
- e->next = next;
- }
- _envListLock->writeLock ()->unlock ();
- }
- _Jv_Free (env);
- check_enabled_events ();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
- char **result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
- NULL_CHECK (property);
- NULL_CHECK (result);
- jstring name = JvNewStringUTF(property);
- jstring result_str = gnu::classpath::SystemProperties::getProperty(name);
- if (result_str == NULL)
- return JVMTI_ERROR_NOT_AVAILABLE;
- int len = JvGetStringUTFLength (result_str);
- *result = (char *) _Jv_MallocUnchecked (len + 1);
- if (*result == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- JvGetStringUTFRegion (result_str, 0, result_str->length(), *result);
- (*result)[len] = '\0';
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetSystemProperty (MAYBE_UNUSED jvmtiEnv *env, const char *property,
- const char *value)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
- NULL_CHECK (property);
- if (value == NULL)
- {
- // FIXME: When would a property not be writeable?
- return JVMTI_ERROR_NONE;
- }
- jstring prop_str = JvNewStringUTF(property);
- jstring value_str = JvNewStringUTF(value);
- gnu::classpath::SystemProperties::setProperty(prop_str, value_str);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetTime (MAYBE_UNUSED jvmtiEnv *env, jlong *nanos_ptr)
- {
- NULL_CHECK (nanos_ptr);
- *nanos_ptr = _Jv_platform_nanotime();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetAvailableProcessors (MAYBE_UNUSED jvmtiEnv *env,
- jint *nprocessors_ptr)
- {
- NULL_CHECK (nprocessors_ptr);
- #ifdef _SC_NPROCESSORS_ONLN
- *nprocessors_ptr = sysconf(_SC_NPROCESSORS_ONLN);
- #else
- *nprocessors_ptr = 1;
- #endif
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_AddToBootstrapClassLoaderSearch (MAYBE_UNUSED jvmtiEnv *env,
- const char *segment)
- {
- using namespace java::lang;
- using namespace java::net;
- using namespace gnu::gcj::runtime;
- REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD);
- NULL_CHECK (segment);
- jstring str_segment = JvNewStringUTF(segment);
- URL *url;
- try
- {
- url = new URL(JvNewStringUTF("file"), NULL, str_segment);
- }
- catch (jthrowable ignore)
- {
- return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- }
- BootClassLoader *loader = VMClassLoader::bootLoader;
- // Don't call this too early.
- // assert (loader != NULL);
- loader->addURL(url);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetVerboseFlag (MAYBE_UNUSED jvmtiEnv *env, jvmtiVerboseFlag flag,
- jboolean value)
- {
- switch (flag)
- {
- case JVMTI_VERBOSE_OTHER:
- case JVMTI_VERBOSE_GC:
- case JVMTI_VERBOSE_JNI:
- // Ignore.
- break;
- case JVMTI_VERBOSE_CLASS:
- gcj::verbose_class_flag = value;
- break;
- default:
- return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- }
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetObjectSize (MAYBE_UNUSED jvmtiEnv *env, jobject object,
- jlong *result)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_START | JVMTI_PHASE_LIVE);
- if (object == NULL)
- return JVMTI_ERROR_INVALID_OBJECT;
- NULL_CHECK (result);
- jclass klass = object->getClass();
- if (klass->isArray())
- {
- jclass comp = klass->getComponentType();
- jint base
- = (jint) (_Jv_uintptr_t) _Jv_GetArrayElementFromElementType(NULL,
- klass->getComponentType());
- // FIXME: correct for primitive types?
- jint compSize = comp->size();
- __JArray *array = (__JArray *) object;
- *result = base + array->length * compSize;
- }
- else
- {
- // Note that if OBJECT is a String then it may (if
- // str->data==str) take more space. Do we care?
- *result = klass->size();
- }
- return JVMTI_ERROR_NONE;
- }
- /* An event is enabled only if it has both an event handler
- and it is enabled in the environment. */
- static void
- check_enabled_event (jvmtiEvent type)
- {
- bool *enabled;
- int offset;
- #define GET_OFFSET(Event) \
- do \
- { \
- enabled = &JVMTI::Event; \
- offset = offsetof (jvmtiEventCallbacks, Event); \
- } \
- while (0)
- switch (type)
- {
- case JVMTI_EVENT_VM_INIT:
- GET_OFFSET (VMInit);
- break;
- case JVMTI_EVENT_VM_DEATH:
- GET_OFFSET (VMDeath);
- break;
- case JVMTI_EVENT_THREAD_START:
- GET_OFFSET (ThreadStart);
- break;
- case JVMTI_EVENT_THREAD_END:
- GET_OFFSET (ThreadEnd);
- break;
- case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
- GET_OFFSET (ClassFileLoadHook);
- break;
- case JVMTI_EVENT_CLASS_LOAD:
- GET_OFFSET (ClassLoad);
- break;
- case JVMTI_EVENT_CLASS_PREPARE:
- GET_OFFSET (ClassPrepare);
- break;
- case JVMTI_EVENT_VM_START:
- GET_OFFSET (VMStart);
- break;
- case JVMTI_EVENT_EXCEPTION:
- GET_OFFSET (Exception);
- break;
- case JVMTI_EVENT_EXCEPTION_CATCH:
- GET_OFFSET (ExceptionCatch);
- break;
- case JVMTI_EVENT_SINGLE_STEP:
- GET_OFFSET (SingleStep);
- break;
- case JVMTI_EVENT_FRAME_POP:
- GET_OFFSET (FramePop);
- break;
- case JVMTI_EVENT_BREAKPOINT:
- GET_OFFSET (Breakpoint);
- break;
- case JVMTI_EVENT_FIELD_ACCESS:
- GET_OFFSET (FieldAccess);
- break;
- case JVMTI_EVENT_FIELD_MODIFICATION:
- GET_OFFSET (FieldModification);
- break;
- case JVMTI_EVENT_METHOD_ENTRY:
- GET_OFFSET (MethodEntry);
- break;
- case JVMTI_EVENT_METHOD_EXIT:
- GET_OFFSET (MethodExit);
- break;
- case JVMTI_EVENT_NATIVE_METHOD_BIND:
- GET_OFFSET (NativeMethodBind);
- break;
- case JVMTI_EVENT_COMPILED_METHOD_LOAD:
- GET_OFFSET (CompiledMethodLoad);
- break;
- case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
- GET_OFFSET (CompiledMethodUnload);
- break;
- case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
- GET_OFFSET (DynamicCodeGenerated);
- break;
- case JVMTI_EVENT_DATA_DUMP_REQUEST:
- GET_OFFSET (DataDumpRequest);
- break;
- case JVMTI_EVENT_MONITOR_WAIT:
- GET_OFFSET (MonitorWait);
- break;
- case JVMTI_EVENT_MONITOR_WAITED:
- GET_OFFSET (MonitorWaited);
- break;
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
- GET_OFFSET (MonitorContendedEnter);
- break;
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
- GET_OFFSET (MonitorContendedEntered);
- break;
- case JVMTI_EVENT_GARBAGE_COLLECTION_START:
- GET_OFFSET (GarbageCollectionStart);
- break;
- case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
- GET_OFFSET (GarbageCollectionFinish);
- break;
- case JVMTI_EVENT_OBJECT_FREE:
- GET_OFFSET (ObjectFree);
- break;
- case JVMTI_EVENT_VM_OBJECT_ALLOC:
- GET_OFFSET (VMObjectAlloc);
- break;
- default:
- fprintf (stderr,
- "libgcj: check_enabled_event for unknown JVMTI event (%d)\n",
- (int) type);
- return;
- }
- #undef GET_OFFSET
- int index = EVENT_INDEX (type); // safe since caller checks this
- if (_jvmtiEnvironments != NULL)
- {
- _envListLock->readLock ()->lock ();
- struct jvmti_env_list *e;
- FOREACH_ENVIRONMENT (e)
- {
- char *addr
- = reinterpret_cast<char *> (&e->env->callbacks) + offset;
- void **callback = reinterpret_cast<void **> (addr);
- if (e->env->enabled[index] && *callback != NULL)
- {
- *enabled = true;
- _envListLock->readLock ()->unlock ();
- return;
- }
- }
- _envListLock->readLock ()->unlock ();
- }
- *enabled = false;
- }
- static void
- check_enabled_events ()
- {
- check_enabled_event (JVMTI_EVENT_VM_INIT);
- check_enabled_event (JVMTI_EVENT_VM_DEATH);
- check_enabled_event (JVMTI_EVENT_THREAD_START);
- check_enabled_event (JVMTI_EVENT_THREAD_END);
- check_enabled_event (JVMTI_EVENT_CLASS_FILE_LOAD_HOOK);
- check_enabled_event (JVMTI_EVENT_CLASS_LOAD);
- check_enabled_event (JVMTI_EVENT_CLASS_PREPARE);
- check_enabled_event (JVMTI_EVENT_VM_START);
- check_enabled_event (JVMTI_EVENT_EXCEPTION);
- check_enabled_event (JVMTI_EVENT_EXCEPTION_CATCH);
- check_enabled_event (JVMTI_EVENT_SINGLE_STEP);
- check_enabled_event (JVMTI_EVENT_FRAME_POP);
- check_enabled_event (JVMTI_EVENT_BREAKPOINT);
- check_enabled_event (JVMTI_EVENT_FIELD_ACCESS);
- check_enabled_event (JVMTI_EVENT_FIELD_MODIFICATION);
- check_enabled_event (JVMTI_EVENT_METHOD_ENTRY);
- check_enabled_event (JVMTI_EVENT_METHOD_EXIT);
- check_enabled_event (JVMTI_EVENT_NATIVE_METHOD_BIND);
- check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_LOAD);
- check_enabled_event (JVMTI_EVENT_COMPILED_METHOD_UNLOAD);
- check_enabled_event (JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
- check_enabled_event (JVMTI_EVENT_DATA_DUMP_REQUEST);
- check_enabled_event (JVMTI_EVENT_MONITOR_WAIT);
- check_enabled_event (JVMTI_EVENT_MONITOR_WAITED);
- check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTER);
- check_enabled_event (JVMTI_EVENT_MONITOR_CONTENDED_ENTERED);
- check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_START);
- check_enabled_event (JVMTI_EVENT_GARBAGE_COLLECTION_FINISH);
- check_enabled_event (JVMTI_EVENT_OBJECT_FREE);
- check_enabled_event (JVMTI_EVENT_VM_OBJECT_ALLOC);
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetEventNotificationMode (jvmtiEnv *env, jvmtiEventMode mode,
- jvmtiEvent type, jthread event_thread, ...)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
- if (event_thread != NULL)
- {
- THREAD_CHECK_VALID (event_thread);
- THREAD_CHECK_IS_ALIVE (event_thread);
- }
- bool enabled;
- switch (mode)
- {
- case JVMTI_DISABLE:
- enabled = false;
- break;
- case JVMTI_ENABLE:
- enabled = true;
- break;
- default:
- return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- }
- switch (type)
- {
- case JVMTI_EVENT_VM_INIT:
- case JVMTI_EVENT_VM_DEATH:
- case JVMTI_EVENT_THREAD_START:
- case JVMTI_EVENT_VM_START:
- case JVMTI_EVENT_COMPILED_METHOD_LOAD:
- case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
- case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
- case JVMTI_EVENT_DATA_DUMP_REQUEST:
- ILLEGAL_ARGUMENT (event_thread != NULL);
- break;
- case JVMTI_EVENT_THREAD_END:
- case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
- case JVMTI_EVENT_CLASS_LOAD:
- case JVMTI_EVENT_CLASS_PREPARE:
- case JVMTI_EVENT_EXCEPTION:
- case JVMTI_EVENT_EXCEPTION_CATCH:
- case JVMTI_EVENT_SINGLE_STEP:
- case JVMTI_EVENT_FRAME_POP:
- case JVMTI_EVENT_BREAKPOINT:
- case JVMTI_EVENT_FIELD_ACCESS:
- case JVMTI_EVENT_FIELD_MODIFICATION:
- case JVMTI_EVENT_METHOD_ENTRY:
- case JVMTI_EVENT_METHOD_EXIT:
- case JVMTI_EVENT_NATIVE_METHOD_BIND:
- case JVMTI_EVENT_MONITOR_WAIT:
- case JVMTI_EVENT_MONITOR_WAITED:
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
- case JVMTI_EVENT_GARBAGE_COLLECTION_START:
- case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
- case JVMTI_EVENT_OBJECT_FREE:
- case JVMTI_EVENT_VM_OBJECT_ALLOC:
- break;
- default:
- return JVMTI_ERROR_INVALID_EVENT_TYPE;
- }
- env->thread[EVENT_INDEX(type)] = event_thread;
- env->enabled[EVENT_INDEX(type)] = enabled;
- check_enabled_event (type);
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_SetEventCallbacks (jvmtiEnv *env,
- const jvmtiEventCallbacks *callbacks,
- jint size_of_callbacks)
- {
- REQUIRE_PHASE (env, JVMTI_PHASE_ONLOAD | JVMTI_PHASE_LIVE);
- ILLEGAL_ARGUMENT (size_of_callbacks < 0);
- // Copy the list of callbacks into the environment
- memcpy (&env->callbacks, callbacks, sizeof (jvmtiEventCallbacks));
- /* Check which events are now enabeld (JVMTI makes no requirements
- about the order in which SetEventCallbacks and SetEventNotifications
- are called. So we must check all events here. */
- check_enabled_events ();
- return JVMTI_ERROR_NONE;
- }
- static jvmtiError JNICALL
- _Jv_JVMTI_GetErrorName (MAYBE_UNUSED jvmtiEnv *env, jvmtiError error,
- char **name_ptr)
- {
- NULL_CHECK (name_ptr);
- const char *name;
- switch (error)
- {
- case JVMTI_ERROR_NONE:
- name = "none";
- break;
- case JVMTI_ERROR_NULL_POINTER:
- name = "null pointer";
- break;
- case JVMTI_ERROR_OUT_OF_MEMORY:
- name = "out of memory";
- break;
- case JVMTI_ERROR_ACCESS_DENIED:
- name = "access denied";
- break;
- case JVMTI_ERROR_WRONG_PHASE:
- name = "wrong phase";
- break;
- case JVMTI_ERROR_INTERNAL:
- name = "internal error";
- break;
- case JVMTI_ERROR_UNATTACHED_THREAD:
- name = "unattached thread";
- break;
- case JVMTI_ERROR_INVALID_ENVIRONMENT:
- name = "invalid environment";
- break;
- case JVMTI_ERROR_INVALID_PRIORITY:
- name = "invalid priority";
- break;
- case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
- name = "thread not suspended";
- break;
- case JVMTI_ERROR_THREAD_SUSPENDED:
- name = "thread suspended";
- break;
- case JVMTI_ERROR_THREAD_NOT_ALIVE:
- name = "thread not alive";
- break;
- case JVMTI_ERROR_CLASS_NOT_PREPARED:
- name = "class not prepared";
- break;
- case JVMTI_ERROR_NO_MORE_FRAMES:
- name = "no more frames";
- break;
- case JVMTI_ERROR_OPAQUE_FRAME:
- name = "opaque frame";
- break;
- case JVMTI_ERROR_DUPLICATE:
- name = "duplicate";
- break;
- case JVMTI_ERROR_NOT_FOUND:
- name = "not found";
- break;
- case JVMTI_ERROR_NOT_MONITOR_OWNER:
- name = "not monitor owner";
- break;
- case JVMTI_ERROR_INTERRUPT:
- name = "interrupted";
- break;
- case JVMTI_ERROR_UNMODIFIABLE_CLASS:
- name = "unmodifiable class";
- break;
- case JVMTI_ERROR_NOT_AVAILABLE:
- name = "not available";
- break;
- case JVMTI_ERROR_ABSENT_INFORMATION:
- name = "absent information";
- break;
- case JVMTI_ERROR_INVALID_EVENT_TYPE:
- name = "invalid event type";
- break;
- case JVMTI_ERROR_NATIVE_METHOD:
- name = "native method";
- break;
- case JVMTI_ERROR_INVALID_THREAD:
- name = "invalid thread";
- break;
- case JVMTI_ERROR_INVALID_THREAD_GROUP:
- name = "invalid thread group";
- break;
- case JVMTI_ERROR_INVALID_OBJECT:
- name = "invalid object";
- break;
- case JVMTI_ERROR_INVALID_CLASS:
- name = "invalid class";
- break;
- case JVMTI_ERROR_INVALID_METHODID:
- name = "invalid method ID";
- break;
- case JVMTI_ERROR_INVALID_LOCATION:
- name = "invalid location";
- break;
- case JVMTI_ERROR_INVALID_FIELDID:
- name = "invalid field ID";
- break;
- case JVMTI_ERROR_TYPE_MISMATCH:
- name = "type mismatch";
- break;
- case JVMTI_ERROR_INVALID_SLOT:
- name = "invalid slot";
- break;
- case JVMTI_ERROR_INVALID_MONITOR:
- name = "invalid monitor";
- break;
- case JVMTI_ERROR_INVALID_CLASS_FORMAT:
- name = "invalid class format";
- break;
- case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
- name = "circular class definition";
- break;
- case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
- name = "unsupported redefinition: method added";
- break;
- case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
- name = "unsupported redefinition: schema changed";
- break;
- case JVMTI_ERROR_INVALID_TYPESTATE:
- name = "invalid type state";
- break;
- case JVMTI_ERROR_FAILS_VERIFICATION:
- name = "fails verification";
- break;
- case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
- name = "unsupported redefinition: hierarchy changed";
- break;
- case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
- name = "unsupported redefinition: method deleted";
- break;
- case JVMTI_ERROR_UNSUPPORTED_VERSION:
- name = "unsupported version";
- break;
- case JVMTI_ERROR_NAMES_DONT_MATCH:
- name = "names do not match";
- break;
- case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
- name = "unsupported redefinition: class modifiers changed";
- break;
- case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
- name = "unsupported redefinition: method modifiers changed";
- break;
- case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
- name = "must possess capability";
- break;
- case JVMTI_ERROR_ILLEGAL_ARGUMENT:
- name = "illegal argument";
- break;
- default:
- return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- }
- *name_ptr = (char *) _Jv_MallocUnchecked (strlen (name) + 1);
- if (*name_ptr == NULL)
- return JVMTI_ERROR_OUT_OF_MEMORY;
- strcpy (*name_ptr, name);
- return JVMTI_ERROR_NONE;
- }
- #define RESERVED NULL
- #define UNIMPLEMENTED NULL
- struct _Jv_jvmtiEnv _Jv_JVMTI_Interface =
- {
- RESERVED, // reserved1
- _Jv_JVMTI_SetEventNotificationMode, // SetEventNotificationMode
- RESERVED, // reserved3
- _Jv_JVMTI_GetAllThreads, // GetAllThreads
- _Jv_JVMTI_SuspendThread, // SuspendThread
- _Jv_JVMTI_ResumeThread, // ResumeThread
- UNIMPLEMENTED, // StopThread
- _Jv_JVMTI_InterruptThread, // InterruptThread
- UNIMPLEMENTED, // GetThreadInfo
- UNIMPLEMENTED, // GetOwnedMonitorInfo
- UNIMPLEMENTED, // GetCurrentContendedMonitor
- UNIMPLEMENTED, // RunAgentThread
- UNIMPLEMENTED, // GetTopThreadGroups
- UNIMPLEMENTED, // GetThreadGroupInfo
- UNIMPLEMENTED, // GetThreadGroupChildren
- _Jv_JVMTI_GetFrameCount, // GetFrameCount
- _Jv_JVMTI_GetThreadState, // GetThreadState
- RESERVED, // reserved18
- UNIMPLEMENTED, // GetFrameLocation
- UNIMPLEMENTED, // NotifyPopFrame
- _Jv_JVMTI_GetLocalObject, // GetLocalObject
- _Jv_JVMTI_GetLocalInt, // GetLocalInt
- _Jv_JVMTI_GetLocalLong, // GetLocalLong
- _Jv_JVMTI_GetLocalFloat, // GetLocalFloat
- _Jv_JVMTI_GetLocalDouble, // GetLocalDouble
- _Jv_JVMTI_SetLocalObject, // SetLocalObject
- _Jv_JVMTI_SetLocalInt, // SetLocalInt
- _Jv_JVMTI_SetLocalLong, // SetLocalLong
- _Jv_JVMTI_SetLocalFloat, // SetLocalFloat
- _Jv_JVMTI_SetLocalDouble, // SetLocalDouble
- _Jv_JVMTI_CreateRawMonitor, // CreateRawMonitor
- _Jv_JVMTI_DestroyRawMonitor, // DestroyRawMonitor
- _Jv_JVMTI_RawMonitorEnter, // RawMonitorEnter
- _Jv_JVMTI_RawMonitorExit, // RawMonitorExit
- _Jv_JVMTI_RawMonitorWait, // RawMonitorWait
- _Jv_JVMTI_RawMonitorNotify, // RawMonitorNotify
- _Jv_JVMTI_RawMonitorNotifyAll, // RawMonitorNotifyAll
- _Jv_JVMTI_SetBreakpoint, // SetBreakpoint
- _Jv_JVMTI_ClearBreakpoint, // ClearBreakpoint
- RESERVED, // reserved40
- UNIMPLEMENTED, // SetFieldAccessWatch
- UNIMPLEMENTED, // ClearFieldAccessWatch
- UNIMPLEMENTED, // SetFieldModificationWatch
- UNIMPLEMENTED, // ClearFieldModificationWatch
- RESERVED, // reserved45
- _Jv_JVMTI_Allocate, // Allocate
- _Jv_JVMTI_Deallocate, // Deallocate
- UNIMPLEMENTED, // GetClassSignature
- _Jv_JVMTI_GetClassStatus, // GetClassStatus
- UNIMPLEMENTED, // GetSourceFileName
- _Jv_JVMTI_GetClassModifiers, // GetClassModifiers
- _Jv_JVMTI_GetClassMethods, // GetClassMethods
- UNIMPLEMENTED, // GetClassFields
- UNIMPLEMENTED, // GetImplementedInterfaces
- _Jv_JVMTI_IsInterface, // IsInterface
- _Jv_JVMTI_IsArrayClass, // IsArrayClass
- _Jv_JVMTI_GetClassLoader, // GetClassLoader
- _Jv_JVMTI_GetObjectHashCode, // GetObjectHashCode
- UNIMPLEMENTED, // GetObjectMonitorUsage
- UNIMPLEMENTED, // GetFieldName
- UNIMPLEMENTED, // GetFieldDeclaringClass
- _Jv_JVMTI_GetFieldModifiers, // GetFieldModifiers
- _Jv_JVMTI_IsFieldSynthetic, // IsFieldSynthetic
- _Jv_JVMTI_GetMethodName, // GetMethodName
- _Jv_JVMTI_GetMethodDeclaringClass, // GetMethodDeclaringClass
- _Jv_JVMTI_GetMethodModifiers, // GetMethodModifers
- RESERVED, // reserved67
- _Jv_JVMTI_GetMaxLocals, // GetMaxLocals
- _Jv_JVMTI_GetArgumentsSize, // GetArgumentsSize
- _Jv_JVMTI_GetLineNumberTable, // GetLineNumberTable
- UNIMPLEMENTED, // GetMethodLocation
- _Jv_JVMTI_GetLocalVariableTable, // GetLocalVariableTable
- RESERVED, // reserved73
- RESERVED, // reserved74
- UNIMPLEMENTED, // GetBytecodes
- _Jv_JVMTI_IsMethodNative, // IsMethodNative
- _Jv_JVMTI_IsMethodSynthetic, // IsMethodSynthetic
- UNIMPLEMENTED, // GetLoadedClasses
- _Jv_JVMTI_GetClassLoaderClasses, // GetClassLoaderClasses
- UNIMPLEMENTED, // PopFrame
- RESERVED, // reserved81
- RESERVED, // reserved82
- RESERVED, // reserved83
- RESERVED, // reserved84
- RESERVED, // reserved85
- RESERVED, // reserved86
- UNIMPLEMENTED, // RedefineClasses
- UNIMPLEMENTED, // GetVersionNumber
- UNIMPLEMENTED, // GetCapabilities
- UNIMPLEMENTED, // GetSourceDebugExtension
- UNIMPLEMENTED, // IsMethodObsolete
- UNIMPLEMENTED, // SuspendThreadList
- UNIMPLEMENTED, // ResumeThreadList
- RESERVED, // reserved94
- RESERVED, // reserved95
- RESERVED, // reserved96
- RESERVED, // reserved97
- RESERVED, // reserved98
- RESERVED, // reserved99
- UNIMPLEMENTED, // GetAllStackTraces
- UNIMPLEMENTED, // GetThreadListStackTraces
- UNIMPLEMENTED, // GetThreadLocalStorage
- UNIMPLEMENTED, // SetThreadLocalStorage
- _Jv_JVMTI_GetStackTrace, // GetStackTrace
- RESERVED, // reserved105
- UNIMPLEMENTED, // GetTag
- UNIMPLEMENTED, // SetTag
- _Jv_JVMTI_ForceGarbageCollection, // ForceGarbageCollection
- UNIMPLEMENTED, // IterateOverObjectsReachable
- UNIMPLEMENTED, // IterateOverReachableObjects
- UNIMPLEMENTED, // IterateOverHeap
- UNIMPLEMENTED, // IterateOverInstanceOfClass
- RESERVED, // reserved113
- UNIMPLEMENTED, // GetObjectsWithTags
- RESERVED, // reserved115
- RESERVED, // reserved116
- RESERVED, // reserved117
- RESERVED, // reserved118
- RESERVED, // reserved119
- _Jv_JVMTI_SetJNIFunctionTable, // SetJNIFunctionTable
- _Jv_JVMTI_GetJNIFunctionTable, // GetJNIFunctionTable
- _Jv_JVMTI_SetEventCallbacks, // SetEventCallbacks
- UNIMPLEMENTED, // GenerateEvents
- UNIMPLEMENTED, // GetExtensionFunctions
- UNIMPLEMENTED, // GetExtensionEvents
- UNIMPLEMENTED, // SetExtensionEventCallback
- _Jv_JVMTI_DisposeEnvironment, // DisposeEnvironment
- _Jv_JVMTI_GetErrorName, // GetErrorName
- UNIMPLEMENTED, // GetJLocationFormat
- UNIMPLEMENTED, // GetSystemProperties
- _Jv_JVMTI_GetSystemProperty, // GetSystemProperty
- _Jv_JVMTI_SetSystemProperty, // SetSystemProperty
- UNIMPLEMENTED, // GetPhase
- UNIMPLEMENTED, // GetCurrentThreadCpuTimerInfo
- UNIMPLEMENTED, // GetCurrentThreadCpuTime
- UNIMPLEMENTED, // GetThreadCpuTimerInfo
- UNIMPLEMENTED, // GetThreadCpuTime
- UNIMPLEMENTED, // GetTimerInfo
- _Jv_JVMTI_GetTime, // GetTime
- UNIMPLEMENTED, // GetPotentialCapabilities
- RESERVED, // reserved141
- UNIMPLEMENTED, // AddCapabilities
- UNIMPLEMENTED, // RelinquishCapabilities
- _Jv_JVMTI_GetAvailableProcessors, // GetAvailableProcessors
- RESERVED, // reserved145
- RESERVED, // reserved146
- UNIMPLEMENTED, // GetEnvironmentLocalStorage
- UNIMPLEMENTED, // SetEnvironmentLocalStorage
- _Jv_JVMTI_AddToBootstrapClassLoaderSearch, // AddToBootstrapClassLoaderSearch
- _Jv_JVMTI_SetVerboseFlag, // SetVerboseFlag
- RESERVED, // reserved151
- RESERVED, // reserved152
- RESERVED, // reserved153
- _Jv_JVMTI_GetObjectSize // GetObjectSize
- };
- _Jv_JVMTIEnv *
- _Jv_GetJVMTIEnv (void)
- {
- _Jv_JVMTIEnv *env
- = (_Jv_JVMTIEnv *) _Jv_MallocUnchecked (sizeof (_Jv_JVMTIEnv));
- memset (env, 0, sizeof (_Jv_JVMTIEnv));
- env->p = &_Jv_JVMTI_Interface;
- struct jvmti_env_list *element
- = (struct jvmti_env_list *) _Jv_MallocUnchecked (sizeof (struct jvmti_env_list));
- element->env = env;
- element->next = NULL;
- _envListLock->writeLock ()->lock ();
- if (_jvmtiEnvironments == NULL)
- _jvmtiEnvironments = element;
- else
- {
- struct jvmti_env_list *e;
- for (e = _jvmtiEnvironments; e->next != NULL; e = e->next)
- ;
- e->next = element;
- }
- _envListLock->writeLock ()->unlock ();
- /* Mark JVMTI active. This is used to force the interpreter
- to use either debugging or non-debugging code. Once JVMTI
- has been enabled, the non-debug interpreter cannot be used. */
- JVMTI::enabled = true;
- return env;
- }
- void
- _Jv_JVMTI_Init ()
- {
- _jvmtiEnvironments = NULL;
- _envListLock
- = new java::util::concurrent::locks::ReentrantReadWriteLock ();
- // No environments, so this should set all JVMTI:: members to false
- check_enabled_events ();
- }
- static void
- post_event (jvmtiEnv *env, jvmtiEvent type, jthread event_thread, va_list args)
- {
- #define ARG(Type,Name) Type Name = (Type) va_arg (args, Type)
- #define GET_BOOLEAN_ARG(Name) \
- ARG (int, b); \
- jboolean Name = (b == 0) ? false : true
- #define GET_CHAR_ARG(Name) \
- ARG (int, c); \
- char Name = static_cast<char> (c)
- switch (type)
- {
- case JVMTI_EVENT_VM_INIT:
- if (env->callbacks.VMInit != NULL)
- {
- ARG (JNIEnv *, jni_env);
- env->callbacks.VMInit (env, jni_env, event_thread);
- }
- break;
- case JVMTI_EVENT_VM_DEATH:
- if (env->callbacks.VMDeath != NULL)
- {
- ARG (JNIEnv *, jni_env);
- env->callbacks.VMDeath (env, jni_env);
- }
- break;
- case JVMTI_EVENT_THREAD_START:
- if (env->callbacks.ThreadStart != NULL)
- {
- ARG (JNIEnv *, jni_env);
- env->callbacks.ThreadStart (env, jni_env, event_thread);
- }
- break;
- case JVMTI_EVENT_THREAD_END:
- if (env->callbacks.ThreadEnd != NULL)
- {
- ARG (JNIEnv *, jni_env);
- env->callbacks.ThreadEnd (env, jni_env, event_thread);
- }
- break;
- case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
- if (env->callbacks.ClassFileLoadHook != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jclass, class_being_redefined);
- ARG (jobject, loader);
- ARG (const char *, name);
- ARG (jobject, protection_domain);
- ARG (jint, class_data_len);
- ARG (const unsigned char *, class_data);
- ARG (jint *, new_class_data_len);
- ARG (unsigned char **, new_class_data);
- env->callbacks.ClassFileLoadHook (env, jni_env,
- class_being_redefined, loader,
- name, protection_domain,
- class_data_len, class_data,
- new_class_data_len,
- new_class_data);
- }
- break;
- case JVMTI_EVENT_CLASS_LOAD:
- if (env->callbacks.ClassLoad != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jclass, klass);
- env->callbacks.ClassLoad (env, jni_env, event_thread, klass);
- }
- break;
- case JVMTI_EVENT_CLASS_PREPARE:
- if (env->callbacks.ClassPrepare != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jclass, klass);
- env->callbacks.ClassPrepare (env, jni_env, event_thread, klass);
- }
- break;
- case JVMTI_EVENT_VM_START:
- if (env->callbacks.VMStart != NULL)
- {
- ARG (JNIEnv *, jni_env);
- env->callbacks.VMStart (env, jni_env);
- }
- break;
- case JVMTI_EVENT_EXCEPTION:
- if (env->callbacks.Exception != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- ARG (jlocation, location);
- ARG (jobject, exception);
- ARG (jmethodID, catch_method);
- ARG (jlocation, catch_location);
- env->callbacks.Exception (env, jni_env, event_thread, method,
- location, exception, catch_method,
- catch_location);
- }
- break;
- case JVMTI_EVENT_EXCEPTION_CATCH:
- if (env->callbacks.ExceptionCatch != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- ARG (jlocation, location);
- ARG (jobject, exception);
- env->callbacks.ExceptionCatch (env, jni_env, event_thread, method,
- location, exception);
- }
- break;
- case JVMTI_EVENT_SINGLE_STEP:
- if (env->callbacks.SingleStep != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- ARG (jlocation, location);
- env->callbacks.SingleStep (env, jni_env, event_thread, method,
- location);
- }
- break;
- case JVMTI_EVENT_FRAME_POP:
- if (env->callbacks.FramePop != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- GET_BOOLEAN_ARG (was_popped_by_exception);
- env->callbacks.FramePop (env, jni_env, event_thread, method,
- was_popped_by_exception);
- }
- break;
- case JVMTI_EVENT_BREAKPOINT:
- if (env->callbacks.Breakpoint != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- ARG (jlocation, location);
- env->callbacks.Breakpoint (env, jni_env, event_thread, method,
- location);
- }
- break;
- case JVMTI_EVENT_FIELD_ACCESS:
- if (env->callbacks.FieldAccess != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- ARG (jlocation, location);
- ARG (jclass, field_class);
- ARG (jobject, object);
- ARG (jfieldID, field);
- env->callbacks.FieldAccess (env, jni_env, event_thread, method,
- location, field_class, object, field);
- }
- break;
- case JVMTI_EVENT_FIELD_MODIFICATION:
- if (env->callbacks.FieldModification != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- ARG (jlocation, location);
- ARG (jclass, field_class);
- ARG (jobject, object);
- ARG (jfieldID, field);
- GET_CHAR_ARG (signature_type);
- ARG (jvalue, new_value);
- env->callbacks.FieldModification (env, jni_env, event_thread, method,
- location, field_class, object,
- field, signature_type, new_value);
- }
- break;
- case JVMTI_EVENT_METHOD_ENTRY:
- if (env->callbacks.MethodEntry != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- env->callbacks.MethodEntry (env, jni_env, event_thread, method);
- }
- break;
- case JVMTI_EVENT_METHOD_EXIT:
- if (env->callbacks.MethodExit != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- GET_BOOLEAN_ARG (was_popped_by_exception);
- ARG (jvalue, return_value);
- env->callbacks.MethodExit (env, jni_env, event_thread, method,
- was_popped_by_exception, return_value);
- }
- break;
- case JVMTI_EVENT_NATIVE_METHOD_BIND:
- if (env->callbacks.NativeMethodBind != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jmethodID, method);
- ARG (void *, address);
- ARG (void **, new_address_ptr);
- env->callbacks.NativeMethodBind (env, jni_env, event_thread, method,
- address, new_address_ptr);
- }
- break;
- case JVMTI_EVENT_COMPILED_METHOD_LOAD:
- if (env->callbacks.CompiledMethodLoad != NULL)
- {
- ARG (jmethodID, method);
- ARG (jint, code_size);
- ARG (const void *, code_addr);
- ARG (jint, map_length);
- ARG (const jvmtiAddrLocationMap *, map);
- ARG (const void *, compile_info);
- env->callbacks.CompiledMethodLoad (env, method, code_size, code_addr,
- map_length, map, compile_info);
- }
- break;
- case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
- if (env->callbacks.CompiledMethodUnload != NULL)
- {
- ARG (jmethodID, method);
- ARG (const void *, code_addr);
- env->callbacks.CompiledMethodUnload (env, method, code_addr);
- }
- break;
- case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
- if (env->callbacks.DynamicCodeGenerated != NULL)
- {
- ARG (const char *, name);
- ARG (const void *, address);
- ARG (jint, length);
- env->callbacks.DynamicCodeGenerated (env, name, address, length);
- }
- break;
- case JVMTI_EVENT_DATA_DUMP_REQUEST:
- if (env->callbacks.DataDumpRequest != NULL)
- {
- env->callbacks.DataDumpRequest (env);
- }
- break;
- case JVMTI_EVENT_MONITOR_WAIT:
- if (env->callbacks.MonitorWait != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jobject, object);
- ARG (jlong, timeout);
- env->callbacks.MonitorWait (env, jni_env, event_thread, object,
- timeout);
- }
- break;
- case JVMTI_EVENT_MONITOR_WAITED:
- if (env->callbacks.MonitorWaited != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jobject, object);
- GET_BOOLEAN_ARG (timed_out);
- env->callbacks.MonitorWaited (env, jni_env, event_thread, object,
- timed_out);
- }
- break;
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
- if (env->callbacks.MonitorContendedEnter != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jobject, object);
- env->callbacks.MonitorContendedEnter (env, jni_env, event_thread,
- object);
- }
- break;
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
- if (env->callbacks.MonitorContendedEntered != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jobject, object);
- env->callbacks.MonitorContendedEntered (env, jni_env, event_thread,
- object);
- }
- break;
- case JVMTI_EVENT_GARBAGE_COLLECTION_START:
- if (env->callbacks.GarbageCollectionStart != NULL)
- {
- env->callbacks.GarbageCollectionStart (env);
- }
- break;
- case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
- if (env->callbacks.GarbageCollectionFinish != NULL)
- {
- env->callbacks.GarbageCollectionFinish (env);
- }
- break;
- case JVMTI_EVENT_OBJECT_FREE:
- if (env->callbacks.ObjectFree != NULL)
- {
- ARG (jlong, tag);
- env->callbacks.ObjectFree (env, tag);
- }
- break;
- case JVMTI_EVENT_VM_OBJECT_ALLOC:
- if (env->callbacks.VMObjectAlloc != NULL)
- {
- ARG (JNIEnv *, jni_env);
- ARG (jobject, object);
- ARG (jclass, object_class);
- ARG (jlong, size);
- env->callbacks.VMObjectAlloc (env, jni_env, event_thread,
- object, object_class, size);
- }
- break;
- default:
- fprintf (stderr, "libgcj: post of unknown JVMTI event (%d)\n",
- (int) type);
- break;
- }
- va_end (args);
- #undef ARG
- #undef GET_BOOLEAN_ARG
- #undef GET_CHAR_ARG
- }
- /* Post an event to requesting JVMTI environments
- *
- * This function should not be called without consulting the
- * JVMTI_REQUESTED_EVENT macro first (for speed). It does no real
- * harm (other than kill speed), since this function will still
- * only send the event if it was properly requested by an environment.
- */
- void
- _Jv_JVMTI_PostEvent (jvmtiEvent type, jthread event_thread, ...)
- {
- va_list args;
- va_start (args, event_thread);
- _envListLock->readLock ()->lock ();
- struct jvmti_env_list *e;
- FOREACH_ENVIRONMENT (e)
- {
- /* Events are only posted if the event was explicitly enabled,
- it has a registered event handler, and the event thread
- matches (either globally or restricted to a specific thread).
- Here we check all but the event handler, which will be handled
- by post_event. */
- if (e->env->enabled[EVENT_INDEX(type)]
- && (e->env->thread[EVENT_INDEX(type)] == NULL
- || e->env->thread[EVENT_INDEX(type)] == event_thread))
- {
- post_event (e->env, type, event_thread, args);
- }
- }
- _envListLock->readLock ()->unlock ();
- va_end (args);
- }
|