diff options
author | Mathieu Chartier <mathieuc@google.com> | 2014-05-21 17:43:44 -0700 |
---|---|---|
committer | Mathieu Chartier <mathieuc@google.com> | 2014-06-09 12:46:32 -0700 |
commit | bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9fe (patch) | |
tree | 3d3f667c8232a9c1bb6fe9daea0d364f9ae01d8c /runtime/handle.h | |
parent | 2e1ca953c7fb165da36cc26ea74d3045d7e272c8 (diff) | |
download | art-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.h | 66 |
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; |