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