diff -r 13203adcd002 -r 421773f441c6 jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_loader.c --- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_loader.c Thu Aug 20 11:38:21 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This source code is provided to illustrate the usage of a given feature - * or technique and has been deliberately simplified. Additional steps - * required for a production-quality application, such as security checks, - * input validation and proper error handling, might not be present in - * this sample code. - */ - - -/* The Class Loader table. */ - -/* - * The Class Loader objects show up so early in the VM process that a - * separate table was designated for Class Loaders. - * - * The Class Loader is unique by way of it's jobject uniqueness, unfortunately - * use of JNI too early for jobject comparisons is problematic. - * It is assumed that the number of class loaders will be limited, and - * a simple linear search will be performed for now. - * That logic is isolated here and can be changed to use the standard - * table hash table search once we know JNI can be called safely. - * - * A weak global reference is created to keep tabs on loaders, and as - * each search for a loader happens, NULL weak global references will - * trigger the freedom of those entries. - * - */ - -#include "hprof.h" - -typedef struct { - jobject globalref; /* Weak Global reference for object */ - ObjectIndex object_index; -} LoaderInfo; - -static LoaderInfo * -get_info(LoaderIndex index) -{ - return (LoaderInfo*)table_get_info(gdata->loader_table, index); -} - -static void -delete_globalref(JNIEnv *env, LoaderInfo *info) -{ - jobject ref; - - HPROF_ASSERT(env!=NULL); - HPROF_ASSERT(info!=NULL); - ref = info->globalref; - info->globalref = NULL; - if ( ref != NULL ) { - deleteWeakGlobalReference(env, ref); - } - info->object_index = 0; -} - -static void -cleanup_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ -} - -static void -delete_ref_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - delete_globalref((JNIEnv*)arg, (LoaderInfo*)info_ptr); -} - -static void -list_item(TableIndex index, void *key_ptr, int key_len, - void *info_ptr, void *arg) -{ - LoaderInfo *info; - - HPROF_ASSERT(info_ptr!=NULL); - - info = (LoaderInfo*)info_ptr; - debug_message( "Loader 0x%08x: globalref=%p, object_index=%d\n", - index, (void*)info->globalref, info->object_index); -} - -static void -free_entry(JNIEnv *env, LoaderIndex index) -{ - LoaderInfo *info; - - info = get_info(index); - delete_globalref(env, info); - table_free_entry(gdata->loader_table, index); -} - -typedef struct SearchData { - JNIEnv *env; - jobject loader; - LoaderIndex found; -} SearchData; - -static void -search_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg) -{ - LoaderInfo *info; - SearchData *data; - - HPROF_ASSERT(info_ptr!=NULL); - HPROF_ASSERT(arg!=NULL); - info = (LoaderInfo*)info_ptr; - data = (SearchData*)arg; - if ( data->loader == info->globalref ) { - /* Covers when looking for NULL too. */ - HPROF_ASSERT(data->found==0); /* Did we find more than one? */ - data->found = index; - } else if ( data->env != NULL && data->loader != NULL && - info->globalref != NULL ) { - jobject lref; - - lref = newLocalReference(data->env, info->globalref); - if ( lref == NULL ) { - /* Object went away, free reference and entry */ - free_entry(data->env, index); - } else if ( isSameObject(data->env, data->loader, lref) ) { - HPROF_ASSERT(data->found==0); /* Did we find more than one? */ - data->found = index; - } - if ( lref != NULL ) { - deleteLocalReference(data->env, lref); - } - } - -} - -static LoaderIndex -search(JNIEnv *env, jobject loader) -{ - SearchData data; - - data.env = env; - data.loader = loader; - data.found = 0; - table_walk_items(gdata->loader_table, &search_item, (void*)&data); - return data.found; -} - -LoaderIndex -loader_find_or_create(JNIEnv *env, jobject loader) -{ - LoaderIndex index; - - /* See if we remembered the system loader */ - if ( loader==NULL && gdata->system_loader != 0 ) { - return gdata->system_loader; - } - if ( loader==NULL ) { - env = NULL; - } - index = search(env, loader); - if ( index == 0 ) { - static LoaderInfo empty_info; - LoaderInfo info; - - info = empty_info; - if ( loader != NULL ) { - HPROF_ASSERT(env!=NULL); - info.globalref = newWeakGlobalReference(env, loader); - info.object_index = 0; - } - index = table_create_entry(gdata->loader_table, NULL, 0, (void*)&info); - } - HPROF_ASSERT(search(env,loader)==index); - /* Remember the system loader */ - if ( loader==NULL && gdata->system_loader == 0 ) { - gdata->system_loader = index; - } - return index; -} - -void -loader_init(void) -{ - gdata->loader_table = table_initialize("Loader", - 16, 16, 0, (int)sizeof(LoaderInfo)); -} - -void -loader_list(void) -{ - debug_message( - "--------------------- Loader Table ------------------------\n"); - table_walk_items(gdata->loader_table, &list_item, NULL); - debug_message( - "----------------------------------------------------------\n"); -} - -void -loader_cleanup(void) -{ - table_cleanup(gdata->loader_table, &cleanup_item, NULL); - gdata->loader_table = NULL; -} - -void -loader_delete_global_references(JNIEnv *env) -{ - table_walk_items(gdata->loader_table, &delete_ref_item, (void*)env); -} - -/* Get the object index for a class loader */ -ObjectIndex -loader_object_index(JNIEnv *env, LoaderIndex index) -{ - LoaderInfo *info; - ObjectIndex object_index; - jobject wref; - - /* Assume no object index at first (default class loader) */ - info = get_info(index); - object_index = info->object_index; - wref = info->globalref; - if ( wref != NULL && object_index == 0 ) { - jobject lref; - - object_index = 0; - lref = newLocalReference(env, wref); - if ( lref != NULL && !isSameObject(env, lref, NULL) ) { - jlong tag; - - /* Get the tag on the object and extract the object_index */ - tag = getTag(lref); - if ( tag != (jlong)0 ) { - object_index = tag_extract(tag); - } - } - if ( lref != NULL ) { - deleteLocalReference(env, lref); - } - info->object_index = object_index; - } - return object_index; -}