handles.inline.hpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 1998, 2012, 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#ifdef TARGET_OS_FAMILY_linux
30# include "thread_linux.inline.hpp"
31#endif
32#ifdef TARGET_OS_FAMILY_solaris
33# include "thread_solaris.inline.hpp"
34#endif
35#ifdef TARGET_OS_FAMILY_windows
36# include "thread_windows.inline.hpp"
37#endif
38#ifdef TARGET_OS_FAMILY_bsd
39# include "thread_bsd.inline.hpp"
40#endif
41
42// these inline functions are in a separate file to break an include cycle
43// between Thread and Handle
44
45inline Handle::Handle(oop obj) {
46  if (obj == NULL) {
47    _handle = NULL;
48  } else {
49    _handle = Thread::current()->handle_area()->allocate_handle(obj);
50  }
51}
52
53
54#ifndef ASSERT
55inline Handle::Handle(Thread* thread, oop obj) {
56  assert(thread == Thread::current(), "sanity check");
57  if (obj == NULL) {
58    _handle = NULL;
59  } else {
60    _handle = thread->handle_area()->allocate_handle(obj);
61  }
62}
63#endif // ASSERT
64
65// Constructors for metadata handles
66#define DEF_METADATA_HANDLE_FN(name, type) \
67inline name##Handle::name##Handle(type* obj) : _value(obj), _thread(NULL) {       \
68  if (obj != NULL) {                                                   \
69    assert(((Metadata*)obj)->is_valid(), "obj is valid");              \
70    _thread = Thread::current();                                       \
71    assert (_thread->is_in_stack((address)this), "not on stack?");     \
72    _thread->metadata_handles()->push((Metadata*)obj);                 \
73  }                                                                    \
74}                                                                      \
75inline name##Handle::name##Handle(Thread* thread, type* obj) : _value(obj), _thread(thread) { \
76  if (obj != NULL) {                                                   \
77    assert(((Metadata*)obj)->is_valid(), "obj is valid");              \
78    assert(_thread == Thread::current(), "thread must be current");    \
79    assert (_thread->is_in_stack((address)this), "not on stack?");     \
80    _thread->metadata_handles()->push((Metadata*)obj);                 \
81  }                                                                    \
82}                                                                      \
83inline name##Handle::name##Handle(const name##Handle &h) {             \
84  _value = h._value;                                                   \
85  if (_value != NULL) {                                                \
86    assert(_value->is_valid(), "obj is valid");                        \
87    if (h._thread != NULL) {                                           \
88      assert(h._thread == Thread::current(), "thread must be current");\
89      _thread = h._thread;                                             \
90    } else {                                                           \
91      _thread = Thread::current();                                     \
92    }                                                                  \
93    _thread->metadata_handles()->push((Metadata*)_value);              \
94  }                                                                    \
95}                                                                      \
96inline name##Handle& name##Handle::operator=(const name##Handle &s) {  \
97  remove();                                                            \
98  _value = s._value;                                                   \
99  if (_value != NULL) {                                                \
100    assert(_value->is_valid(), "obj is valid");                        \
101    if (s._thread != NULL) {                                           \
102      assert(s._thread == Thread::current(), "thread must be current");\
103      _thread = s._thread;                                             \
104    } else {                                                           \
105      _thread = Thread::current();                                     \
106    }                                                                  \
107    _thread->metadata_handles()->push((Metadata*)_value);              \
108  }                                                                    \
109  return *this;                                                        \
110}                                                                      \
111inline void name##Handle::remove() {                                   \
112  if (_value != NULL) {                                                \
113    int i = _thread->metadata_handles()->find_from_end((Metadata*)_value); \
114    assert(i!=-1, "not in metadata_handles list");                     \
115    _thread->metadata_handles()->remove_at(i);                         \
116  }                                                                    \
117}                                                                      \
118inline name##Handle::~name##Handle () { remove(); }                    \
119
120DEF_METADATA_HANDLE_FN(method, Method)
121DEF_METADATA_HANDLE_FN(constantPool, ConstantPool)
122
123inline HandleMark::HandleMark() {
124  initialize(Thread::current());
125}
126
127
128inline void HandleMark::push() {
129  // This is intentionally a NOP. pop_and_restore will reset
130  // values to the HandleMark further down the stack, typically
131  // in JavaCalls::call_helper.
132  debug_only(_area->_handle_mark_nesting++);
133}
134
135inline void HandleMark::pop_and_restore() {
136  HandleArea* area = _area;   // help compilers with poor alias analysis
137  // Delete later chunks
138  if( _chunk->next() ) {
139    _chunk->next_chop();
140  }
141  // Roll back arena to saved top markers
142  area->_chunk = _chunk;
143  area->_hwm = _hwm;
144  area->_max = _max;
145  area->set_size_in_bytes(_size_in_bytes);
146  debug_only(area->_handle_mark_nesting--);
147}
148
149#endif // SHARE_VM_RUNTIME_HANDLES_INLINE_HPP
150