summaryrefslogtreecommitdiffstats
path: root/runtime/handle.h
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-05-21 17:43:44 -0700
committerMathieu Chartier <mathieuc@google.com>2014-06-09 12:46:32 -0700
commitbfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe (patch)
tree3d3f667c8232a9c1bb6fe9daea0d364f9ae01d8c /runtime/handle.h
parent2e1ca953c7fb165da36cc26ea74d3045d7e272c8 (diff)
downloadart-bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe.tar.gz
art-bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe.tar.bz2
art-bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe.zip
Change MethodHelper to use a Handle.
Added ConstHandle to help prevent errors where you modify the value stored in the handle of the caller. Also fixed compaction bugs related to not knowing MethodHelper::GetReturnType can resolve types. This bug was present in interpreter RETURN_OBJECT. Bug: 13077697 Change-Id: I71f964d4d810ab4debda1a09bc968af8f3c874a3
Diffstat (limited to 'runtime/handle.h')
-rw-r--r--runtime/handle.h66
1 files changed, 54 insertions, 12 deletions
diff --git a/runtime/handle.h b/runtime/handle.h
index b70f6510a4..7e13601af9 100644
--- a/runtime/handle.h
+++ b/runtime/handle.h
@@ -26,18 +26,20 @@ namespace art {
class Thread;
+template<class T> class Handle;
+
template<class T>
-class Handle {
+class ConstHandle {
public:
- Handle() : reference_(nullptr) {
+ ConstHandle() : reference_(nullptr) {
}
- Handle(const Handle<T>& handle) ALWAYS_INLINE : reference_(handle.reference_) {
+ ConstHandle(const ConstHandle<T>& handle) ALWAYS_INLINE : reference_(handle.reference_) {
}
- Handle<T>& operator=(const Handle<T>& handle) ALWAYS_INLINE {
+ ConstHandle<T>& operator=(const ConstHandle<T>& handle) ALWAYS_INLINE {
reference_ = handle.reference_;
return *this;
}
- explicit Handle(StackReference<T>* reference) ALWAYS_INLINE : reference_(reference) {
+ explicit ConstHandle(StackReference<T>* reference) ALWAYS_INLINE : reference_(reference) {
}
T& operator*() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
return *Get();
@@ -48,11 +50,6 @@ class Handle {
T* Get() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
return reference_->AsMirrorPtr();
}
- T* Assign(T* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
- T* old = reference_->AsMirrorPtr();
- reference_->Assign(reference);
- return old;
- }
jobject ToJObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
if (UNLIKELY(reference_->AsMirrorPtr() == nullptr)) {
// Special case so that we work with NullHandles.
@@ -65,17 +62,62 @@ class Handle {
StackReference<T>* reference_;
template<typename S>
- explicit Handle(StackReference<S>* reference)
+ explicit ConstHandle(StackReference<S>* reference)
: reference_(reinterpret_cast<StackReference<T>*>(reference)) {
}
template<typename S>
- explicit Handle(const Handle<S>& handle)
+ explicit ConstHandle(const ConstHandle<S>& handle)
: reference_(reinterpret_cast<StackReference<T>*>(handle.reference_)) {
}
StackReference<T>* GetReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
return reference_;
}
+ const StackReference<T>* GetReference() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ ALWAYS_INLINE {
+ return reference_;
+ }
+
+ private:
+ friend class BuildGenericJniFrameVisitor;
+ template<class S> friend class ConstHandle;
+ friend class HandleScope;
+ template<class S> friend class HandleWrapper;
+ template<size_t kNumReferences> friend class StackHandleScope;
+};
+
+template<class T>
+class Handle : public ConstHandle<T> {
+ public:
+ Handle() {
+ }
+ Handle(const Handle<T>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE
+ : ConstHandle<T>(handle.reference_) {
+ }
+ Handle<T>& operator=(const Handle<T>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ ALWAYS_INLINE {
+ ConstHandle<T>::operator=(handle);
+ return *this;
+ }
+ explicit Handle(StackReference<T>* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ ALWAYS_INLINE : ConstHandle<T>(reference) {
+ }
+ T* Assign(T* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE {
+ StackReference<T>* ref = ConstHandle<T>::GetReference();
+ T* const old = ref->AsMirrorPtr();
+ ref->Assign(reference);
+ return old;
+ }
+
+ protected:
+ template<typename S>
+ explicit Handle(StackReference<S>* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : ConstHandle<T>(reference) {
+ }
+ template<typename S>
+ explicit Handle(const Handle<S>& handle) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ : ConstHandle<T>(handle) {
+ }
private:
friend class BuildGenericJniFrameVisitor;