< prev index next >

src/hotspot/share/services/mallocSiteTable.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 26,63 **** #include "memory/allocation.inline.hpp" #include "runtime/atomic.hpp" #include "services/mallocSiteTable.hpp" - /* - * Early os::malloc() calls come from initializations of static variables, long before entering any - * VM code. Upon the arrival of the first os::malloc() call, malloc site hashtable has to be - * initialized, along with the allocation site for the hashtable entries. - * To ensure that malloc site hashtable can be initialized without triggering any additional os::malloc() - * call, the hashtable bucket array and hashtable entry allocation site have to be static. - * It is not a problem for hashtable bucket, since it is an array of pointer type, C runtime just - * allocates a block memory and zero the memory for it. - * But for hashtable entry allocation site object, things get tricky. C runtime not only allocates - * memory for it, but also calls its constructor at some later time. If we initialize the allocation site - * at the first os::malloc() call, the object will be reinitialized when its constructor is called - * by C runtime. - * To workaround above issue, we declare a static size_t array with the size of the CallsiteHashtableEntry, - * the memory is used to instantiate CallsiteHashtableEntry for the hashtable entry allocation site. - * Given it is a primitive type array, C runtime will do nothing other than assign the memory block for the variable, - * which is exactly what we want. - * The same trick is also applied to create NativeCallStack object for CallsiteHashtableEntry memory allocation. - * - * Note: C++ object usually aligns to particular alignment, depends on compiler implementation, we declare - * the memory as size_t arrays, to ensure the memory is aligned to native machine word alignment. - */ - - // Reserve enough memory for NativeCallStack and MallocSiteHashtableEntry objects - size_t MallocSiteTable::_hash_entry_allocation_stack[CALC_OBJ_SIZE_IN_TYPE(NativeCallStack, size_t)]; - size_t MallocSiteTable::_hash_entry_allocation_site[CALC_OBJ_SIZE_IN_TYPE(MallocSiteHashtableEntry, size_t)]; - // Malloc site hashtable buckets MallocSiteHashtableEntry* MallocSiteTable::_table[MallocSiteTable::table_size]; // concurrent access counter volatile int MallocSiteTable::_access_count = 0; // Tracking hashtable contention --- 26,39 ---- #include "memory/allocation.inline.hpp" #include "runtime/atomic.hpp" #include "services/mallocSiteTable.hpp" // Malloc site hashtable buckets MallocSiteHashtableEntry* MallocSiteTable::_table[MallocSiteTable::table_size]; + const NativeCallStack* MallocSiteTable::_hash_entry_allocation_stack = NULL; + const MallocSiteHashtableEntry* MallocSiteTable::_hash_entry_allocation_site = NULL; // concurrent access counter volatile int MallocSiteTable::_access_count = 0; // Tracking hashtable contention
*** 71,83 **** * this allocation site. * The method is called during C runtime static variable initialization * time, it is in single-threaded mode from JVM perspective. */ bool MallocSiteTable::initialize() { - assert(sizeof(_hash_entry_allocation_stack) >= sizeof(NativeCallStack), "Sanity Check"); - assert(sizeof(_hash_entry_allocation_site) >= sizeof(MallocSiteHashtableEntry), - "Sanity Check"); assert((size_t)table_size <= MAX_MALLOCSITE_TABLE_SIZE, "Hashtable overflow"); // Fake the call stack for hashtable entry allocation assert(NMT_TrackingStackDepth > 1, "At least one tracking stack"); --- 47,56 ----
*** 89,109 **** if (NMT_TrackingStackDepth >= 2) { pc[1] = (address)MallocSiteTable::lookup_or_add; } pc[0] = (address)MallocSiteTable::new_entry; ! // Instantiate NativeCallStack object, have to use placement new operator. (see comments above) ! NativeCallStack* stack = ::new ((void*)_hash_entry_allocation_stack) ! NativeCallStack(pc, MIN2(((int)(sizeof(pc) / sizeof(address))), ((int)NMT_TrackingStackDepth))); ! ! // Instantiate hash entry for hashtable entry allocation callsite ! MallocSiteHashtableEntry* entry = ::new ((void*)_hash_entry_allocation_site) ! MallocSiteHashtableEntry(*stack, mtNMT); // Add the allocation site to hashtable. ! int index = hash_to_index(stack->hash()); ! _table[index] = entry; return true; } // Walks entries in the hashtable. --- 62,84 ---- if (NMT_TrackingStackDepth >= 2) { pc[1] = (address)MallocSiteTable::lookup_or_add; } pc[0] = (address)MallocSiteTable::new_entry; ! static const NativeCallStack stack(pc, MIN2(((int)(sizeof(pc) / sizeof(address))), ((int)NMT_TrackingStackDepth))); ! static const MallocSiteHashtableEntry entry(stack, mtNMT); ! ! assert(_hash_entry_allocation_stack == NULL && ! _hash_entry_allocation_site == NULL, ! "Already initailized"); ! ! _hash_entry_allocation_stack = &stack; ! _hash_entry_allocation_site = &entry; // Add the allocation site to hashtable. ! int index = hash_to_index(stack.hash()); ! _table[index] = const_cast<MallocSiteHashtableEntry*>(&entry); return true; } // Walks entries in the hashtable.
*** 202,219 **** for (int index = 0; index < table_size; index ++) { MallocSiteHashtableEntry* head = _table[index]; _table[index] = NULL; delete_linked_list(head); } } void MallocSiteTable::delete_linked_list(MallocSiteHashtableEntry* head) { MallocSiteHashtableEntry* p; while (head != NULL) { p = head; head = (MallocSiteHashtableEntry*)head->next(); ! if (p != (MallocSiteHashtableEntry*)_hash_entry_allocation_site) { delete p; } } } --- 177,197 ---- for (int index = 0; index < table_size; index ++) { MallocSiteHashtableEntry* head = _table[index]; _table[index] = NULL; delete_linked_list(head); } + + _hash_entry_allocation_stack = NULL; + _hash_entry_allocation_site = NULL; } void MallocSiteTable::delete_linked_list(MallocSiteHashtableEntry* head) { MallocSiteHashtableEntry* p; while (head != NULL) { p = head; head = (MallocSiteHashtableEntry*)head->next(); ! if (p != hash_entry_allocation_site()) { delete p; } } }
< prev index next >