annotate src/share/demo/jvmti/waiters/Agent.cpp @ 6581:cea72c2bf071

7197491: update copyright year to match last edit in jdk8 jdk repository Reviewed-by: chegar, ksrini
author alanb
date Fri, 02 Nov 2012 15:50:11 +0000
parents d8fccd6db59b
children
rev   line source
duke@0 1 /*
alanb@6581 2 * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
duke@0 3 *
duke@0 4 * Redistribution and use in source and binary forms, with or without
duke@0 5 * modification, are permitted provided that the following conditions
duke@0 6 * are met:
duke@0 7 *
duke@0 8 * - Redistributions of source code must retain the above copyright
duke@0 9 * notice, this list of conditions and the following disclaimer.
duke@0 10 *
duke@0 11 * - Redistributions in binary form must reproduce the above copyright
duke@0 12 * notice, this list of conditions and the following disclaimer in the
duke@0 13 * documentation and/or other materials provided with the distribution.
duke@0 14 *
ohair@2362 15 * - Neither the name of Oracle nor the names of its
duke@0 16 * contributors may be used to endorse or promote products derived
duke@0 17 * from this software without specific prior written permission.
duke@0 18 *
duke@0 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
duke@0 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
duke@0 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
duke@0 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
duke@0 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
duke@0 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
duke@0 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
duke@0 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
duke@0 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
duke@0 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
duke@0 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
duke@0 30 */
duke@0 31
nloodin@4503 32 /*
nloodin@4503 33 * This source code is provided to illustrate the usage of a given feature
nloodin@4503 34 * or technique and has been deliberately simplified. Additional steps
nloodin@4503 35 * required for a production-quality application, such as security checks,
nloodin@4503 36 * input validation and proper error handling, might not be present in
nloodin@4503 37 * this sample code.
nloodin@4503 38 */
nloodin@4503 39
nloodin@4503 40
duke@0 41 #include <stdio.h>
duke@0 42 #include <stdlib.h>
duke@0 43 #include <string.h>
duke@0 44 #include <stddef.h>
duke@0 45
duke@0 46 #include "jni.h"
duke@0 47 #include "jvmti.h"
duke@0 48
duke@0 49 #include "agent_util.h"
duke@0 50
duke@0 51 #include "Monitor.hpp"
duke@0 52 #include "Thread.hpp"
duke@0 53 #include "Agent.hpp"
duke@0 54
duke@0 55 /* Implementation of the Agent class */
duke@0 56
duke@0 57 /* Given a jvmtiEnv* and jthread, find the Thread instance */
duke@0 58 Thread *
duke@0 59 Agent::get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
duke@0 60 {
duke@0 61 jvmtiError err;
duke@0 62 Thread *t;
duke@0 63
duke@0 64 /* This should always be in the Thread Local Storage */
duke@0 65 t = NULL;
duke@0 66 err = jvmti->GetThreadLocalStorage(thread, (void**)&t);
duke@0 67 check_jvmti_error(jvmti, err, "get thread local storage");
duke@0 68 if ( t == NULL ) {
duke@0 69 /* This jthread has never been seen before? */
duke@0 70 stdout_message("WARNING: Never before seen jthread?\n");
duke@0 71 t = new Thread(jvmti, env, thread);
duke@0 72 err = jvmti->SetThreadLocalStorage(thread, (const void*)t);
duke@0 73 check_jvmti_error(jvmti, err, "set thread local storage");
duke@0 74 }
duke@0 75 return t;
duke@0 76 }
duke@0 77
duke@0 78 /* Given a jvmtiEnv* and jobject, find the Monitor instance or create one */
duke@0 79 Monitor *
duke@0 80 Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object)
duke@0 81 {
duke@0 82 jvmtiError err;
duke@0 83 Monitor *m;
alanb@1657 84 jlong tag;
duke@0 85
alanb@1657 86 m = NULL;
alanb@1657 87 tag = (jlong)0;
alanb@1657 88 err = jvmti->GetTag(object, &tag);
alanb@1657 89 check_jvmti_error(jvmti, err, "get tag");
alanb@1657 90 /*LINTED*/
alanb@1657 91 m = (Monitor *)(void *)(ptrdiff_t)tag;
alanb@1657 92 if ( m == NULL ) {
alanb@1657 93 m = new Monitor(jvmti, env, object);
alanb@1657 94 /* Save monitor on list */
alanb@1657 95 if (monitor_count == monitor_list_size) {
alanb@1657 96 monitor_list_size += monitor_list_grow_size;
alanb@1657 97 monitor_list = (Monitor**)realloc((void*)monitor_list,
alanb@1657 98 (monitor_list_size)*(int)sizeof(Monitor*));
alanb@1657 99 }
alanb@1657 100 monitor_list[monitor_count] = m;
alanb@1657 101 m->set_slot(monitor_count);
alanb@1657 102 monitor_count++;
duke@0 103 /*LINTED*/
alanb@1657 104 tag = (jlong)(ptrdiff_t)(void *)m;
alanb@1657 105 err = jvmti->SetTag(object, tag);
alanb@1657 106 check_jvmti_error(jvmti, err, "set tag");
alanb@1657 107 }
duke@0 108 return m;
duke@0 109 }
duke@0 110
duke@0 111 /* VM initialization and VM death calls to Agent */
duke@0 112 Agent::Agent(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
duke@0 113 {
duke@0 114 jvmtiError err;
duke@0 115
duke@0 116 stdout_message("Agent created..\n");
duke@0 117 stdout_message("VMInit...\n");
duke@0 118 /* Start monitor list */
duke@0 119 monitor_count = 0;
alanb@1657 120 monitor_list_size = initial_monitor_list_size;
alanb@1657 121 monitor_list = (Monitor**)
alanb@1657 122 malloc(monitor_list_size*(int)sizeof(Monitor*));
duke@0 123 }
duke@0 124
duke@0 125 Agent::~Agent()
duke@0 126 {
duke@0 127 stdout_message("Agent reclaimed..\n");
duke@0 128 }
duke@0 129
duke@0 130 void Agent::vm_death(jvmtiEnv *jvmti, JNIEnv *env)
duke@0 131 {
duke@0 132 jvmtiError err;
duke@0 133
duke@0 134 /* Delete all Monitors we allocated */
duke@0 135 for ( int i = 0; i < (int)monitor_count; i++ ) {
duke@0 136 delete monitor_list[i];
duke@0 137 }
duke@0 138 free(monitor_list);
duke@0 139 /* Print death message */
duke@0 140 stdout_message("VMDeath...\n");
duke@0 141 }
duke@0 142
duke@0 143 /* Thread start event, setup a new thread */
duke@0 144 void Agent::thread_start(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
duke@0 145 {
duke@0 146 jvmtiError err;
duke@0 147 Thread *t;
duke@0 148
duke@0 149 /* Allocate a new Thread instance, put it in the Thread Local
duke@0 150 * Storage for easy access later.
duke@0 151 */
duke@0 152 t = new Thread(jvmti, env, thread);
duke@0 153 err = jvmti->SetThreadLocalStorage(thread, (const void*)t);
duke@0 154 check_jvmti_error(jvmti, err, "set thread local storage");
duke@0 155 }
duke@0 156
duke@0 157
duke@0 158 /* Thread end event, we need to reclaim the space */
duke@0 159 void Agent::thread_end(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
duke@0 160 {
duke@0 161 jvmtiError err;
duke@0 162 Thread *t;
duke@0 163
duke@0 164 /* Find the thread */
duke@0 165 t = get_thread(jvmti, env, thread);
duke@0 166
duke@0 167 /* Clear out the Thread Local Storage */
duke@0 168 err = jvmti->SetThreadLocalStorage(thread, (const void*)NULL);
duke@0 169 check_jvmti_error(jvmti, err, "set thread local storage");
duke@0 170
duke@0 171 /* Reclaim the C++ object space */
duke@0 172 delete t;
duke@0 173 }
duke@0 174
duke@0 175 /* Monitor contention begins for a thread. */
duke@0 176 void Agent::monitor_contended_enter(jvmtiEnv* jvmti, JNIEnv *env,
duke@0 177 jthread thread, jobject object)
duke@0 178 {
duke@0 179 get_monitor(jvmti, env, object)->contended();
duke@0 180 get_thread(jvmti, env, thread)->
duke@0 181 monitor_contended_enter(jvmti, env, thread, object);
duke@0 182 }
duke@0 183
duke@0 184 /* Monitor contention ends for a thread. */
duke@0 185 void Agent::monitor_contended_entered(jvmtiEnv* jvmti, JNIEnv *env,
duke@0 186 jthread thread, jobject object)
duke@0 187 {
duke@0 188 /* Do nothing for now */
duke@0 189 }
duke@0 190
duke@0 191 /* Monitor wait begins for a thread. */
duke@0 192 void Agent::monitor_wait(jvmtiEnv* jvmti, JNIEnv *env,
duke@0 193 jthread thread, jobject object, jlong timeout)
duke@0 194 {
duke@0 195 get_monitor(jvmti, env, object)->waited();
duke@0 196 get_thread(jvmti, env, thread)->
duke@0 197 monitor_wait(jvmti, env, thread, object, timeout);
duke@0 198 }
duke@0 199
duke@0 200 /* Monitor wait ends for a thread. */
duke@0 201 void Agent::monitor_waited(jvmtiEnv* jvmti, JNIEnv *env,
duke@0 202 jthread thread, jobject object, jboolean timed_out)
duke@0 203 {
duke@0 204 if ( timed_out ) {
duke@0 205 get_monitor(jvmti, env, object)->timeout();
duke@0 206 }
duke@0 207 get_thread(jvmti, env, thread)->
duke@0 208 monitor_waited(jvmti, env, thread, object, timed_out);
duke@0 209 }
duke@0 210
duke@0 211 /* A tagged object has been freed */
duke@0 212 void Agent::object_free(jvmtiEnv* jvmti, jlong tag)
duke@0 213 {
duke@0 214 /* We just cast the tag to a C++ pointer and delete it.
duke@0 215 * we know it can only be a Monitor *.
duke@0 216 */
alanb@1657 217 Monitor *m;
duke@0 218 /*LINTED*/
duke@0 219 m = (Monitor *)(ptrdiff_t)tag;
alanb@1657 220 if (monitor_count > 1) {
alanb@1657 221 /* Move the last element to this Monitor's slot */
alanb@1657 222 int slot = m->get_slot();
alanb@1657 223 Monitor *last = monitor_list[monitor_count-1];
alanb@1657 224 monitor_list[slot] = last;
alanb@1657 225 last->set_slot(slot);
alanb@1657 226 }
alanb@1657 227 monitor_count--;
duke@0 228 delete m;
duke@0 229 }