blob: c4e92851e29e8a5ea50348ae26afdc195670a634 [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 Chartiere09ae092014-05-15 12:39:19 -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 Chartiere09ae092014-05-15 12:39:19 -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 Chartiere09ae092014-05-15 12:39:19 -070076 private:
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070077 template<class S> friend class Handle;
78 friend class HandleScope;
79 template<class S> friend class HandleWrapper;
80 template<size_t kNumReferences> friend class StackHandleScope;
81};
82
Mathieu Chartiere09ae092014-05-15 12:39:19 -070083template<class T>
84class NullHandle : public Handle<T> {
85 public:
86 NullHandle() : Handle<T>(&null_ref_) {
87 }
88
89 private:
90 StackReference<T> null_ref_;
91};
92
Mathieu Chartiereb8167a2014-05-07 15:43:14 -070093} // namespace art
94
95#endif // ART_RUNTIME_HANDLE_H_