Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/jvmti/hprof/hprof_object.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/* Object table. */4142/*43* An Object is unique by it's allocation site (SiteIndex), it's size,44* it's kind, and it's serial number. Normally only the serial number45* would have been necessary for heap=dump, and these other items46* could have been moved to the ObjectInfo. An optimization left47* to the reader. Lookups are not normally done on ObjectIndex's48* anyway because we typically know when to create them.49* Objects that have been tagged, are tagged with an ObjectIndex,50* Objects that are not tagged need a ObjectIndex, a lookup when51* heap=sites, and a new one when heap=dump.52* Objects that are freed, need the tag converted to an ObjectIndex,53* so they can be freed, but only when heap=dump.54* The thread serial number is for the thread associated with this55* object. If the object is a Thread object, it should be the serial56* number for that thread. The ThreadStart event is responsible57* for making sure the thread serial number is correct, but between the58* initial allocation of a Thread object and it's ThreadStart event59* the thread serial number could be for the thread that allocated60* the Thread object.61*62* This will likely be the largest table when using heap=dump, when63* there is one table entry per object.64*65* ObjectIndex entries differ between heap=dump and heap=sites.66* With heap=sites, each ObjectIndex represents a unique site, size,67* and kind of object, so many jobject's will map to a single ObjectIndex.68* With heap=dump, every ObjectIndex maps to a unique jobject.69*70* During processing of a heap dump, the references for the object71* this ObjectIndex represents is assigned to the references field72* of the ObjectInfo as a linked list. (see hprof_references.c).73* Once all the refernces are attached, they are processed into the74* appropriate hprof dump information.75*76* The references field is set and cleared as many times as the heap77* is dumped, as is the reference table.78*79*/8081#include "hprof.h"8283typedef struct ObjectKey {84SiteIndex site_index; /* Site of allocation */85jint size; /* Size of object as reported by VM */86ObjectKind kind; /* Kind of object, most are OBJECT_NORMAL */87SerialNumber serial_num; /* For heap=dump, a unique number. */88} ObjectKey;8990typedef struct ObjectInfo {91RefIndex references; /* Linked list of refs in this object */92SerialNumber thread_serial_num; /* Thread serial number for allocation */93} ObjectInfo;9495/* Private internal functions. */9697static ObjectKey*98get_pkey(ObjectIndex index)99{100void *key_ptr;101int key_len;102103table_get_key(gdata->object_table, index, (void*)&key_ptr, &key_len);104HPROF_ASSERT(key_len==(int)sizeof(ObjectKey));105HPROF_ASSERT(key_ptr!=NULL);106return (ObjectKey*)key_ptr;107}108109static ObjectInfo *110get_info(ObjectIndex index)111{112ObjectInfo *info;113114info = (ObjectInfo*)table_get_info(gdata->object_table, index);115return info;116}117118static void119list_item(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)120{121ObjectKey *pkey;122ObjectInfo *info;123124HPROF_ASSERT(key_ptr!=NULL);125HPROF_ASSERT(key_len!=0);126HPROF_ASSERT(info_ptr!=NULL);127128info = (ObjectInfo*)info_ptr;129130pkey = (ObjectKey*)key_ptr;131debug_message( "Object 0x%08x: site=0x%08x, SN=%u, "132" size=%d, kind=%d, refs=0x%x, threadSN=%u\n",133i, pkey->site_index, pkey->serial_num, pkey->size, pkey->kind,134info->references, info->thread_serial_num);135}136137static void138clear_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)139{140ObjectInfo *info;141142HPROF_ASSERT(info_ptr!=NULL);143info = (ObjectInfo *)info_ptr;144info->references = 0;145}146147static void148dump_class_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)149{150ObjectInfo *info;151152HPROF_ASSERT(info_ptr!=NULL);153info = (ObjectInfo *)info_ptr;154reference_dump_class((JNIEnv*)arg, i, info->references);155}156157static void158dump_instance_references(TableIndex i, void *key_ptr, int key_len, void *info_ptr, void *arg)159{160ObjectInfo *info;161162HPROF_ASSERT(info_ptr!=NULL);163info = (ObjectInfo *)info_ptr;164reference_dump_instance((JNIEnv*)arg, i, info->references);165}166167/* External interfaces. */168169ObjectIndex170object_new(SiteIndex site_index, jint size, ObjectKind kind, SerialNumber thread_serial_num)171{172ObjectIndex index;173ObjectKey key;174static ObjectKey empty_key;175176key = empty_key;177key.site_index = site_index;178key.size = size;179key.kind = kind;180if ( gdata->heap_dump ) {181static ObjectInfo empty_info;182ObjectInfo i;183184i = empty_info;185i.thread_serial_num = thread_serial_num;186key.serial_num = gdata->object_serial_number_counter++;187index = table_create_entry(gdata->object_table,188&key, (int)sizeof(ObjectKey), &i);189} else {190key.serial_num =191class_get_serial_number(site_get_class_index(site_index));192index = table_find_or_create_entry(gdata->object_table,193&key, (int)sizeof(ObjectKey), NULL, NULL);194}195site_update_stats(site_index, size, 1);196return index;197}198199void200object_init(void)201{202jint bucket_count;203204bucket_count = 511;205if ( gdata->heap_dump ) {206bucket_count = 0;207}208HPROF_ASSERT(gdata->object_table==NULL);209gdata->object_table = table_initialize("Object", 4096,2104096, bucket_count, (int)sizeof(ObjectInfo));211}212213SiteIndex214object_get_site(ObjectIndex index)215{216ObjectKey *pkey;217218pkey = get_pkey(index);219return pkey->site_index;220}221222jint223object_get_size(ObjectIndex index)224{225ObjectKey *pkey;226227pkey = get_pkey(index);228return pkey->size;229}230231ObjectKind232object_get_kind(ObjectIndex index)233{234ObjectKey *pkey;235236pkey = get_pkey(index);237return pkey->kind;238}239240ObjectKind241object_free(ObjectIndex index)242{243ObjectKey *pkey;244ObjectKind kind;245246pkey = get_pkey(index);247kind = pkey->kind;248249/* Decrement allocations at this site. */250site_update_stats(pkey->site_index, -(pkey->size), -1);251252if ( gdata->heap_dump ) {253table_free_entry(gdata->object_table, index);254}255return kind;256}257258void259object_list(void)260{261debug_message(262"--------------------- Object Table ------------------------\n");263table_walk_items(gdata->object_table, &list_item, NULL);264debug_message(265"----------------------------------------------------------\n");266}267268void269object_cleanup(void)270{271table_cleanup(gdata->object_table, NULL, NULL);272gdata->object_table = NULL;273}274275void276object_set_thread_serial_number(ObjectIndex index,277SerialNumber thread_serial_num)278{279ObjectInfo *info;280281info = get_info(index);282info->thread_serial_num = thread_serial_num;283}284285SerialNumber286object_get_thread_serial_number(ObjectIndex index)287{288ObjectInfo *info;289290info = get_info(index);291return info->thread_serial_num;292}293294RefIndex295object_get_references(ObjectIndex index)296{297ObjectInfo *info;298299info = get_info(index);300return info->references;301}302303void304object_set_references(ObjectIndex index, RefIndex ref_index)305{306ObjectInfo *info;307308info = get_info(index);309info->references = ref_index;310}311312void313object_clear_references(void)314{315table_walk_items(gdata->object_table, &clear_references, NULL);316}317318void319object_reference_dump(JNIEnv *env)320{321table_walk_items(gdata->object_table, &dump_instance_references, (void*)env);322table_walk_items(gdata->object_table, &dump_class_references, (void*)env);323}324325326