jdk/src/share/instrument/JPLISAgent.c
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 7978 120267233d5e
child 11359 9e53808b2128
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 7978
diff changeset
     2
 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1090
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1090
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1090
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1090
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1090
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * Copyright 2003 Wily Technology, Inc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
#include    <jni.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
#include    <jvmti.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
#include    <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
#include    <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
#include    "JPLISAgent.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
#include    "JPLISAssert.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
#include    "Utilities.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
#include    "Reentrancy.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
#include    "JavaExceptions.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
#include    "EncodingSupport.h"
1090
c5805b1672a6 6732421: Removed old javavm and Classic VM files from the jdk7 sources
ohair
parents: 715
diff changeset
    41
#include    "FileSystemSupport.h"    /* For MAXPATHLEN & uintptr_t */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
#include    "sun_instrument_InstrumentationImpl.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *  The JPLISAgent manages the initialization all of the Java programming language Agents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *  It also supports the native method bridge between the JPLIS and the JVMTI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *  It maintains a single JVMTI Env that all JPL agents share.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *  It parses command line requests and creates individual Java agents.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *  private prototypes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
/* Allocates an unformatted JPLIS agent data structure. Returns NULL if allocation fails. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
JPLISAgent *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
allocateJPLISAgent(jvmtiEnv *       jvmtiEnv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
/* Initializes an already-allocated JPLIS agent data structure. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
JPLISInitializationError
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
initializeJPLISAgent(   JPLISAgent *    agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
                        JavaVM *        vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
                        jvmtiEnv *      jvmtienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
/* De-allocates a JPLIS agent data structure. Only used in partial-failure cases at startup;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * in normal usage the JPLIS agent lives forever
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
deallocateJPLISAgent(   jvmtiEnv *      jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
                        JPLISAgent *    agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
/* Does one-time work to interrogate the JVM about capabilities and cache the answers. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
checkCapabilities(JPLISAgent * agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
/* Takes the elements of the command string (agent class name and options string) and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 * create java strings for them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * Returns true if a classname was found. Makes no promises beyond the textual; says nothing about whether
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * the class exists or can be loaded.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 * If return value is true, sets outputClassname to a non-NULL local JNI reference.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
 * If return value is true, sets outputOptionsString either to NULL or to a non-NULL local JNI reference.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
 * If return value is false, neither output parameter is set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
commandStringIntoJavaStrings(  JNIEnv *        jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
                               const char *    classname,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
                               const char *    optionsString,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
                               jstring *       outputClassname,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
                               jstring *       outputOptionsString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
/* Start one Java agent from the supplied parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
 * Most of the logic lives in a helper function that lives over in Java code--
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
 * we pass parameters out to Java and use our own Java helper to actually
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
 * load the agent and call the premain.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
 * Returns true if the Java agent class is loaded and the premain/agentmain method completes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
 * with no exceptions, false otherwise.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
invokeJavaAgentMainMethod( JNIEnv *    jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
                           jobject     instrumentationImpl,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
                           jmethodID   agentMainMethod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
                           jstring     className,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
                           jstring     optionsString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
/* Once we have loaded the Java agent and called the premain,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
 * we can release the copies we have been keeping of the command line
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
 * data (agent class name and option strings).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
deallocateCommandLineData(JPLISAgent * agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
 *  Common support for various class list fetchers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
typedef jvmtiError (*ClassListFetcher)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    (   jvmtiEnv *  jvmtiEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        jobject     classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        jint *      classCount,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        jclass **   classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
/* Fetcher that ignores the class loader parameter, and uses the JVMTI to get a list of all classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
 * Returns a jvmtiError according to the underlying JVMTI service.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
jvmtiError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
getAllLoadedClassesClassListFetcher(    jvmtiEnv *  jvmtiEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                                        jobject     classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
                                        jint *      classCount,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
                                        jclass **   classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
/* Fetcher that uses the class loader parameter, and uses the JVMTI to get a list of all classes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 * for which the supplied loader is the initiating loader.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
 * Returns a jvmtiError according to the underlying JVMTI service.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
jvmtiError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
getInitiatedClassesClassListFetcher(    jvmtiEnv *  jvmtiEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                                        jobject     classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                                        jint *      classCount,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                                        jclass **   classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
 * Common guts for two native methods, which are the same except for the policy for fetching
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
 * the list of classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
 * Either returns a local JNI reference to an array of references to java.lang.Class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 * Can throw, if it does will alter the JNIEnv with an outstanding exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
jobjectArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
commonGetClassList( JNIEnv *            jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
                    JPLISAgent *        agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
                    jobject             classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
                    ClassListFetcher    fetcher);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
 *  Misc. utilities.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
/* Checked exception mapper used by the redefine classes implementation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
 * Allows ClassNotFoundException or UnmodifiableClassException; maps others
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
 * to InternalError. Can return NULL in an error case.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
jthrowable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
redefineClassMapper(    JNIEnv *    jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                        jthrowable  throwableToMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
/* Turns a buffer of jclass * into a Java array whose elements are java.lang.Class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
 * Can throw, if it does will alter the JNIEnv with an outstanding exception.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
jobjectArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
getObjectArrayFromClasses(JNIEnv* jnienv, jclass* classes, jint classCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
JPLISEnvironment *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
getJPLISEnvironment(jvmtiEnv * jvmtienv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    JPLISEnvironment * environment  = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    jvmtiError         jvmtierror   = JVMTI_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    jvmtierror = (*jvmtienv)->GetEnvironmentLocalStorage(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                                            jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                                            (void**)&environment);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   181
    /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    if (jvmtierror == JVMTI_ERROR_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        jplis_assert(environment != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        jplis_assert(environment->mJVMTIEnv == jvmtienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        environment = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    return environment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
 *  OnLoad processing code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
 *  Creates a new JPLISAgent.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
 *  Returns error if the agent cannot be created and initialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
 *  The JPLISAgent* pointed to by agent_ptr is set to the new broker,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
 *  or NULL if an error has occurred.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
JPLISInitializationError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    JPLISInitializationError initerror       = JPLIS_INIT_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    jvmtiEnv *               jvmtienv        = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    jint                     jnierror        = JNI_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    *agent_ptr = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    jnierror = (*vm)->GetEnv(  vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                               (void **) &jvmtienv,
7978
120267233d5e 6436034: Instance filter doesn't filter event if it occurs in native method
kamg
parents: 5506
diff changeset
   212
                               JVMTI_VERSION_1_1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    if ( jnierror != JNI_OK ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        initerror = JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        JPLISAgent * agent = allocateJPLISAgent(jvmtienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        if ( agent == NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            initerror = initializeJPLISAgent(  agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                                               vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                                               jvmtienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            if ( initerror == JPLIS_INIT_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                *agent_ptr = agent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                deallocateJPLISAgent(jvmtienv, agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        /* don't leak envs */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        if ( initerror != JPLIS_INIT_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   233
            /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    return initerror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
 *  Allocates a JPLISAgent. Returns NULL if it cannot be allocated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
JPLISAgent *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
allocateJPLISAgent(jvmtiEnv * jvmtienv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
  return (JPLISAgent *) allocate( jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                                    sizeof(JPLISAgent));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
JPLISInitializationError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
initializeJPLISAgent(   JPLISAgent *    agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                        JavaVM *        vm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                        jvmtiEnv *      jvmtienv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
    jvmtiError      jvmtierror = JVMTI_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
    jvmtiPhase      phase;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
    agent->mJVM                                      = vm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
    agent->mNormalEnvironment.mJVMTIEnv              = jvmtienv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    agent->mNormalEnvironment.mAgent                 = agent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
    agent->mNormalEnvironment.mIsRetransformer       = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    agent->mRetransformEnvironment.mJVMTIEnv         = NULL;        /* NULL until needed */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    agent->mRetransformEnvironment.mAgent            = agent;
279
e0911cc0a5d1 6547358: 2/2 j.l.i.: manifest attribute 'Can-Retransform-Classes' is ignored by isRetransformClassesSupported()
dcubed
parents: 2
diff changeset
   263
    agent->mRetransformEnvironment.mIsRetransformer  = JNI_FALSE;   /* JNI_FALSE until mJVMTIEnv is set */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    agent->mAgentmainCaller                          = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    agent->mInstrumentationImpl                      = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    agent->mPremainCaller                            = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    agent->mTransform                                = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    agent->mRedefineAvailable                        = JNI_FALSE;   /* assume no for now */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    agent->mRedefineAdded                            = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    agent->mNativeMethodPrefixAvailable              = JNI_FALSE;   /* assume no for now */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    agent->mNativeMethodPrefixAdded                  = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    agent->mAgentClassName                           = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    agent->mOptionsString                            = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
    /* make sure we can recover either handle in either direction.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
     * the agent has a ref to the jvmti; make it mutual
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    jvmtierror = (*jvmtienv)->SetEnvironmentLocalStorage(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                                            jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                                            &(agent->mNormalEnvironment));
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   281
    /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
    /* check what capabilities are available */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
    checkCapabilities(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
    /* check phase - if live phase then we don't need the VMInit event */
281
3da74b83e387 6642405: 4/4 src/share/instrument/JPLISAgent.c line 286: "==" found where assignment "=" expected
dcubed
parents: 280
diff changeset
   288
    jvmtierror = (*jvmtienv)->GetPhase(jvmtienv, &phase);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   289
    /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    if (phase == JVMTI_PHASE_LIVE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        return JPLIS_INIT_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   295
    if (phase != JVMTI_PHASE_ONLOAD) {
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   296
        /* called too early or called too late; either way bail out */
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   297
        return JPLIS_INIT_ERROR_FAILURE;
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   298
    }
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   299
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    /* now turn on the VMInit event */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    if ( jvmtierror == JVMTI_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        jvmtiEventCallbacks callbacks;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        memset(&callbacks, 0, sizeof(callbacks));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        callbacks.VMInit = &eventHandlerVMInit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                                                     &callbacks,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                                                     sizeof(callbacks));
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   309
        check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    if ( jvmtierror == JVMTI_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        jvmtierror = (*jvmtienv)->SetEventNotificationMode(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                                                jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                                                JVMTI_ENABLE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                                                JVMTI_EVENT_VM_INIT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                                                NULL /* all threads */);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   319
        check_phase_ret_blob(jvmtierror, JPLIS_INIT_ERROR_FAILURE);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    return (jvmtierror == JVMTI_ERROR_NONE)? JPLIS_INIT_ERROR_NONE : JPLIS_INIT_ERROR_FAILURE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
deallocateJPLISAgent(jvmtiEnv * jvmtienv, JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    deallocate(jvmtienv, agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
JPLISInitializationError
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
recordCommandLineData(  JPLISAgent *    agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                        const char *    agentClassName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                        const char *    optionsString ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    JPLISInitializationError    initerror   = JPLIS_INIT_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    char *      ourCopyOfAgentClassName     = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    char *      ourCopyOfOptionsString      = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
    /* if no actual params, bail out now */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    if ((agentClassName == NULL) || (*agentClassName == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        initerror = JPLIS_INIT_ERROR_AGENT_CLASS_NOT_SPECIFIED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        ourCopyOfAgentClassName = allocate(jvmti(agent), strlen(agentClassName)+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        if (ourCopyOfAgentClassName == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
            initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            if (optionsString != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                ourCopyOfOptionsString = allocate(jvmti(agent), strlen(optionsString)+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                if (ourCopyOfOptionsString == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                    deallocate(jvmti(agent), ourCopyOfAgentClassName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                    initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    if (initerror == JPLIS_INIT_ERROR_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        strcpy(ourCopyOfAgentClassName, agentClassName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        if (optionsString != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            strcpy(ourCopyOfOptionsString, optionsString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        agent->mAgentClassName = ourCopyOfAgentClassName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        agent->mOptionsString = ourCopyOfOptionsString;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    return initerror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
 *  VMInit processing code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
 * If this call fails, the JVM launch will ultimately be aborted,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
 * so we don't have to be super-careful to clean up in partial failure
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
 * cases.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
processJavaStart(   JPLISAgent *    agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                    JNIEnv *        jnienv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    jboolean    result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
     *  OK, Java is up now. We can start everything that needs Java.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     *  First make our emergency fallback InternalError throwable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    result = initializeFallbackError(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    jplis_assert(result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     *  Now make the InstrumentationImpl instance.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    if ( result ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        result = createInstrumentationImpl(jnienv, agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        jplis_assert(result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     *  Then turn off the VMInit handler and turn on the ClassFileLoadHook.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     *  This way it is on before anyone registers a transformer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
    if ( result ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        result = setLivePhaseEventHandlers(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        jplis_assert(result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     *  Load the Java agent, and call the premain.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    if ( result ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        result = startJavaAgent(agent, jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                                agent->mAgentClassName, agent->mOptionsString,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                                agent->mPremainCaller);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
     * Finally surrender all of the tracking data that we don't need any more.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
     * If something is wrong, skip it, we will be aborting the JVM anyway.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    if ( result ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        deallocateCommandLineData(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
startJavaAgent( JPLISAgent *    agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                JNIEnv *        jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                const char *    classname,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                const char *    optionsString,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                jmethodID       agentMainMethod) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    jboolean    success = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    jstring classNameObject = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    jstring optionsStringObject = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    success = commandStringIntoJavaStrings(    jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                                               classname,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                                               optionsString,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                                               &classNameObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                                               &optionsStringObject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    if (success) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        success = invokeJavaAgentMainMethod(   jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                                               agent->mInstrumentationImpl,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                                               agentMainMethod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                                               classNameObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                                               optionsStringObject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
    return success;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
deallocateCommandLineData( JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    deallocate(jvmti(agent), (void*)agent->mAgentClassName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    deallocate(jvmti(agent), (void*)agent->mOptionsString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    /* zero things out so it is easier to see what is going on */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
    agent->mAgentClassName = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    agent->mOptionsString = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
 * Create the java.lang.instrument.Instrumentation instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
 * and access information for it (method IDs, etc)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
createInstrumentationImpl( JNIEnv *        jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                           JPLISAgent *    agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
    jclass      implClass               = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
    jboolean    errorOutstanding        = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
    jobject     resultImpl              = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
    jmethodID   premainCallerMethodID   = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    jmethodID   agentmainCallerMethodID = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
    jmethodID   transformMethodID       = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    jmethodID   constructorID           = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    jobject     localReference          = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    /* First find the class of our implementation */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
    implClass = (*jnienv)->FindClass(   jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                                        JPLIS_INSTRUMENTIMPL_CLASSNAME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
    errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
    errorOutstanding = errorOutstanding || (implClass == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
    jplis_assert_msg(!errorOutstanding, "find class on InstrumentationImpl failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        constructorID = (*jnienv)->GetMethodID( jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                                                implClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                                                JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODNAME,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                                                JPLIS_INSTRUMENTIMPL_CONSTRUCTOR_METHODSIGNATURE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        errorOutstanding = errorOutstanding || (constructorID == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        jplis_assert_msg(!errorOutstanding, "find constructor on InstrumentationImpl failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        jlong   peerReferenceAsScalar = (jlong)(intptr_t) agent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        localReference = (*jnienv)->NewObject(  jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                                                implClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                                                constructorID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                                                peerReferenceAsScalar,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                                                agent->mRedefineAdded,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                                                agent->mNativeMethodPrefixAdded);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        errorOutstanding = errorOutstanding || (localReference == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        jplis_assert_msg(!errorOutstanding, "call constructor on InstrumentationImpl failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        resultImpl = (*jnienv)->NewGlobalRef(jnienv, localReference);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
        jplis_assert_msg(!errorOutstanding, "copy local ref to global ref");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    /* Now look up the method ID for the pre-main caller (we will need this more than once) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
        premainCallerMethodID = (*jnienv)->GetMethodID( jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
                                                        implClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                                                        JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODNAME,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                                                        JPLIS_INSTRUMENTIMPL_PREMAININVOKER_METHODSIGNATURE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        errorOutstanding = errorOutstanding || (premainCallerMethodID == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
        jplis_assert_msg(!errorOutstanding, "can't find premain invoker methodID");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    /* Now look up the method ID for the agent-main caller */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
        agentmainCallerMethodID = (*jnienv)->GetMethodID( jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                                                          implClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                                                          JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODNAME,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                                                          JPLIS_INSTRUMENTIMPL_AGENTMAININVOKER_METHODSIGNATURE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        errorOutstanding = errorOutstanding || (agentmainCallerMethodID == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
        jplis_assert_msg(!errorOutstanding, "can't find agentmain invoker methodID");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
    /* Now look up the method ID for the transform method (we will need this constantly) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
        transformMethodID = (*jnienv)->GetMethodID( jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                                                    implClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                                                    JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODNAME,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                                                    JPLIS_INSTRUMENTIMPL_TRANSFORM_METHODSIGNATURE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
        errorOutstanding = errorOutstanding || (transformMethodID == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
        jplis_assert_msg(!errorOutstanding, "can't find transform methodID");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        agent->mInstrumentationImpl = resultImpl;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        agent->mPremainCaller       = premainCallerMethodID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
        agent->mAgentmainCaller     = agentmainCallerMethodID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
        agent->mTransform           = transformMethodID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
    return !errorOutstanding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
commandStringIntoJavaStrings(  JNIEnv *        jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                               const char *    classname,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                               const char *    optionsString,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                               jstring *       outputClassname,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                               jstring *       outputOptionsString) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
    jstring     classnameJavaString     = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
    jstring     optionsJavaString       = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
    jboolean    errorOutstanding        = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
    classnameJavaString = (*jnienv)->NewStringUTF(jnienv, classname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
    errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
    jplis_assert_msg(!errorOutstanding, "can't create class name java string");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
    if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        if ( optionsString != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            optionsJavaString = (*jnienv)->NewStringUTF(jnienv, optionsString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
            errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
            jplis_assert_msg(!errorOutstanding, "can't create options java string");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
        if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            *outputClassname        = classnameJavaString;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            *outputOptionsString    = optionsJavaString;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
    return !errorOutstanding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
invokeJavaAgentMainMethod( JNIEnv *    jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
                           jobject     instrumentationImpl,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
                           jmethodID   mainCallingMethod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                           jstring     className,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                           jstring     optionsString) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    jboolean errorOutstanding = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
    jplis_assert(mainCallingMethod != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
    if ( mainCallingMethod != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
        (*jnienv)->CallVoidMethod(  jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                                    instrumentationImpl,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                                    mainCallingMethod,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                                    className,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                                    optionsString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        errorOutstanding = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        if ( errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            logThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
        checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    return !errorOutstanding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
setLivePhaseEventHandlers(  JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    jvmtiEventCallbacks callbacks;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
    jvmtiEnv *          jvmtienv = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    /* first swap out the handlers (switch from the VMInit handler, which we do not need,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * to the ClassFileLoadHook handler, which is what the agents need from now on)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    memset(&callbacks, 0, sizeof(callbacks));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    callbacks.ClassFileLoadHook = &eventHandlerClassFileLoadHook;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
    jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                                                 &callbacks,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                                                 sizeof(callbacks));
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   635
    check_phase_ret_false(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    if ( jvmtierror == JVMTI_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
        /* turn off VMInit */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        jvmtierror = (*jvmtienv)->SetEventNotificationMode(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                                                    jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
                                                    JVMTI_DISABLE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                                                    JVMTI_EVENT_VM_INIT,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                                                    NULL /* all threads */);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   646
        check_phase_ret_false(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    if ( jvmtierror == JVMTI_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        /* turn on ClassFileLoadHook */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        jvmtierror = (*jvmtienv)->SetEventNotificationMode(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
                                                    jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                                                    JVMTI_ENABLE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
                                                    JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
                                                    NULL /* all threads */);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   657
        check_phase_ret_false(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    return (jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
 *  Check if the can_redefine_classes capability is available.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
checkCapabilities(JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    jvmtiEnv *          jvmtienv = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
    jvmtiCapabilities   potentialCapabilities;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
    memset(&potentialCapabilities, 0, sizeof(potentialCapabilities));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    jvmtierror = (*jvmtienv)->GetPotentialCapabilities(jvmtienv, &potentialCapabilities);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   676
    check_phase_ret(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    if ( jvmtierror == JVMTI_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        if ( potentialCapabilities.can_redefine_classes == 1 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
            agent->mRedefineAvailable = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        if ( potentialCapabilities.can_set_native_method_prefix == 1 ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            agent->mNativeMethodPrefixAvailable = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
 * Enable native method prefix in one JVM TI environment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
enableNativeMethodPrefixCapability(jvmtiEnv * jvmtienv) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
    jvmtiCapabilities   desiredCapabilities;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   698
        /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        desiredCapabilities.can_set_native_method_prefix = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   702
        check_phase_ret(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
 * Add the can_set_native_method_prefix capability
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
addNativeMethodPrefixCapability(JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
    if (agent->mNativeMethodPrefixAvailable && !agent->mNativeMethodPrefixAdded) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        jvmtiEnv * jvmtienv = agent->mNormalEnvironment.mJVMTIEnv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        enableNativeMethodPrefixCapability(jvmtienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
        jvmtienv = agent->mRetransformEnvironment.mJVMTIEnv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
        if (jvmtienv != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            enableNativeMethodPrefixCapability(jvmtienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        agent->mNativeMethodPrefixAdded = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
 * Add the can_maintain_original_method_order capability (for testing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
addOriginalMethodOrderCapability(JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
    jvmtiEnv *          jvmtienv = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    jvmtiCapabilities   desiredCapabilities;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   734
    /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    desiredCapabilities.can_maintain_original_method_order = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
    jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   738
    check_phase_ret(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
 * Add the can_redefine_classes capability
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
addRedefineClassesCapability(JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    jvmtiEnv *          jvmtienv = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    jvmtiCapabilities   desiredCapabilities;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    if (agent->mRedefineAvailable && !agent->mRedefineAdded) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        jvmtierror = (*jvmtienv)->GetCapabilities(jvmtienv, &desiredCapabilities);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   753
        /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        desiredCapabilities.can_redefine_classes = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        jvmtierror = (*jvmtienv)->AddCapabilities(jvmtienv, &desiredCapabilities);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
   757
        check_phase_ret(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
         * With mixed premain/agentmain agents then it's possible that the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
         * capability was potentially available in the onload phase but
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
         * subsequently unavailable in the live phase.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                     jvmtierror == JVMTI_ERROR_NOT_AVAILABLE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        if (jvmtierror == JVMTI_ERROR_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            agent->mRedefineAdded = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
 *  Support for the JVMTI callbacks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
transformClassFile(             JPLISAgent *            agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                                JNIEnv *                jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                                jobject                 loaderObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                                const char*             name,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                                jclass                  classBeingRedefined,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                                jobject                 protectionDomain,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                                jint                    class_data_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                                const unsigned char*    class_data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                                jint*                   new_class_data_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                                unsigned char**         new_class_data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                                jboolean                is_retransformer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
    jboolean        errorOutstanding        = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
    jstring         classNameStringObject   = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
    jarray          classFileBufferObject   = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    jarray          transformedBufferObject = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
    jsize           transformedBufferSize   = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    unsigned char * resultBuffer            = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
    jboolean        shouldRun               = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    /* only do this if we aren't already in the middle of processing a class on this thread */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
    shouldRun = tryToAcquireReentrancyToken(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                                jvmti(agent),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                                NULL);  /* this thread */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    if ( shouldRun ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
        /* first marshall all the parameters */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
        classNameStringObject = (*jnienv)->NewStringUTF(jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                                                        name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        jplis_assert_msg(!errorOutstanding, "can't create name string");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            classFileBufferObject = (*jnienv)->NewByteArray(jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                                                            class_data_len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            jplis_assert_msg(!errorOutstanding, "can't create byte arrau");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
            jbyte * typedBuffer = (jbyte *) class_data; /* nasty cast, dumb JNI interface, const missing */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                                                        /* The sign cast is safe. The const cast is dumb. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            (*jnienv)->SetByteArrayRegion(  jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
                                            classFileBufferObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
                                            0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
                                            class_data_len,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                                            typedBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            jplis_assert_msg(!errorOutstanding, "can't set byte array region");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
        /*  now call the JPL agents to do the transforming */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        /*  potential future optimization: may want to skip this if there are none */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
        if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            jplis_assert(agent->mInstrumentationImpl != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            jplis_assert(agent->mTransform != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            transformedBufferObject = (*jnienv)->CallObjectMethod(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                                                jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                                                agent->mInstrumentationImpl,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
                                                agent->mTransform,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
                                                loaderObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                                                classNameStringObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                                                classBeingRedefined,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                                                protectionDomain,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                                                classFileBufferObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
                                                is_retransformer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
            errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            jplis_assert_msg(!errorOutstanding, "transform method call failed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
        /* Finally, unmarshall the parameters (if someone touched the buffer, tell the JVM) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
        if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
            if ( transformedBufferObject != NULL ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                transformedBufferSize = (*jnienv)->GetArrayLength(  jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                                                                    transformedBufferObject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
                errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                jplis_assert_msg(!errorOutstanding, "can't get array length");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                    /* allocate the response buffer with the JVMTI allocate call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                     *  This is what the JVMTI spec says to do for Class File Load hook responses
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                    jvmtiError  allocError = (*(jvmti(agent)))->Allocate(jvmti(agent),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                                                                             transformedBufferSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                                                                             &resultBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                    errorOutstanding = (allocError != JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    jplis_assert_msg(!errorOutstanding, "can't allocate result buffer");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
                if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                    (*jnienv)->GetByteArrayRegion(  jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                                                    transformedBufferObject,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
                                                    0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
                                                    transformedBufferSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                                                    (jbyte *) resultBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                    errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                    jplis_assert_msg(!errorOutstanding, "can't get byte array region");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                    /* in this case, we will not return the buffer to the JVMTI,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                     * so we need to deallocate it ourselves
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                    if ( errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                        deallocate( jvmti(agent),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                                   (void*)resultBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
                if ( !errorOutstanding ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                    *new_class_data_len = (transformedBufferSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                    *new_class_data     = resultBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        /* release the token */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        releaseReentrancyToken( jvmti(agent),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                                NULL);      /* this thread */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
 *  Misc. internal utilities.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
 *  The only checked exceptions we can throw are ClassNotFoundException and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
 *  UnmodifiableClassException. All others map to InternalError.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
jthrowable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
redefineClassMapper(    JNIEnv *    jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
                        jthrowable  throwableToMap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
    jthrowable  mappedThrowable = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    jplis_assert(isSafeForJNICalls(jnienv));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
    jplis_assert(!isUnchecked(jnienv, throwableToMap));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
    if ( isInstanceofClassName( jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                                throwableToMap,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
                                "java/lang/ClassNotFoundException") ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
        mappedThrowable = throwableToMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
        if ( isInstanceofClassName( jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
                                throwableToMap,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
                                "java/lang/instrument/UnmodifiableClassException")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
            mappedThrowable = throwableToMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
            jstring message = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
            message = getMessageFromThrowable(jnienv, throwableToMap);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
            mappedThrowable = createInternalError(jnienv, message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
    jplis_assert(isSafeForJNICalls(jnienv));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    return mappedThrowable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
jobjectArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
getObjectArrayFromClasses(JNIEnv* jnienv, jclass* classes, jint classCount) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
    jclass          classArrayClass = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
    jobjectArray    localArray      = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    jint            classIndex      = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
    jboolean        errorOccurred   = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
    /* get the class array class */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
    classArrayClass = (*jnienv)->FindClass(jnienv, "java/lang/Class");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
    errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
        jplis_assert_msg(classArrayClass != NULL, "FindClass returned null class");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
        /* create the array for the classes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        localArray = (*jnienv)->NewObjectArray(jnienv, classCount, classArrayClass, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
        errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            jplis_assert_msg(localArray != NULL, "NewObjectArray returned null array");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
            /* now copy refs to all the classes and put them into the array */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
            for (classIndex = 0; classIndex < classCount; classIndex++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
                /* put class into array */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
                (*jnienv)->SetObjectArrayElement(jnienv, localArray, classIndex, classes[classIndex]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
                    localArray = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
    return localArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
/* Return the environment with the retransformation capability.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
 * Create it if it doesn't exist.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
 * Return NULL if it can't be created.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
jvmtiEnv *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
retransformableEnvironment(JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
    jvmtiEnv *          retransformerEnv     = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
    jint                jnierror             = JNI_OK;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
    jvmtiCapabilities   desiredCapabilities;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
    jvmtiEventCallbacks callbacks;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
    if (agent->mRetransformEnvironment.mJVMTIEnv != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
        return agent->mRetransformEnvironment.mJVMTIEnv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
    jnierror = (*agent->mJVM)->GetEnv(  agent->mJVM,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
                               (void **) &retransformerEnv,
7978
120267233d5e 6436034: Instance filter doesn't filter event if it occurs in native method
kamg
parents: 5506
diff changeset
   993
                               JVMTI_VERSION_1_1);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
    if ( jnierror != JNI_OK ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
    jvmtierror = (*retransformerEnv)->GetCapabilities(retransformerEnv, &desiredCapabilities);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
    desiredCapabilities.can_retransform_classes = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
    if (agent->mNativeMethodPrefixAdded) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
        desiredCapabilities.can_set_native_method_prefix = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
    jvmtierror = (*retransformerEnv)->AddCapabilities(retransformerEnv, &desiredCapabilities);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
    if (jvmtierror != JVMTI_ERROR_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
         /* cannot get the capability, dispose of the retransforming environment */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
        jvmtierror = (*retransformerEnv)->DisposeEnvironment(retransformerEnv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        jplis_assert(jvmtierror == JVMTI_ERROR_NOT_AVAILABLE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
        return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
    memset(&callbacks, 0, sizeof(callbacks));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
    callbacks.ClassFileLoadHook = &eventHandlerClassFileLoadHook;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
    jvmtierror = (*retransformerEnv)->SetEventCallbacks(retransformerEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                                                        &callbacks,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
                                                        sizeof(callbacks));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
    if (jvmtierror == JVMTI_ERROR_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
        // install the retransforming environment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        agent->mRetransformEnvironment.mJVMTIEnv = retransformerEnv;
279
e0911cc0a5d1 6547358: 2/2 j.l.i.: manifest attribute 'Can-Retransform-Classes' is ignored by isRetransformClassesSupported()
dcubed
parents: 2
diff changeset
  1021
        agent->mRetransformEnvironment.mIsRetransformer = JNI_TRUE;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
        // Make it for ClassFileLoadHook handling
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        jvmtierror = (*retransformerEnv)->SetEnvironmentLocalStorage(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
                                                       retransformerEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
                                                       &(agent->mRetransformEnvironment));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        if (jvmtierror == JVMTI_ERROR_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
            return retransformerEnv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
    return NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
 *  Underpinnings for native methods
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
isModifiableClass(JNIEnv * jnienv, JPLISAgent * agent, jclass clazz) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
    jvmtiEnv *          jvmtienv = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
    jboolean            is_modifiable = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
    jvmtierror = (*jvmtienv)->IsModifiableClass( jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                                                 clazz,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
                                                 &is_modifiable);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
  1049
    check_phase_ret_false(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
    return is_modifiable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
jboolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
isRetransformClassesSupported(JNIEnv * jnienv, JPLISAgent * agent) {
279
e0911cc0a5d1 6547358: 2/2 j.l.i.: manifest attribute 'Can-Retransform-Classes' is ignored by isRetransformClassesSupported()
dcubed
parents: 2
diff changeset
  1057
    return agent->mRetransformEnvironment.mIsRetransformer;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
setHasRetransformableTransformers(JNIEnv * jnienv, JPLISAgent * agent, jboolean has) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
    jvmtiEnv *          retransformerEnv     = retransformableEnvironment(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
    jvmtiError          jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
    jplis_assert(retransformerEnv != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
    jvmtierror = (*retransformerEnv)->SetEventNotificationMode(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                                                    retransformerEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                                                    has? JVMTI_ENABLE : JVMTI_DISABLE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                                                    JVMTI_EVENT_CLASS_FILE_LOAD_HOOK,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
                                                    NULL /* all threads */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
retransformClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
    jvmtiEnv *  retransformerEnv     = retransformableEnvironment(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
    jboolean    errorOccurred        = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
    jvmtiError  errorCode            = JVMTI_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
    jsize       numClasses           = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
    jclass *    classArray           = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
    /* This is supposed to be checked by caller, but just to be sure */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
    if (retransformerEnv == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
        jplis_assert(retransformerEnv != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
        errorOccurred = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
        errorCode = JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
    /* This was supposed to be checked by caller too */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
    if (!errorOccurred && classes == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
        jplis_assert(classes != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
        errorOccurred = JNI_TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
        errorCode = JVMTI_ERROR_NULL_POINTER;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
        numClasses = (*jnienv)->GetArrayLength(jnienv, classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
        errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
        jplis_assert(!errorOccurred);
280
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1100
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1101
        if (!errorOccurred && numClasses == 0) {
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1102
            jplis_assert(numClasses != 0);
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1103
            errorOccurred = JNI_TRUE;
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1104
            errorCode = JVMTI_ERROR_NULL_POINTER;
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1105
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
        classArray = (jclass *) allocate(retransformerEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
                                         numClasses * sizeof(jclass));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
        errorOccurred = (classArray == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
        jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
            errorCode = JVMTI_ERROR_OUT_OF_MEMORY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
        jint index;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
        for (index = 0; index < numClasses; index++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
            classArray[index] = (*jnienv)->GetObjectArrayElement(jnienv, classes, index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
            errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
            jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
            if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
            }
280
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1127
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1128
            if (classArray[index] == NULL) {
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1129
                jplis_assert(classArray[index] != NULL);
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1130
                errorOccurred = JNI_TRUE;
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1131
                errorCode = JVMTI_ERROR_NULL_POINTER;
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1132
                break;
988fe6228d49 6547500: 2/2 j.l.i.: .retransformClasses throws unexpected InternalError
dcubed
parents: 279
diff changeset
  1133
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
        errorCode = (*retransformerEnv)->RetransformClasses(retransformerEnv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
                                                            numClasses, classArray);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
        errorOccurred = (errorCode != JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
    /* Give back the buffer if we allocated it.  Throw any exceptions after.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
    if (classArray != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
        deallocate(retransformerEnv, (void*)classArray);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
    if (errorCode != JVMTI_ERROR_NONE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
        createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
    mapThrownThrowableIfNecessary(jnienv, redefineClassMapper);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
 *  Java code must not call this with a null list or a zero-length list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
redefineClasses(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray classDefinitions) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
    jvmtiEnv*   jvmtienv                        = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
    jboolean    errorOccurred                   = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
    jclass      classDefClass                   = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
    jmethodID   getDefinitionClassMethodID      = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
    jmethodID   getDefinitionClassFileMethodID  = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
    jvmtiClassDefinition* classDefs             = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
    jsize       numDefs                         = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
    jplis_assert(classDefinitions != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
    numDefs = (*jnienv)->GetArrayLength(jnienv, classDefinitions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
    errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
    jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
        jplis_assert(numDefs > 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
        /* get method IDs for methods to call on class definitions */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
        classDefClass = (*jnienv)->FindClass(jnienv, "java/lang/instrument/ClassDefinition");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
        errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
        jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
        getDefinitionClassMethodID = (*jnienv)->GetMethodID(    jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                                                classDefClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                                                "getDefinitionClass",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
                                                "()Ljava/lang/Class;");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
        errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
        jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
        getDefinitionClassFileMethodID = (*jnienv)->GetMethodID(    jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                                                    classDefClass,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
                                                    "getDefinitionClassFile",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
                                                    "()[B");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
        errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
        jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
        classDefs = (jvmtiClassDefinition *) allocate(
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
                                                jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
                                                numDefs * sizeof(jvmtiClassDefinition));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
        errorOccurred = (classDefs == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
        jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
        if ( errorOccurred ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
            createAndThrowThrowableFromJVMTIErrorCode(jnienv, JVMTI_ERROR_OUT_OF_MEMORY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
            jint i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
            for (i = 0; i < numDefs; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                jclass      classDef    = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                jbyteArray  targetFile  = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
                classDef = (*jnienv)->GetObjectArrayElement(jnienv, classDefinitions, i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
                jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                classDefs[i].klass = (*jnienv)->CallObjectMethod(jnienv, classDef, getDefinitionClassMethodID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
                targetFile = (*jnienv)->CallObjectMethod(jnienv, classDef, getDefinitionClassFileMethodID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
                classDefs[i].class_bytes = (unsigned char*)(*jnienv)->GetByteArrayElements(jnienv, targetFile, NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
                jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
                classDefs[i].class_byte_count = (*jnienv)->GetArrayLength(jnienv, targetFile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
                jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
            if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
                jvmtiError  errorCode = JVMTI_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
                errorCode = (*jvmtienv)->RedefineClasses(jvmtienv, numDefs, classDefs);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
  1255
                check_phase_blob_ret(errorCode, deallocate(jvmtienv, (void*)classDefs));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
                errorOccurred = (errorCode != JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
                if ( errorOccurred ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                    createAndThrowThrowableFromJVMTIErrorCode(jnienv, errorCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
            /* Give back the buffer if we allocated it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
            deallocate(jvmtienv, (void*)classDefs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
    mapThrownThrowableIfNecessary(jnienv, redefineClassMapper);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
/* Cheesy sharing. ClassLoader may be null. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
jobjectArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
commonGetClassList( JNIEnv *            jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
                    JPLISAgent *        agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
                    jobject             classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
                    ClassListFetcher    fetcher) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
    jvmtiEnv *      jvmtienv        = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
    jboolean        errorOccurred   = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
    jvmtiError      jvmtierror      = JVMTI_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
    jint            classCount      = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
    jclass *        classes         = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
    jobjectArray    localArray      = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
    /* retrieve the classes from the JVMTI agent */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
    jvmtierror = (*fetcher)( jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
                        classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
                        &classCount,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
                        &classes);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
  1289
    check_phase_ret_blob(jvmtierror, localArray);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
    errorOccurred = (jvmtierror != JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
    jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
    if ( errorOccurred ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
        createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
        localArray = getObjectArrayFromClasses( jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
                                                classes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
                                                classCount);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
        errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
        jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
        /* do this whether or not we saw a problem */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
        deallocate(jvmtienv, (void*)classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
    mapThrownThrowableIfNecessary(jnienv, mapAllCheckedToInternalErrorMapper);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
    return localArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
jvmtiError
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
getAllLoadedClassesClassListFetcher(    jvmtiEnv *  jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                                        jobject     classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
                                        jint *      classCount,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                                        jclass **   classes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
    return (*jvmtienv)->GetLoadedClasses(jvmtienv, classCount, classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
jobjectArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
getAllLoadedClasses(JNIEnv * jnienv, JPLISAgent * agent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
    return commonGetClassList(  jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
                                agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
                                NULL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
                                getAllLoadedClassesClassListFetcher);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
jvmtiError
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
getInitiatedClassesClassListFetcher(    jvmtiEnv *  jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
                                        jobject     classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
                                        jint *      classCount,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
                                        jclass **   classes) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
    return (*jvmtienv)->GetClassLoaderClasses(jvmtienv, classLoader, classCount, classes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
jobjectArray
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
getInitiatedClasses(JNIEnv * jnienv, JPLISAgent * agent, jobject classLoader) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
    return commonGetClassList(  jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
                                agent,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
                                classLoader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
                                getInitiatedClassesClassListFetcher);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
jlong
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
getObjectSize(JNIEnv * jnienv, JPLISAgent * agent, jobject objectToSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
    jvmtiEnv *  jvmtienv    = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
    jlong       objectSize  = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
    jvmtiError  jvmtierror  = JVMTI_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
    jvmtierror = (*jvmtienv)->GetObjectSize(jvmtienv, objectToSize, &objectSize);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
  1351
    check_phase_ret_0(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
    if ( jvmtierror != JVMTI_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
    mapThrownThrowableIfNecessary(jnienv, mapAllCheckedToInternalErrorMapper);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
    return objectSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
appendToClassLoaderSearch(JNIEnv * jnienv, JPLISAgent * agent, jstring jarFile, jboolean isBootLoader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
{
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
    jvmtiEnv *  jvmtienv    = jvmti(agent);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
    jboolean    errorOutstanding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
    jvmtiError  jvmtierror;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
    const char* utf8Chars;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
    jsize       utf8Len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
    jboolean    isCopy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
    char        platformChars[MAXPATHLEN];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
    int         platformLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
    utf8Len = (*jnienv)->GetStringUTFLength(jnienv, jarFile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
    errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
    if (!errorOutstanding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
        utf8Chars = (*jnienv)->GetStringUTFChars(jnienv, jarFile, &isCopy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
        errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        if (!errorOutstanding && utf8Chars != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
             * JVMTI spec'ed to use modified UTF8. At this time this is not implemented
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
             * the platform encoding is used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
            platformLen = convertUft8ToPlatformString((char*)utf8Chars, utf8Len, platformChars, MAXPATHLEN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
            if (platformLen < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
                createAndThrowInternalError(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
            (*jnienv)->ReleaseStringUTFChars(jnienv, jarFile, utf8Chars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
            errorOutstanding = checkForAndClearThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
            if (!errorOutstanding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
                if (isBootLoader) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
                    jvmtierror = (*jvmtienv)->AddToBootstrapClassLoaderSearch(jvmtienv, platformChars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
                    jvmtierror = (*jvmtienv)->AddToSystemClassLoaderSearch(jvmtienv, platformChars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
                }
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
  1401
                check_phase_ret(jvmtierror);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
                if ( jvmtierror != JVMTI_ERROR_NONE ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
                    createAndThrowThrowableFromJVMTIErrorCode(jnienv, jvmtierror);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
    mapThrownThrowableIfNecessary(jnienv, mapAllCheckedToInternalErrorMapper);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
 *  Set the prefixes used to wrap native methods (so they can be instrumented).
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
 *  Each transform can set a prefix, any that have been set come in as prefixArray.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
 *  Convert them in native strings in a native array then call JVM TI.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
 *  One a given call, this function handles either the prefixes for retransformable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
 *  transforms or for normal transforms.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
void
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
setNativeMethodPrefixes(JNIEnv * jnienv, JPLISAgent * agent, jobjectArray prefixArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
                        jboolean isRetransformable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
    jvmtiEnv*   jvmtienv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
    jvmtiError  err                             = JVMTI_ERROR_NONE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
    jsize       arraySize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
    jboolean    errorOccurred                   = JNI_FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
    jplis_assert(prefixArray != NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
    if (isRetransformable) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
        jvmtienv = agent->mRetransformEnvironment.mJVMTIEnv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
        jvmtienv = agent->mNormalEnvironment.mJVMTIEnv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
    arraySize = (*jnienv)->GetArrayLength(jnienv, prefixArray);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
    errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
    jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
    if (!errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
        /* allocate the native to hold the native prefixes */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
        const char** prefixes = (const char**) allocate(jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
                                                        arraySize * sizeof(char*));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
        /* since JNI ReleaseStringUTFChars needs the jstring from which the native
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
         * string was allocated, we store them in a parallel array */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
        jstring* originForRelease = (jstring*) allocate(jvmtienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
                                                        arraySize * sizeof(jstring));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
        errorOccurred = (prefixes == NULL || originForRelease == NULL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
        jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
        if ( errorOccurred ) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
            createAndThrowThrowableFromJVMTIErrorCode(jnienv, JVMTI_ERROR_OUT_OF_MEMORY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
            jint inx = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
            jint i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
            for (i = 0; i < arraySize; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
                jstring      prefixStr  = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
                const char*  prefix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
                jsize        prefixLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
                jboolean     isCopy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
                prefixStr = (jstring) ((*jnienv)->GetObjectArrayElement(jnienv,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
                                                                        prefixArray, i));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
                jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
                if (prefixStr == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
                prefixLen = (*jnienv)->GetStringUTFLength(jnienv, prefixStr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
                errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
                jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
                if (errorOccurred) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
                if (prefixLen > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
                    prefix = (*jnienv)->GetStringUTFChars(jnienv, prefixStr, &isCopy);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
                    errorOccurred = checkForThrowable(jnienv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
                    jplis_assert(!errorOccurred);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
                    if (!errorOccurred && prefix != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
                        prefixes[inx] = prefix;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
                        originForRelease[inx] = prefixStr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
                        ++inx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
            err = (*jvmtienv)->SetNativeMethodPrefixes(jvmtienv, inx, (char**)prefixes);
282
bca3e5a71df1 6572160: 3/3 Instrumentation.getObjectSize triggers JVM crash in JPLISAssert in shutdown
dcubed
parents: 281
diff changeset
  1492
            /* can be called from any phase */
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
            jplis_assert(err == JVMTI_ERROR_NONE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
            for (i = 0; i < inx; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
              (*jnienv)->ReleaseStringUTFChars(jnienv, originForRelease[i], prefixes[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
        deallocate(jvmtienv, (void*)prefixes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
        deallocate(jvmtienv, (void*)originForRelease);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
}