1 /*
  2  * Copyright (c) 1998, 2020, 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_RUNTIME_HANDLES_INLINE_HPP
 26 #define SHARE_RUNTIME_HANDLES_INLINE_HPP
 27 
 28 #include "runtime/handles.hpp"
 29 
 30 #include "runtime/thread.hpp"
 31 #include "oops/metadata.hpp"
 32 #include "oops/oop.hpp"
 33 
 34 // these inline functions are in a separate file to break an include cycle
 35 // between Thread and Handle
 36 
 37 inline Handle::Handle(Thread* thread, oop obj) {
 38   assert(thread == Thread::current(), "sanity check");
 39   if (obj == NULL) {
 40     _handle = NULL;
 41   } else {
 42     _handle = thread->handle_area()->allocate_handle(obj);
 43   }
 44 }
 45 
 46 // Inline constructors for Specific Handles for different oop types
 47 #define DEF_HANDLE_CONSTR(type, is_a)                   \
 48 inline type##Handle::type##Handle (Thread* thread, type##Oop obj) : Handle(thread, (oop)obj) { \
 49   assert(is_null() || ((oop)obj)->is_a(), "illegal type");                \
 50 }
 51 
 52 DEF_HANDLE_CONSTR(instance , is_instance_noinline )
 53 DEF_HANDLE_CONSTR(array    , is_array_noinline    )
 54 DEF_HANDLE_CONSTR(objArray , is_objArray_noinline )
 55 DEF_HANDLE_CONSTR(typeArray, is_typeArray_noinline)
 56 
 57 // Constructor for metadata handles
 58 #define DEF_METADATA_HANDLE_FN(name, type) \
 59 inline name##Handle::name##Handle(Thread* thread, type* obj) : _value(obj), _thread(thread) { \
 60   if (obj != NULL) {                                                   \
 61     assert(((Metadata*)obj)->is_valid(), "obj is valid");              \
 62     assert(_thread == Thread::current(), "thread must be current");    \
 63     assert(_thread->is_in_live_stack((address)this), "not on stack?"); \
 64     _thread->metadata_handles()->push((Metadata*)obj);                 \
 65   }                                                                    \
 66 }                                                                      \
 67 
 68 DEF_METADATA_HANDLE_FN(method, Method)
 69 DEF_METADATA_HANDLE_FN(constantPool, ConstantPool)
 70 
 71 inline void HandleMark::push() {
 72   // This is intentionally a NOP. pop_and_restore will reset
 73   // values to the HandleMark further down the stack, typically
 74   // in JavaCalls::call_helper.
 75   debug_only(_area->_handle_mark_nesting++);
 76 }
 77 
 78 inline void HandleMark::pop_and_restore() {
 79   // Delete later chunks
 80   if(_chunk->next() != NULL) {
 81     assert(_area->size_in_bytes() > size_in_bytes(), "Sanity check");
 82     chop_later_chunks();
 83   } else {
 84     assert(_area->size_in_bytes() == size_in_bytes(), "Sanity check");
 85   }
 86   // Roll back arena to saved top markers
 87   _area->_chunk = _chunk;
 88   _area->_hwm = _hwm;
 89   _area->_max = _max;
 90   debug_only(_area->_handle_mark_nesting--);
 91 }
 92 
 93 inline HandleMarkCleaner::HandleMarkCleaner(Thread* thread) {
 94   _thread = thread;
 95   _thread->last_handle_mark()->push();
 96 }
 97 
 98 inline HandleMarkCleaner::~HandleMarkCleaner() {
 99   _thread->last_handle_mark()->pop_and_restore();
100 }
101 
102 #endif // SHARE_RUNTIME_HANDLES_INLINE_HPP