scoped_fast_native_object_access.h revision c645f1ddb7c40bea6a38eda4b3f83f6b6dec405b
1/* 2 * Copyright (C) 2013 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_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_ 18#define ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_ 19 20#include "base/casts.h" 21#include "jni_internal.h" 22#include "thread-inl.h" 23#include "mirror/art_method.h" 24#include "verify_object.h" 25 26namespace art { 27 28// Variant of ScopedObjectAccess that does no runnable transitions. Should only be used by "fast" 29// JNI methods. 30class ScopedFastNativeObjectAccess { 31 public: 32 explicit ScopedFastNativeObjectAccess(JNIEnv* env) 33 LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_) 34 SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE 35 : env_(down_cast<JNIEnvExt*>(env)), self_(ThreadForEnv(env)) { 36 Locks::mutator_lock_->AssertSharedHeld(Self()); 37 DCHECK((*Self()->GetManagedStack()->GetTopQuickFrame())->IsFastNative()); 38 // Don't work with raw objects in non-runnable states. 39 DCHECK_EQ(Self()->GetState(), kRunnable); 40 } 41 42 ~ScopedFastNativeObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE { 43 } 44 45 Thread* Self() const { 46 return self_; 47 } 48 49 JNIEnvExt* Env() const { 50 return env_; 51 } 52 53 template<typename T> 54 T Decode(jobject obj) const 55 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 56 Locks::mutator_lock_->AssertSharedHeld(Self()); 57 // Don't work with raw objects in non-runnable states. 58 DCHECK_EQ(Self()->GetState(), kRunnable); 59 return down_cast<T>(Self()->DecodeJObject(obj)); 60 } 61 62 mirror::ArtField* DecodeField(jfieldID fid) const 63 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 64 Locks::mutator_lock_->AssertSharedHeld(Self()); 65 // Don't work with raw objects in non-runnable states. 66 DCHECK_EQ(Self()->GetState(), kRunnable); 67 return reinterpret_cast<mirror::ArtField*>(fid); 68 } 69 70 /* 71 * Variant of ScopedObjectAccessUnched::AddLocalReference that without JNI work arounds 72 * or check JNI that should be being used by fast native methods. 73 */ 74 template<typename T> 75 T AddLocalReference(mirror::Object* obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 76 Locks::mutator_lock_->AssertSharedHeld(Self()); 77 // Don't work with raw objects in non-runnable states. 78 DCHECK_EQ(Self()->GetState(), kRunnable); 79 if (obj == NULL) { 80 return NULL; 81 } 82 83 DCHECK_NE((reinterpret_cast<uintptr_t>(obj) & 0xffff0000), 0xebad0000); 84 85 IndirectReferenceTable& locals = Env()->locals; 86 87 uint32_t cookie = Env()->local_ref_cookie; 88 IndirectRef ref = locals.Add(cookie, obj); 89 90 return reinterpret_cast<T>(ref); 91 } 92 93 private: 94 JNIEnvExt* const env_; 95 Thread* const self_; 96}; 97 98} // namespace art 99 100#endif // ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_ 101