handles.inline.hpp revision 5776:de6a9e811145
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
34inline 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
44inline 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// Constructors for metadata handles
55#define DEF_METADATA_HANDLE_FN(name, type) \
56inline name##Handle::name##Handle(type* obj) : _value(obj), _thread(NULL) {       \
57  if (obj != NULL) {                                                   \
58    assert(((Metadata*)obj)->is_valid(), "obj is valid");              \
59    _thread = Thread::current();                                       \
60    assert (_thread->is_in_stack((address)this), "not on stack?");     \
61    _thread->metadata_handles()->push((Metadata*)obj);                 \
62  }                                                                    \
63}                                                                      \
64inline name##Handle::name##Handle(Thread* thread, type* obj) : _value(obj), _thread(thread) { \
65  if (obj != NULL) {                                                   \
66    assert(((Metadata*)obj)->is_valid(), "obj is valid");              \
67    assert(_thread == Thread::current(), "thread must be current");    \
68    assert (_thread->is_in_stack((address)this), "not on stack?");     \
69    _thread->metadata_handles()->push((Metadata*)obj);                 \
70  }                                                                    \
71}                                                                      \
72inline name##Handle::name##Handle(const name##Handle &h) {             \
73  _value = h._value;                                                   \
74  if (_value != NULL) {                                                \
75    assert(_value->is_valid(), "obj is valid");                        \
76    if (h._thread != NULL) {                                           \
77      assert(h._thread == Thread::current(), "thread must be current");\
78      _thread = h._thread;                                             \
79    } else {                                                           \
80      _thread = Thread::current();                                     \
81    }                                                                  \
82    assert (_thread->is_in_stack((address)this), "not on stack?");     \
83    _thread->metadata_handles()->push((Metadata*)_value);              \
84  } else {                                                             \
85    _thread = NULL;                                                    \
86  }                                                                    \
87}                                                                      \
88inline name##Handle& name##Handle::operator=(const name##Handle &s) {  \
89  remove();                                                            \
90  _value = s._value;                                                   \
91  if (_value != NULL) {                                                \
92    assert(_value->is_valid(), "obj is valid");                        \
93    if (s._thread != NULL) {                                           \
94      assert(s._thread == Thread::current(), "thread must be current");\
95      _thread = s._thread;                                             \
96    } else {                                                           \
97      _thread = Thread::current();                                     \
98    }                                                                  \
99    assert (_thread->is_in_stack((address)this), "not on stack?");     \
100    _thread->metadata_handles()->push((Metadata*)_value);              \
101  } else {                                                             \
102    _thread = NULL;                                                    \
103  }                                                                    \
104  return *this;                                                        \
105}                                                                      \
106inline void name##Handle::remove() {                                   \
107  if (_value != NULL) {                                                \
108    int i = _thread->metadata_handles()->find_from_end((Metadata*)_value); \
109    assert(i!=-1, "not in metadata_handles list");                     \
110    _thread->metadata_handles()->remove_at(i);                         \
111  }                                                                    \
112}                                                                      \
113inline name##Handle::~name##Handle () { remove(); }                    \
114
115DEF_METADATA_HANDLE_FN(method, Method)
116DEF_METADATA_HANDLE_FN(constantPool, ConstantPool)
117
118inline HandleMark::HandleMark() {
119  initialize(Thread::current());
120}
121
122
123inline void HandleMark::push() {
124  // This is intentionally a NOP. pop_and_restore will reset
125  // values to the HandleMark further down the stack, typically
126  // in JavaCalls::call_helper.
127  debug_only(_area->_handle_mark_nesting++);
128}
129
130inline void HandleMark::pop_and_restore() {
131  HandleArea* area = _area;   // help compilers with poor alias analysis
132  // Delete later chunks
133  if( _chunk->next() ) {
134    // reset arena size before delete chunks. Otherwise, the total
135    // arena size could exceed total chunk size
136    assert(area->size_in_bytes() > size_in_bytes(), "Sanity check");
137    area->set_size_in_bytes(size_in_bytes());
138    _chunk->next_chop();
139  } else {
140    assert(area->size_in_bytes() == size_in_bytes(), "Sanity check");
141  }
142  // Roll back arena to saved top markers
143  area->_chunk = _chunk;
144  area->_hwm = _hwm;
145  area->_max = _max;
146  debug_only(area->_handle_mark_nesting--);
147}
148
149#endif // SHARE_VM_RUNTIME_HANDLES_INLINE_HPP
150