1 /* 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_RUNTIME_HANDLES_INLINE_HPP 26 #define SHARE_VM_RUNTIME_HANDLES_INLINE_HPP 27 28 #include "runtime/handles.hpp" 29 #include "runtime/thread.inline.hpp" 30 31 // these inline functions are in a separate file to break an include cycle 32 // between Thread and Handle 33 34 inline Handle::Handle(oop obj) { 35 if (obj == NULL) { 36 _handle = NULL; 37 } else { 38 _handle = Thread::current()->handle_area()->allocate_handle(obj); 39 } 40 } 41 42 43 #ifndef ASSERT 44 inline Handle::Handle(Thread* thread, oop obj) { 45 assert(thread == Thread::current(), "sanity check"); 46 if (obj == NULL) { 47 _handle = NULL; 48 } else { 49 _handle = thread->handle_area()->allocate_handle(obj); 50 } 51 } 52 #endif // ASSERT 53 54 #ifndef SHARK 55 #define CHECK_IN_STACK() assert (_thread->is_in_stack((address)this), "not on stack?") 56 #else 57 #define CHECK_IN_STACK() 58 #endif 59 60 // Constructors for metadata handles 61 #define DEF_METADATA_HANDLE_FN(name, type) \ 62 inline name##Handle::name##Handle(type* obj) : _value(obj), _thread(NULL) { \ 63 if (obj != NULL) { \ 64 assert(((Metadata*)obj)->is_valid(), "obj is valid"); \ 65 _thread = Thread::current(); \ 66 assert (_thread->is_in_stack((address)this), "not on stack?"); \ 67 _thread->metadata_handles()->push((Metadata*)obj); \ 68 } \ 69 } \ 70 inline name##Handle::name##Handle(Thread* thread, type* obj) : _value(obj), _thread(thread) { \ 71 if (obj != NULL) { \ 72 assert(((Metadata*)obj)->is_valid(), "obj is valid"); \ 73 assert(_thread == Thread::current(), "thread must be current"); \ 74 assert (_thread->is_in_stack((address)this), "not on stack?"); \ 75 _thread->metadata_handles()->push((Metadata*)obj); \ 76 } \ 77 } \ 78 inline name##Handle::name##Handle(const name##Handle &h) { \ 79 _value = h._value; \ 80 if (_value != NULL) { \ 81 assert(_value->is_valid(), "obj is valid"); \ 82 if (h._thread != NULL) { \ 83 assert(h._thread == Thread::current(), "thread must be current");\ 84 _thread = h._thread; \ 85 } else { \ 86 _thread = Thread::current(); \ 87 } \ 88 CHECK_IN_STACK(); \ 89 _thread->metadata_handles()->push((Metadata*)_value); \ 90 } else { \ 91 _thread = NULL; \ 92 } \ 93 } \ 94 inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ 95 remove(); \ 96 _value = s._value; \ 97 if (_value != NULL) { \ 98 assert(_value->is_valid(), "obj is valid"); \ 99 if (s._thread != NULL) { \ 100 assert(s._thread == Thread::current(), "thread must be current");\ 101 _thread = s._thread; \ 102 } else { \ 103 _thread = Thread::current(); \ 104 } \ 105 assert (_thread->is_in_stack((address)this), "not on stack?"); \ 106 _thread->metadata_handles()->push((Metadata*)_value); \ 107 } else { \ 108 _thread = NULL; \ 109 } \ 110 return *this; \ 111 } \ 112 inline void name##Handle::remove() { \ 113 if (_value != NULL) { \ 114 int i = _thread->metadata_handles()->find_from_end((Metadata*)_value); \ 115 assert(i!=-1, "not in metadata_handles list"); \ 116 _thread->metadata_handles()->remove_at(i); \ 117 } \ 118 } \ 119 inline name##Handle::~name##Handle () { remove(); } \ 120 121 DEF_METADATA_HANDLE_FN(method, Method) 122 DEF_METADATA_HANDLE_FN(constantPool, ConstantPool) 123 124 #undef CHECK_IN_STACK 125 126 inline HandleMark::HandleMark() { 127 initialize(Thread::current()); 128 } 129 130 131 inline void HandleMark::push() { 132 // This is intentionally a NOP. pop_and_restore will reset 133 // values to the HandleMark further down the stack, typically 134 // in JavaCalls::call_helper. 135 debug_only(_area->_handle_mark_nesting++); 136 } 137 138 inline void HandleMark::pop_and_restore() { 139 HandleArea* area = _area; // help compilers with poor alias analysis 140 // Delete later chunks 141 if( _chunk->next() ) { 142 // reset arena size before delete chunks. Otherwise, the total 143 // arena size could exceed total chunk size 144 assert(area->size_in_bytes() > size_in_bytes(), "Sanity check"); 145 area->set_size_in_bytes(size_in_bytes()); 146 _chunk->next_chop(); 147 } else { 148 assert(area->size_in_bytes() == size_in_bytes(), "Sanity check"); 149 } 150 // Roll back arena to saved top markers 151 area->_chunk = _chunk; 152 area->_hwm = _hwm; 153 area->_max = _max; 154 debug_only(area->_handle_mark_nesting--); 155 } 156 157 #endif // SHARE_VM_RUNTIME_HANDLES_INLINE_HPP