18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file jvmpi_oprofile.cpp
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * JVMPI agent implementation to report jitted JVM code to OProfile
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copyright 2007 OProfile authors
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This library is free software; you can redistribute it and/or
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * modify it under the terms of the GNU Lesser General Public
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * License as published by the Free Software Foundation; either
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * version 2.1 of the License, or (at your option) any later version.
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * This library is distributed in the hope that it will be useful,
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * but WITHOUT ANY WARRANTY; without even the implied warranty of
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Lesser General Public License for more details.
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * You should have received a copy of the GNU Lesser General Public
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * License along with this library; if not, write to the Free Software
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @author Maynard Johnson
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Copyright IBM Corporation 2007
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <iostream>
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <map>
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <string>
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cstring>
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdexcept>
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <cerrno>
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddextern "C" {
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <stdint.h>
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <jvmpi.h>
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <opagent.h>
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddusing namespace std;
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic bool debug = false;
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic op_agent_t agent_hdl;
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddclass class_details {
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddpublic:
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string name;
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	map<jmethodID, string> method_names;
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	map<jmethodID, string> method_signatures;
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd};
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic pthread_mutex_t class_map_mutex = PTHREAD_MUTEX_INITIALIZER;
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddstatic map <jobjectID, class_details> loaded_classes;
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid class_load(JVMPI_Event * event)
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	class_details cls;
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cls.name = event->u.class_load.class_name;
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	JVMPI_Method * passed_methods = event->u.class_load.methods;
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	for (int i = 0; i < event->u.class_load.num_methods;
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	     i++, passed_methods++) {
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cls.method_names[passed_methods->method_id] =
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			passed_methods->method_name;
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cls.method_signatures[passed_methods->method_id] =
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			passed_methods->method_signature;
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	pthread_mutex_lock(&class_map_mutex);
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	loaded_classes[event->u.class_load.class_id] = cls;
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	pthread_mutex_unlock(&class_map_mutex);
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid class_unload(JVMPI_Event * event)
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	pthread_mutex_lock(&class_map_mutex);
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	loaded_classes.erase(event->u.class_load.class_id);
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	pthread_mutex_unlock(&class_map_mutex);
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddJVMPI_Interface * jvmpi;
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid compiled_method_load(JVMPI_Event * event)
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jmethodID method = event->u.compiled_method_load.method_id;
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void * code_addr =  event->u.compiled_method_load.code_addr;
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jint code_size =  event->u.compiled_method_load.code_size;
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi->DisableGC();
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 /* Get the class of the method */
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jobjectID classID = jvmpi->GetMethodClass(method);
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi->EnableGC();
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	pthread_mutex_lock(&class_map_mutex);
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	map<jobjectID, class_details>::iterator iter =
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		loaded_classes.find(classID);
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (iter == loaded_classes.end()) {
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw runtime_error("Error: Cannot find class for compiled"
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				    " method\n");
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	class_details cls_info = ((class_details)iter->second);
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	map<jmethodID, string>::iterator method_it =
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cls_info.method_names.find(method);
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (method_it == cls_info.method_names.end()) {
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw runtime_error("Error: Cannot find method name for "
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				    "compiled method\n");
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	char const * method_name = ((string)method_it->second).c_str();
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	method_it = cls_info.method_signatures.find(method);
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (method_it == cls_info.method_signatures.end()) {
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw runtime_error("Error: Cannot find method signature "
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				    "for compiled method\n");
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	char const * method_signature = ((string)method_it->second).c_str();
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	string const class_signature = "L" + cls_info.name + ";";
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	pthread_mutex_unlock(&class_map_mutex);
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (debug) {
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cerr << "load: class=" << class_signature << ", method ="
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		     << method_name << ", method signature = "
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		     << method_signature
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		     << ", addr=" << code_addr << ", size="
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		     << code_size << endl;
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	// produce a symbol name out of class name and method name
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int cnt = strlen(method_name) + strlen(class_signature.c_str()) +
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		strlen(method_signature) + 2;
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	char buf[cnt];
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	strncpy(buf, class_signature.c_str(), cnt - 1);
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	strncat(buf, method_name, cnt - strlen(buf) - 1);
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	strncat(buf, method_signature, cnt - strlen(buf) - 1);
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (op_write_native_code(agent_hdl, buf, (uint64_t) code_addr,
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 code_addr, code_size))
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		perror("Error: op_write_native_code()");
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid compiled_method_unload(JVMPI_Event * event)
1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	void * code_addr =  event->u.compiled_method_load.code_addr;
1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (debug) {
1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cerr << "unload: addr="
1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			<< (unsigned long long) (uintptr_t) code_addr
1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			<< endl;
1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (op_unload_native_code(agent_hdl, (uint64_t)code_addr))
1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		perror("Error: op_unload_native_code()");
1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid jvm_shutdown(JVMPI_Event * event)
1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* Checking event here is not really necessary; added only to silence
1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * the 'unused parameter' compiler warning.
1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (event)
1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (op_close_agent(agent_hdl))
1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			perror("Error: op_close_agent()");
1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddvoid jvm_notify_event(JVMPI_Event * event)
1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	switch (event->event_type) {
1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	case JVMPI_EVENT_COMPILED_METHOD_LOAD:
1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		compiled_method_load(event);
1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		break;
1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	case JVMPI_EVENT_COMPILED_METHOD_UNLOAD:
1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		compiled_method_unload(event);
1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		break;
1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	case JVMPI_EVENT_JVM_SHUT_DOWN:
1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		jvm_shutdown(event);
1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		break;
1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	case JVMPI_EVENT_CLASS_LOAD:
1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		class_load(event);
1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		break;
1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	case JVMPI_EVENT_CLASS_UNLOAD:
1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		class_unload(event);
1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		break;
1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	default:
1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		break;
1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Doddextern "C" {
1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike DoddJNIEXPORT jint JNICALL JVM_OnLoad(JavaVM * jvm, char * options,
1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd                                  void * reserved)
1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd{
1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	int err;
1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (options && strstr(options, "version")) {
1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cerr << "jvmpi_oprofile: current libopagent version "
1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 << op_major_version() << "." << op_minor_version()
1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd				 << endl;
1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw runtime_error("Exiting");
1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (options && strstr(options, "debug=yes")) {
2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		debug = true;
2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		/* Add something braindead to silence the 'unused parameter'
2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		 * compiler warning.
2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		 */
2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		if (reserved)
2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd			debug = true;
2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (debug)
2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cerr << "jvmpi_oprofile: agent activated" << endl;
2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	agent_hdl = op_open_agent();
2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (!agent_hdl) {
2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		perror("Error: op_open_agent()");
2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw runtime_error("Exiting");
2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* The union below is used to avoid the 'dereferencing type-punned
2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * pointer will break strict-aliasing rules' compiler warning on the
2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 * GetEnv call.
2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	 */
2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	union {
2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		JVMPI_Interface * jvmpi_ifc;
2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		void * jvmpi_ifc_ptr;
2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	} jvmpi_GetEnv_arg;
2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	err = jvm->GetEnv(&jvmpi_GetEnv_arg.jvmpi_ifc_ptr, JVMPI_VERSION_1);
2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	if (err < 0) {
2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		cerr << "GetEnv failed with rc=" << err << endl;
2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd		throw runtime_error("Exiting");
2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	}
2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi = jvmpi_GetEnv_arg.jvmpi_ifc;
2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi->EnableEvent(JVMPI_EVENT_COMPILED_METHOD_LOAD, NULL);
2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi->EnableEvent(JVMPI_EVENT_COMPILED_METHOD_UNLOAD, NULL);
2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi->EnableEvent(JVMPI_EVENT_JVM_SHUT_DOWN, NULL);
2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi->EnableEvent(JVMPI_EVENT_CLASS_LOAD, NULL);
2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	jvmpi->NotifyEvent = jvm_notify_event;
2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	return JNI_OK;
2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd}
240