Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/jvmti/hprof/hprof_loader.c
38829 views
/*1* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6*7* - Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9*10* - Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* - Neither the name of Oracle nor the names of its15* contributors may be used to endorse or promote products derived16* from this software without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS19* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,20* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR21* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR22* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,23* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,24* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR25* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF26* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING27* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS28* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29*/3031/*32* This source code is provided to illustrate the usage of a given feature33* or technique and has been deliberately simplified. Additional steps34* required for a production-quality application, such as security checks,35* input validation and proper error handling, might not be present in36* this sample code.37*/383940/* The Class Loader table. */4142/*43* The Class Loader objects show up so early in the VM process that a44* separate table was designated for Class Loaders.45*46* The Class Loader is unique by way of it's jobject uniqueness, unfortunately47* use of JNI too early for jobject comparisons is problematic.48* It is assumed that the number of class loaders will be limited, and49* a simple linear search will be performed for now.50* That logic is isolated here and can be changed to use the standard51* table hash table search once we know JNI can be called safely.52*53* A weak global reference is created to keep tabs on loaders, and as54* each search for a loader happens, NULL weak global references will55* trigger the freedom of those entries.56*57*/5859#include "hprof.h"6061typedef struct {62jobject globalref; /* Weak Global reference for object */63ObjectIndex object_index;64} LoaderInfo;6566static LoaderInfo *67get_info(LoaderIndex index)68{69return (LoaderInfo*)table_get_info(gdata->loader_table, index);70}7172static void73delete_globalref(JNIEnv *env, LoaderInfo *info)74{75jobject ref;7677HPROF_ASSERT(env!=NULL);78HPROF_ASSERT(info!=NULL);79ref = info->globalref;80info->globalref = NULL;81if ( ref != NULL ) {82deleteWeakGlobalReference(env, ref);83}84info->object_index = 0;85}8687static void88cleanup_item(TableIndex index, void *key_ptr, int key_len,89void *info_ptr, void *arg)90{91}9293static void94delete_ref_item(TableIndex index, void *key_ptr, int key_len,95void *info_ptr, void *arg)96{97delete_globalref((JNIEnv*)arg, (LoaderInfo*)info_ptr);98}99100static void101list_item(TableIndex index, void *key_ptr, int key_len,102void *info_ptr, void *arg)103{104LoaderInfo *info;105106HPROF_ASSERT(info_ptr!=NULL);107108info = (LoaderInfo*)info_ptr;109debug_message( "Loader 0x%08x: globalref=%p, object_index=%d\n",110index, (void*)info->globalref, info->object_index);111}112113static void114free_entry(JNIEnv *env, LoaderIndex index)115{116LoaderInfo *info;117118info = get_info(index);119delete_globalref(env, info);120table_free_entry(gdata->loader_table, index);121}122123typedef struct SearchData {124JNIEnv *env;125jobject loader;126LoaderIndex found;127} SearchData;128129static void130search_item(TableIndex index, void *key_ptr, int key_len, void *info_ptr, void *arg)131{132LoaderInfo *info;133SearchData *data;134135HPROF_ASSERT(info_ptr!=NULL);136HPROF_ASSERT(arg!=NULL);137info = (LoaderInfo*)info_ptr;138data = (SearchData*)arg;139if ( data->loader == info->globalref ) {140/* Covers when looking for NULL too. */141HPROF_ASSERT(data->found==0); /* Did we find more than one? */142data->found = index;143} else if ( data->env != NULL && data->loader != NULL &&144info->globalref != NULL ) {145jobject lref;146147lref = newLocalReference(data->env, info->globalref);148if ( lref == NULL ) {149/* Object went away, free reference and entry */150free_entry(data->env, index);151} else if ( isSameObject(data->env, data->loader, lref) ) {152HPROF_ASSERT(data->found==0); /* Did we find more than one? */153data->found = index;154}155if ( lref != NULL ) {156deleteLocalReference(data->env, lref);157}158}159160}161162static LoaderIndex163search(JNIEnv *env, jobject loader)164{165SearchData data;166167data.env = env;168data.loader = loader;169data.found = 0;170table_walk_items(gdata->loader_table, &search_item, (void*)&data);171return data.found;172}173174LoaderIndex175loader_find_or_create(JNIEnv *env, jobject loader)176{177LoaderIndex index;178179/* See if we remembered the system loader */180if ( loader==NULL && gdata->system_loader != 0 ) {181return gdata->system_loader;182}183if ( loader==NULL ) {184env = NULL;185}186index = search(env, loader);187if ( index == 0 ) {188static LoaderInfo empty_info;189LoaderInfo info;190191info = empty_info;192if ( loader != NULL ) {193HPROF_ASSERT(env!=NULL);194info.globalref = newWeakGlobalReference(env, loader);195info.object_index = 0;196}197index = table_create_entry(gdata->loader_table, NULL, 0, (void*)&info);198}199HPROF_ASSERT(search(env,loader)==index);200/* Remember the system loader */201if ( loader==NULL && gdata->system_loader == 0 ) {202gdata->system_loader = index;203}204return index;205}206207void208loader_init(void)209{210gdata->loader_table = table_initialize("Loader",21116, 16, 0, (int)sizeof(LoaderInfo));212}213214void215loader_list(void)216{217debug_message(218"--------------------- Loader Table ------------------------\n");219table_walk_items(gdata->loader_table, &list_item, NULL);220debug_message(221"----------------------------------------------------------\n");222}223224void225loader_cleanup(void)226{227table_cleanup(gdata->loader_table, &cleanup_item, NULL);228gdata->loader_table = NULL;229}230231void232loader_delete_global_references(JNIEnv *env)233{234table_walk_items(gdata->loader_table, &delete_ref_item, (void*)env);235}236237/* Get the object index for a class loader */238ObjectIndex239loader_object_index(JNIEnv *env, LoaderIndex index)240{241LoaderInfo *info;242ObjectIndex object_index;243jobject wref;244245/* Assume no object index at first (default class loader) */246info = get_info(index);247object_index = info->object_index;248wref = info->globalref;249if ( wref != NULL && object_index == 0 ) {250jobject lref;251252object_index = 0;253lref = newLocalReference(env, wref);254if ( lref != NULL && !isSameObject(env, lref, NULL) ) {255jlong tag;256257/* Get the tag on the object and extract the object_index */258tag = getTag(lref);259if ( tag != (jlong)0 ) {260object_index = tag_extract(tag);261}262}263if ( lref != NULL ) {264deleteLocalReference(env, lref);265}266info->object_index = object_index;267}268return object_index;269}270271272