blob: b70f6510a470945481eb9642d6c481b31b353ccf [file] [log] [blame]
Mathieu Chartiereb8167a2014-05-07 15:43:14 -07001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_HANDLE_H_
18#define ART_RUNTIME_HANDLE_H_
19
20#include "base/casts.h"
21#include "base/logging.h"
22#include "base/macros.h"
23#include "stack.h"
24
25namespace art {
26
27class Thread;
28
29template<class T>
30class Handle {
31 public:
32 Handle() : reference_(nullptr) {
33 }
34 Handle(const Handle<T>& handle) ALWAYS_INLINE : reference_(handle.reference_) {
35 }
36 Handle<T>& operator=(const Handle<T>& handle) ALWAYS_INLINE {
37 reference_ = handle.reference_;
38 return *this;
39 }
40 explicit Handle(StackReference<T>* reference) ALWAYS_INLINE : reference_(reference) {
41 }
42 T& operator*() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
43 return *Get();
44 }
45 T* operator->() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
46 return Get();
47 }
48 T* Get() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
49 return reference_->AsMirrorPtr();
50 }
51 T* Assign(T* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
52 T* old = reference_->AsMirrorPtr();
53 reference_->Assign(reference);
54 return old;
55 }
Mathieu Chartier0cd81352014-05-22 16:48:55 -070056 jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
57 if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
58 // Special case so that we work with NullHandles.
59 return nullptr;
60 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070061 return reinterpret_cast<jobject>(reference_);
62 }
63
Mathieu Chartier0cd81352014-05-22 16:48:55 -070064 protected:
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070065 StackReference<T>* reference_;
66
67 template<typename S>
68 explicit Handle(StackReference<S>* reference)
69 : reference_(reinterpret_cast<StackReference<T>*>(reference)) {
70 }
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070071 template<typename S>
72 explicit Handle(const Handle<S>& handle)
73 : reference_(reinterpret_cast<StackReference<T>*>(handle.reference_)) {
74 }
75
Mathieu Chartier0cd81352014-05-22 16:48:55 -070076 StackReference<T>* GetReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
77 return reference_;
78 }
79
80 private:
81 friend class BuildGenericJniFrameVisitor;
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070082 template<class S> friend class Handle;
83 friend class HandleScope;
84 template<class S> friend class HandleWrapper;
85 template<size_t kNumReferences> friend class StackHandleScope;
86};
87
Mathieu Chartier0cd81352014-05-22 16:48:55 -070088template<class T>
89class NullHandle : public Handle<T> {
90 public:
91 NullHandle() : Handle<T>(&null_ref_) {
92 }
93
94 private:
95 StackReference<T> null_ref_;
96};
97
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070098} // namespace art
99
100#endif // ART_RUNTIME_HANDLE_H_