Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/runtime/handles.cpp
32285 views
/*1* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "memory/allocation.inline.hpp"26#include "oops/constantPool.hpp"27#include "oops/oop.inline.hpp"28#include "runtime/handles.inline.hpp"29#include "runtime/thread.inline.hpp"30#ifdef TARGET_OS_FAMILY_linux31# include "os_linux.inline.hpp"32#endif33#ifdef TARGET_OS_FAMILY_solaris34# include "os_solaris.inline.hpp"35#endif36#ifdef TARGET_OS_FAMILY_windows37# include "os_windows.inline.hpp"38#endif39#ifdef TARGET_OS_FAMILY_bsd40# include "os_bsd.inline.hpp"41#endif4243PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC4445#ifdef ASSERT46oop* HandleArea::allocate_handle(oop obj) {47assert(_handle_mark_nesting > 1, "memory leak: allocating handle outside HandleMark");48assert(_no_handle_mark_nesting == 0, "allocating handle inside NoHandleMark");49assert(obj->is_oop(), err_msg("not an oop: " INTPTR_FORMAT, (intptr_t*) obj));50return real_allocate_handle(obj);51}5253Handle::Handle(Thread* thread, oop obj) {54assert(thread == Thread::current(), "sanity check");55if (obj == NULL) {56_handle = NULL;57} else {58_handle = thread->handle_area()->allocate_handle(obj);59}60}6162#endif6364static uintx chunk_oops_do(OopClosure* f, Chunk* chunk, char* chunk_top) {65oop* bottom = (oop*) chunk->bottom();66oop* top = (oop*) chunk_top;67uintx handles_visited = top - bottom;68assert(top >= bottom && top <= (oop*) chunk->top(), "just checking");69// during GC phase 3, a handle may be a forward pointer that70// is not yet valid, so loosen the assertion71while (bottom < top) {72// This test can be moved up but for now check every oop.7374// JFR is known to set mark word to 0 for duration of leak analysis VM operaiton75assert((*bottom)->is_oop(INCLUDE_JFR), "handle should point to oop");7677f->do_oop(bottom++);78}79return handles_visited;80}8182// Used for debugging handle allocation.83NOT_PRODUCT(jint _nof_handlemarks = 0;)8485void HandleArea::oops_do(OopClosure* f) {86uintx handles_visited = 0;87// First handle the current chunk. It is filled to the high water mark.88handles_visited += chunk_oops_do(f, _chunk, _hwm);89// Then handle all previous chunks. They are completely filled.90Chunk* k = _first;91while(k != _chunk) {92handles_visited += chunk_oops_do(f, k, k->top());93k = k->next();94}9596// The thread local handle areas should not get very large97if (TraceHandleAllocation && handles_visited > TotalHandleAllocationLimit) {98#ifdef ASSERT99warning("%d: Visited in HandleMark : %d",100_nof_handlemarks, handles_visited);101#else102warning("Visited in HandleMark : %d", handles_visited);103#endif104}105if (_prev != NULL) _prev->oops_do(f);106}107108void HandleMark::initialize(Thread* thread) {109_thread = thread;110// Save area111_area = thread->handle_area();112// Save current top113_chunk = _area->_chunk;114_hwm = _area->_hwm;115_max = _area->_max;116_size_in_bytes = _area->_size_in_bytes;117debug_only(_area->_handle_mark_nesting++);118assert(_area->_handle_mark_nesting > 0, "must stack allocate HandleMarks");119debug_only(Atomic::inc(&_nof_handlemarks);)120121// Link this in the thread122set_previous_handle_mark(thread->last_handle_mark());123thread->set_last_handle_mark(this);124}125126127HandleMark::~HandleMark() {128HandleArea* area = _area; // help compilers with poor alias analysis129assert(area == _thread->handle_area(), "sanity check");130assert(area->_handle_mark_nesting > 0, "must stack allocate HandleMarks" );131debug_only(area->_handle_mark_nesting--);132133// Debug code to trace the number of handles allocated per mark/134#ifdef ASSERT135if (TraceHandleAllocation) {136size_t handles = 0;137Chunk *c = _chunk->next();138if (c == NULL) {139handles = area->_hwm - _hwm; // no new chunk allocated140} else {141handles = _max - _hwm; // add rest in first chunk142while(c != NULL) {143handles += c->length();144c = c->next();145}146handles -= area->_max - area->_hwm; // adjust for last trunk not full147}148handles /= sizeof(void *); // Adjust for size of a handle149if (handles > HandleAllocationLimit) {150// Note: _nof_handlemarks is only set in debug mode151warning("%d: Allocated in HandleMark : %d", _nof_handlemarks, handles);152}153154tty->print_cr("Handles %d", handles);155}156#endif157158// Delete later chunks159if( _chunk->next() ) {160// reset arena size before delete chunks. Otherwise, the total161// arena size could exceed total chunk size162assert(area->size_in_bytes() > size_in_bytes(), "Sanity check");163area->set_size_in_bytes(size_in_bytes());164_chunk->next_chop();165} else {166assert(area->size_in_bytes() == size_in_bytes(), "Sanity check");167}168// Roll back arena to saved top markers169area->_chunk = _chunk;170area->_hwm = _hwm;171area->_max = _max;172#ifdef ASSERT173// clear out first chunk (to detect allocation bugs)174if (ZapVMHandleArea) {175memset(_hwm, badHandleValue, _max - _hwm);176}177Atomic::dec(&_nof_handlemarks);178#endif179180// Unlink this from the thread181_thread->set_last_handle_mark(previous_handle_mark());182}183184void* HandleMark::operator new(size_t size) throw() {185return AllocateHeap(size, mtThread);186}187188void* HandleMark::operator new [] (size_t size) throw() {189return AllocateHeap(size, mtThread);190}191192void HandleMark::operator delete(void* p) {193FreeHeap(p, mtThread);194}195196void HandleMark::operator delete[](void* p) {197FreeHeap(p, mtThread);198}199200#ifdef ASSERT201202NoHandleMark::NoHandleMark() {203HandleArea* area = Thread::current()->handle_area();204area->_no_handle_mark_nesting++;205assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" );206}207208209NoHandleMark::~NoHandleMark() {210HandleArea* area = Thread::current()->handle_area();211assert(area->_no_handle_mark_nesting > 0, "must stack allocate NoHandleMark" );212area->_no_handle_mark_nesting--;213}214215216ResetNoHandleMark::ResetNoHandleMark() {217HandleArea* area = Thread::current()->handle_area();218_no_handle_mark_nesting = area->_no_handle_mark_nesting;219area->_no_handle_mark_nesting = 0;220}221222223ResetNoHandleMark::~ResetNoHandleMark() {224HandleArea* area = Thread::current()->handle_area();225area->_no_handle_mark_nesting = _no_handle_mark_nesting;226}227228#endif229230231