Merge "Build fix." into dalvik-dev
diff --git a/runtime/native/scoped_fast_native_object_access.h b/runtime/native/scoped_fast_native_object_access.h
new file mode 100644
index 0000000..d941ec3
--- /dev/null
+++ b/runtime/native/scoped_fast_native_object_access.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_
+#define ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_
+
+#include "base/casts.h"
+#include "jni_internal.h"
+#include "thread-inl.h"
+#include "mirror/art_method.h"
+
+namespace art {
+
+// Variant of ScopedObjectAccess that does no runnable transitions. Should only be used by "fast"
+// JNI methods.
+class ScopedFastNativeObjectAccess {
+ public:
+  explicit ScopedFastNativeObjectAccess(JNIEnv* env)
+    LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
+    SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE
+     : env_(down_cast<JNIEnvExt*>(env)), self_(ThreadForEnv(env)) {
+    Locks::mutator_lock_->AssertSharedHeld(Self());
+    DCHECK((*Self()->GetManagedStack()->GetTopQuickFrame())->IsFastNative());
+    // Don't work with raw objects in non-runnable states.
+    DCHECK_EQ(Self()->GetState(), kRunnable);
+  }
+
+  ~ScopedFastNativeObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE {
+  }
+
+  Thread* Self() const {
+    return self_;
+  }
+
+  JNIEnvExt* Env() const {
+    return env_;
+  }
+
+  template<typename T>
+  T Decode(jobject obj) const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    Locks::mutator_lock_->AssertSharedHeld(Self());
+    // Don't work with raw objects in non-runnable states.
+    DCHECK_EQ(Self()->GetState(), kRunnable);
+    return down_cast<T>(Self()->DecodeJObject(obj));
+  }
+
+  mirror::ArtField* DecodeField(jfieldID fid) const
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    Locks::mutator_lock_->AssertSharedHeld(Self());
+    // Don't work with raw objects in non-runnable states.
+    DCHECK_EQ(Self()->GetState(), kRunnable);
+#ifdef MOVING_GARBAGE_COLLECTOR
+    // TODO: we should make these unique weak globals if Field instances can ever move.
+    UNIMPLEMENTED(WARNING);
+#endif
+    return reinterpret_cast<mirror::ArtField*>(fid);
+  }
+
+  /*
+   * Variant of ScopedObjectAccessUnched::AddLocalReference that without JNI work arounds
+   * or check JNI that should be being used by fast native methods.
+   */
+  template<typename T>
+  T AddLocalReference(mirror::Object* obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+    Locks::mutator_lock_->AssertSharedHeld(Self());
+    // Don't work with raw objects in non-runnable states.
+    DCHECK_EQ(Self()->GetState(), kRunnable);
+    if (obj == NULL) {
+      return NULL;
+    }
+
+    DCHECK_NE((reinterpret_cast<uintptr_t>(obj) & 0xffff0000), 0xebad0000);
+
+    IndirectReferenceTable& locals = Env()->locals;
+
+    uint32_t cookie = Env()->local_ref_cookie;
+    IndirectRef ref = locals.Add(cookie, obj);
+
+    return reinterpret_cast<T>(ref);
+  }
+
+ private:
+  JNIEnvExt* const env_;
+  Thread* const self_;
+};
+
+}  // namespace art
+
+#endif  // ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_