Revert "Support using opaque JNI ids"
This reverts commit 21d5994583c679cd5d8573b5d35dbd659bdca2c7.
Bug: 134162467
Reason for revert: Breaks debuggable
Change-Id: I9510a6ac208d392ff25ee196a1a519fecd151445
diff --git a/runtime/Android.bp b/runtime/Android.bp
index db4ef02..6b691fd 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -121,7 +121,6 @@
"jni/check_jni.cc",
"jni/java_vm_ext.cc",
"jni/jni_env_ext.cc",
- "jni/jni_id_manager.cc",
"jni/jni_internal.cc",
"linear_alloc.cc",
"managed_stack.cc",
@@ -480,7 +479,6 @@
"jdwp_provider.h",
"jdwp/jdwp.h",
"jdwp/jdwp_constants.h",
- "jni_id_type.h",
"lock_word.h",
"oat.h",
"object_callbacks.h",
diff --git a/runtime/base/locks.cc b/runtime/base/locks.cc
index 7404d0d..1cec44c 100644
--- a/runtime/base/locks.cc
+++ b/runtime/base/locks.cc
@@ -76,7 +76,6 @@
Mutex* Locks::jni_weak_globals_lock_ = nullptr;
ReaderWriterMutex* Locks::dex_lock_ = nullptr;
Mutex* Locks::native_debug_interface_lock_ = nullptr;
-ReaderWriterMutex* Locks::jni_id_lock_ = nullptr;
std::vector<BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_;
Atomic<const BaseMutex*> Locks::expected_mutexes_on_weak_ref_access_guard_;
@@ -158,7 +157,6 @@
DCHECK(user_code_suspension_lock_ != nullptr);
DCHECK(dex_lock_ != nullptr);
DCHECK(native_debug_interface_lock_ != nullptr);
- DCHECK(jni_id_lock_ != nullptr);
DCHECK(runtime_thread_pool_lock_ != nullptr);
} else {
// Create global locks in level order from highest lock level to lowest.
@@ -319,10 +317,6 @@
DCHECK(native_debug_interface_lock_ == nullptr);
native_debug_interface_lock_ = new Mutex("Native debug interface lock", current_lock_level);
- UPDATE_CURRENT_LOCK_LEVEL(kJniIdLock);
- DCHECK(jni_id_lock_ == nullptr);
- jni_id_lock_ = new ReaderWriterMutex("JNI id map lock", current_lock_level);
-
UPDATE_CURRENT_LOCK_LEVEL(kAbortLock);
DCHECK(abort_lock_ == nullptr);
abort_lock_ = new Mutex("abort lock", current_lock_level, true);
diff --git a/runtime/base/locks.h b/runtime/base/locks.h
index 4b85df0..77e304d 100644
--- a/runtime/base/locks.h
+++ b/runtime/base/locks.h
@@ -45,7 +45,6 @@
kUnexpectedSignalLock,
kThreadSuspendCountLock,
kAbortLock,
- kJniIdLock,
kNativeDebugInterfaceLock,
kSignalHandlingLock,
// A generic lock level for mutexs that should not allow any additional mutexes to be gained after
@@ -354,12 +353,8 @@
// Guards the magic global variables used by native tools (e.g. libunwind).
static Mutex* native_debug_interface_lock_ ACQUIRED_AFTER(unexpected_signal_lock_);
- // Guards the data structures responsible for keeping track of the JNI
- // jmethodID/jfieldID <-> ArtMethod/ArtField mapping when using index-ids.
- static ReaderWriterMutex* jni_id_lock_ ACQUIRED_AFTER(native_debug_interface_lock_);
-
// Have an exclusive logging thread.
- static Mutex* logging_lock_ ACQUIRED_AFTER(jni_id_lock_);
+ static Mutex* logging_lock_ ACQUIRED_AFTER(native_debug_interface_lock_);
// List of mutexes that we expect a thread may hold when accessing weak refs. This is used to
// avoid a deadlock in the empty checkpoint while weak ref access is disabled (b/34964016). If we
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 0ffbc4a..2a7cbaa 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -610,8 +610,6 @@
struct ClassExtOffsets : public CheckOffsets<mirror::ClassExt> {
ClassExtOffsets() : CheckOffsets<mirror::ClassExt>(false, "Ldalvik/system/ClassExt;") {
- addOffset(OFFSETOF_MEMBER(mirror::ClassExt, instance_jfield_ids_), "instanceJfieldIDs");
- addOffset(OFFSETOF_MEMBER(mirror::ClassExt, jmethod_ids_), "jmethodIDs");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, obsolete_dex_caches_), "obsoleteDexCaches");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, obsolete_methods_), "obsoleteMethods");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, original_dex_file_), "originalDexFile");
@@ -619,7 +617,6 @@
"preRedefineClassDefIndex");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, pre_redefine_dex_file_ptr_),
"preRedefineDexFilePtr");
- addOffset(OFFSETOF_MEMBER(mirror::ClassExt, static_jfield_ids_), "staticJfieldIDs");
addOffset(OFFSETOF_MEMBER(mirror::ClassExt, verify_error_), "verifyError");
}
};
diff --git a/runtime/jni/jni_env_ext.h b/runtime/jni/jni_env_ext.h
index 924ff51..61de074 100644
--- a/runtime/jni/jni_env_ext.h
+++ b/runtime/jni/jni_env_ext.h
@@ -199,7 +199,7 @@
// If we are a JNI env for a daemon thread with a deleted runtime.
bool runtime_deleted_;
- template<bool kEnableIndexIds> friend class JNI;
+ friend class JNI;
friend class ScopedJniEnvLocalRefState;
friend class Thread;
ART_FRIEND_TEST(JniInternalTest, JNIEnvExtOffsets);
diff --git a/runtime/jni/jni_id_manager.cc b/runtime/jni/jni_id_manager.cc
deleted file mode 100644
index 16f4d5f..0000000
--- a/runtime/jni/jni_id_manager.cc
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include "jni_id_manager.h"
-
-#include "android-base/macros.h"
-#include "art_field-inl.h"
-#include "art_method-inl.h"
-#include "base/enums.h"
-#include "base/globals.h"
-#include "base/locks.h"
-#include "base/mutex.h"
-#include "gc/allocation_listener.h"
-#include "gc/heap.h"
-#include "jni/jni_internal.h"
-#include "mirror/array-inl.h"
-#include "mirror/class-inl.h"
-#include "mirror/class.h"
-#include "mirror/class_ext.h"
-#include "mirror/object-inl.h"
-#include "obj_ptr-inl.h"
-#include "thread-inl.h"
-#include "thread.h"
-#include <algorithm>
-#include <cstdint>
-#include <type_traits>
-
-namespace art {
-namespace jni {
-
-constexpr bool kTraceIds = false;
-
-// TODO This whole thing could be done lock & wait free (since we never remove anything from the
-// ids list). It's not clear this would be worthwile though.
-
-namespace {
-
-static constexpr size_t IdToIndex(uintptr_t id) {
- return id >> 1;
-}
-
-static constexpr uintptr_t IndexToId(size_t index) {
- return (index << 1) + 1;
-}
-
-template <typename ArtType>
-ObjPtr<mirror::PointerArray> GetOrCreateIds(Thread* self,
- ObjPtr<mirror::Class> k,
- ArtType* t,
- /*out*/bool* allocation_failure)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
-template <>
-ObjPtr<mirror::PointerArray> GetOrCreateIds(Thread* self,
- ObjPtr<mirror::Class> k,
- ArtField* field,
- /*out*/bool* allocation_failure) {
- ScopedExceptionStorage ses(self);
- ObjPtr<mirror::PointerArray> res;
- if (Locks::mutator_lock_->IsExclusiveHeld(self)) {
- res = field->IsStatic() ? k->GetStaticFieldIds() : k->GetInstanceFieldIds();
- } else {
- res = field->IsStatic() ? k->GetOrCreateStaticFieldIds() : k->GetOrCreateInstanceFieldIds();
- }
- if (self->IsExceptionPending()) {
- self->AssertPendingOOMException();
- ses.SuppressOldException("Failed to allocate maps for jmethodIDs. ");
- *allocation_failure = true;
- } else {
- *allocation_failure = false;
- }
- return res;
-}
-
-template <>
-ObjPtr<mirror::PointerArray> GetOrCreateIds(Thread* self,
- ObjPtr<mirror::Class> k,
- ArtMethod* method,
- /*out*/bool* allocation_failure) {
- if (method->IsObsolete()) {
- if (kTraceIds) {
- LOG(INFO) << "jmethodID for Obsolete method " << method->PrettyMethod() << " requested!";
- }
- // No ids array for obsolete methods. Just do a linear scan.
- *allocation_failure = false;
- return nullptr;
- }
- ObjPtr<mirror::PointerArray> res;
- if (Locks::mutator_lock_->IsExclusiveHeld(self) || !Locks::mutator_lock_->IsSharedHeld(self)) {
- res = k->GetMethodIds();
- } else {
- res = k->GetOrCreateMethodIds();
- }
- if (self->IsExceptionPending()) {
- self->AssertPendingOOMException();
- *allocation_failure = true;
- } else {
- *allocation_failure = false;
- }
- return res;
-}
-
-template <typename ArtType>
-size_t GetIdOffset(ObjPtr<mirror::Class> k, ArtType* t, PointerSize pointer_size)
- REQUIRES_SHARED(Locks::mutator_lock_);
-template <>
-size_t GetIdOffset(ObjPtr<mirror::Class> k, ArtField* f, PointerSize ptr_size ATTRIBUTE_UNUSED) {
- return f->IsStatic() ? k->GetStaticFieldIdOffset(f) : k->GetInstanceFieldIdOffset(f);
-}
-template <>
-size_t GetIdOffset(ObjPtr<mirror::Class> k, ArtMethod* method, PointerSize pointer_size) {
- return method->IsObsolete() ? -1 : k->GetMethodIdOffset(method, pointer_size);
-}
-
-// Calls the relevant PrettyMethod/PrettyField on the input.
-template <typename ArtType>
-std::string PrettyGeneric(ArtType* t) REQUIRES_SHARED(Locks::mutator_lock_);
-template <> std::string PrettyGeneric(ArtMethod* f) {
- return f->PrettyMethod();
-}
-template <> std::string PrettyGeneric(ArtField* f) {
- return f->PrettyField();
-}
-
-// Checks if the field or method is obsolete.
-template <typename ArtType> bool IsObsolete(ArtType* t) REQUIRES_SHARED(Locks::mutator_lock_);
-template <> bool IsObsolete(ArtField* t ATTRIBUTE_UNUSED) {
- return false;
-}
-template <> bool IsObsolete(ArtMethod* t) {
- return t->IsObsolete();
-}
-
-// Get the canonical (non-copied) version of the field or method. Only relevant for methods.
-template <typename ArtType> ArtType* Canonicalize(ArtType* t) REQUIRES_SHARED(Locks::mutator_lock_);
-template <> ArtField* Canonicalize(ArtField* t) {
- return t;
-}
-template <> ArtMethod* Canonicalize(ArtMethod* t) {
- if (UNLIKELY(t->IsCopied())) {
- t = t->GetCanonicalMethod();
- }
- return t;
-}
-
-}; // namespace
-
-// We increment the id by 2 each time to allow us to use the LSB as a flag that the ID is an index
-// and not a pointer. This gives us 2**31 unique methods that can be addressed on 32-bit art, which
-// should be more than enough.
-template <> uintptr_t JniIdManager::GetNextId<ArtField>() {
- uintptr_t res = next_field_id_;
- next_field_id_ += 2;
- CHECK_GT(next_field_id_, res) << "jfieldID Overflow";
- return res;
-}
-
-template <> uintptr_t JniIdManager::GetNextId<ArtMethod>() {
- uintptr_t res = next_method_id_;
- next_method_id_ += 2;
- CHECK_GT(next_method_id_, res) << "jmethodID Overflow";
- return res;
-}
-template <> std::vector<ArtField*>& JniIdManager::GetGenericMap<ArtField>() {
- return field_id_map_;
-}
-
-template <> std::vector<ArtMethod*>& JniIdManager::GetGenericMap<ArtMethod>() {
- return method_id_map_;
-}
-template <> size_t JniIdManager::GetLinearSearchStartId<ArtField>(ArtField* t ATTRIBUTE_UNUSED) {
- return deferred_allocation_field_id_start_;
-}
-
-template <> size_t JniIdManager::GetLinearSearchStartId<ArtMethod>(ArtMethod* m) {
- if (m->IsObsolete()) {
- return 1;
- } else {
- return deferred_allocation_method_id_start_;
- }
-}
-
-template <typename ArtType> uintptr_t JniIdManager::EncodeGenericId(ArtType* t) {
- if (!Runtime::Current()->JniIdsAreIndices() || t == nullptr) {
- return reinterpret_cast<uintptr_t>(t);
- }
- Thread* self = Thread::Current();
- ScopedExceptionStorage ses(self);
- t = Canonicalize(t);
- ObjPtr<mirror::Class> klass = t->GetDeclaringClass();
- DCHECK(!klass.IsNull()) << "Null declaring class " << PrettyGeneric(t);
- size_t off = GetIdOffset(klass, t, kRuntimePointerSize);
- bool allocation_failure = false;
- ObjPtr<mirror::PointerArray> ids(GetOrCreateIds(self, klass, t, &allocation_failure));
- if (allocation_failure) {
- self->AssertPendingOOMException();
- ses.SuppressOldException("OOM exception while trying to allocate JNI ids.");
- return 0u;
- }
- uintptr_t cur_id = 0;
- if (!ids.IsNull()) {
- DCHECK_GT(ids->GetLength(), static_cast<int32_t>(off)) << " is " << PrettyGeneric(t);
- cur_id = ids->GetElementPtrSize<uintptr_t>(off, kRuntimePointerSize);
- }
- if (cur_id != 0) {
- return cur_id;
- }
- WriterMutexLock mu(self, *Locks::jni_id_lock_);
- // Check the ids array for a racing id.
- if (!ids.IsNull()) {
- cur_id = ids->GetElementPtrSize<uintptr_t>(off, kRuntimePointerSize);
- if (cur_id != 0) {
- // We were racing some other thread and lost.
- return cur_id;
- }
- } else {
- // We cannot allocate anything here or don't have an ids array (we might be an obsolete method).
- DCHECK(IsObsolete(t) || deferred_allocation_refcount_ > 0u)
- << "deferred_allocation_refcount_: " << deferred_allocation_refcount_
- << " t: " << PrettyGeneric(t);
- // Check to see if we raced and lost to another thread.
- const std::vector<ArtType*>& vec = GetGenericMap<ArtType>();
- bool found = false;
- // simple count-while.
- size_t search_start_index = IdToIndex(GetLinearSearchStartId(t));
- size_t index = std::count_if(vec.cbegin() + search_start_index,
- vec.cend(),
- [&found, t](const ArtType* candidate) {
- found = found || candidate == t;
- return !found;
- }) +
- search_start_index;
- if (found) {
- // We were either racing some other thread and lost or this thread was asked to encode the
- // same method multiple times while holding the mutator lock.
- DCHECK_EQ(vec[index], t) << "Expected: " << PrettyGeneric(vec[index]) << " got "
- << PrettyGeneric(t) << " at index " << index
- << " (id: " << IndexToId(index) << ").";
- return IndexToId(index);
- }
- }
- cur_id = GetNextId<ArtType>();
- size_t cur_index = IdToIndex(cur_id);
- std::vector<ArtType*>& vec = GetGenericMap<ArtType>();
- vec.reserve(cur_index + 1);
- vec.resize(std::max(vec.size(), cur_index + 1), nullptr);
- vec[cur_index] = t;
- if (ids.IsNull()) {
- if (kIsDebugBuild && !IsObsolete(t)) {
- CHECK_NE(deferred_allocation_refcount_, 0u)
- << "Failed to allocate ids array despite not being forbidden from doing so!";
- Locks::mutator_lock_->AssertExclusiveHeld(self);
- }
- } else {
- ids->SetElementPtrSize(off, reinterpret_cast<void*>(cur_id), kRuntimePointerSize);
- }
- return cur_id;
-}
-
-jfieldID JniIdManager::EncodeFieldId(ArtField* field) {
- auto* res = reinterpret_cast<jfieldID>(EncodeGenericId(field));
- if (kTraceIds && field != nullptr) {
- LOG(INFO) << "Returning " << res << " for field " << field->PrettyField();
- }
- return res;
-}
-jmethodID JniIdManager::EncodeMethodId(ArtMethod* method) {
- auto* res = reinterpret_cast<jmethodID>(EncodeGenericId(method));
- if (kTraceIds && method != nullptr) {
- LOG(INFO) << "Returning " << res << " for method " << method->PrettyMethod();
- }
- return res;
-}
-
-template <typename ArtType> ArtType* JniIdManager::DecodeGenericId(uintptr_t t) {
- if (Runtime::Current()->JniIdsAreIndices() && (t % 2) == 1) {
- ReaderMutexLock mu(Thread::Current(), *Locks::jni_id_lock_);
- size_t index = IdToIndex(t);
- DCHECK_GT(GetGenericMap<ArtType>().size(), index);
- return GetGenericMap<ArtType>().at(index);
- } else {
- DCHECK_EQ((t % 2), 0u) << "id: " << t;
- return reinterpret_cast<ArtType*>(t);
- }
-}
-
-ArtMethod* JniIdManager::DecodeMethodId(jmethodID method) {
- return DecodeGenericId<ArtMethod>(reinterpret_cast<uintptr_t>(method));
-}
-
-ArtField* JniIdManager::DecodeFieldId(jfieldID field) {
- return DecodeGenericId<ArtField>(reinterpret_cast<uintptr_t>(field));
-}
-
-// This whole defer system is an annoying requirement to allow us to generate IDs during heap-walks
-// such as those required for instrumentation tooling.
-//
-// The defer system works with the normal id-assignment routine to ensure that all the class-ext
-// data structures are eventually created and filled in. Basically how it works is the id-assignment
-// function will check to see if it has a strong mutator-lock. If it does not then it will try to
-// allocate the class-ext data structures normally and fail if it is unable to do so. In the case
-// where mutator-lock is being held exclusive no attempt to allocate will be made and the thread
-// will CHECK that allocations are being deferred (or that the method is obsolete, in which case
-// there is no class-ext to store the method->id map in).
-//
-// Once the thread is done holding the exclusive mutator-lock it will go back and fill-in the
-// class-ext data of all the methods that were added. We do this without the exclusive mutator-lock
-// on a copy of the maps before we decrement the deferred refcount. This ensures that any other
-// threads running at the same time know they need to perform a linear scan of the id-map. Since we
-// don't have the mutator-lock anymore other threads can allocate the class-ext data, meaning our
-// copy is fine. The only way additional methods could end up on the id-maps after our copy without
-// having class-ext data is if another thread picked up the exclusive mutator-lock and added another
-// defer, in which case that thread would fix-up the remaining ids. In this way we maintain eventual
-// consistency between the class-ext method/field->id maps and the JniIdManager id->method/field
-// maps.
-//
-// TODO It is possible that another thread to gain the mutator-lock and allocate new ids without
-// calling StartDefer. This is basically a race that we should try to catch but doing so is
-// rather difficult and since this defer system is only used in very rare circumstances unlikely to
-// be worth the trouble.
-void JniIdManager::StartDefer() {
- Thread* self = Thread::Current();
- WriterMutexLock mu(self, *Locks::jni_id_lock_);
- if (deferred_allocation_refcount_++ == 0) {
- deferred_allocation_field_id_start_ = next_field_id_;
- deferred_allocation_method_id_start_ = next_method_id_;
- }
-}
-
-void JniIdManager::EndDefer() {
- // Fixup the method->id map.
- Thread* self = Thread::Current();
- auto set_id = [&](auto* t, uintptr_t id) REQUIRES_SHARED(Locks::mutator_lock_) {
- if (t == nullptr) {
- return;
- }
- ObjPtr<mirror::Class> klass(t->GetDeclaringClass());
- size_t off = GetIdOffset(klass, t, kRuntimePointerSize);
- bool alloc_failure = false;
- ObjPtr<mirror::PointerArray> ids = GetOrCreateIds(self, klass, t, &alloc_failure);
- CHECK(!alloc_failure) << "Could not allocate jni ids array!";
- if (ids.IsNull()) {
- return;
- }
- if (kIsDebugBuild) {
- uintptr_t old_id = ids->GetElementPtrSize<uintptr_t, kRuntimePointerSize>(off);
- if (old_id != 0) {
- DCHECK_EQ(old_id, id);
- }
- }
- ids->SetElementPtrSize(off, reinterpret_cast<void*>(id), kRuntimePointerSize);
- };
- // To ensure eventual consistency this depends on the fact that the method_id_map_ and
- // field_id_map_ are the ultimate source of truth and no id is ever reused to be valid. It also
- // relies on all threads always getting calling StartDefer if they are going to be allocating jni
- // ids while suspended. If a thread tries to do so while it doesn't have a scope we could miss
- // ids.
- // TODO We should use roles or something to verify that this requirement is not broken.
- //
- // If another thread comes along and adds more methods to the list after
- // copying either (1) the id-maps are already present for the method and everything is fine, (2)
- // the thread is not suspended and so can create the ext-data and id lists or, (3) the thread also
- // suspended everything and incremented the deferred_allocation_refcount_ so it will fix up new
- // ids when it finishes.
- Locks::mutator_lock_->AssertNotExclusiveHeld(self);
- Locks::mutator_lock_->AssertSharedHeld(self);
- std::vector<ArtMethod*> method_id_copy;
- std::vector<ArtField*> field_id_copy;
- uintptr_t method_start_id;
- uintptr_t field_start_id;
- {
- ReaderMutexLock mu(self, *Locks::jni_id_lock_);
- method_id_copy = method_id_map_;
- field_id_copy = field_id_map_;
- method_start_id = deferred_allocation_method_id_start_;
- field_start_id = deferred_allocation_field_id_start_;
- }
-
- for (size_t index = kIsDebugBuild ? 0 : IdToIndex(method_start_id); index < method_id_copy.size();
- ++index) {
- set_id(method_id_copy[index], IndexToId(index));
- }
- for (size_t index = kIsDebugBuild ? 0 : IdToIndex(field_start_id); index < field_id_copy.size();
- ++index) {
- set_id(field_id_copy[index], IndexToId(index));
- }
- WriterMutexLock mu(self, *Locks::jni_id_lock_);
- DCHECK_GE(deferred_allocation_refcount_, 1u);
- if (--deferred_allocation_refcount_ == 0) {
- deferred_allocation_field_id_start_ = 0;
- deferred_allocation_method_id_start_ = 0;
- }
-}
-
-ScopedEnableSuspendAllJniIdQueries::ScopedEnableSuspendAllJniIdQueries()
- : manager_(Runtime::Current()->GetJniIdManager()) {
- manager_->StartDefer();
-}
-
-ScopedEnableSuspendAllJniIdQueries::~ScopedEnableSuspendAllJniIdQueries() {
- manager_->EndDefer();
-}
-
-}; // namespace jni
-}; // namespace art
diff --git a/runtime/jni/jni_id_manager.h b/runtime/jni/jni_id_manager.h
deleted file mode 100644
index 5e5c581..0000000
--- a/runtime/jni/jni_id_manager.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2019 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_JNI_JNI_ID_MANAGER_H_
-#define ART_RUNTIME_JNI_JNI_ID_MANAGER_H_
-
-#include <atomic>
-#include <jni.h>
-#include <vector>
-
-#include "art_field.h"
-#include "art_method.h"
-#include "base/mutex.h"
-
-namespace art {
-namespace jni {
-
-class ScopedEnableSuspendAllJniIdQueries;
-class JniIdManager {
- public:
- ArtMethod* DecodeMethodId(jmethodID method) REQUIRES(!Locks::jni_id_lock_);
- ArtField* DecodeFieldId(jfieldID field) REQUIRES(!Locks::jni_id_lock_);
- jmethodID EncodeMethodId(ArtMethod* method) REQUIRES(!Locks::jni_id_lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
- jfieldID EncodeFieldId(ArtField* field) REQUIRES(!Locks::jni_id_lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- private:
- template <typename ArtType>
- uintptr_t EncodeGenericId(ArtType* t) REQUIRES(!Locks::jni_id_lock_)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template <typename ArtType>
- ArtType* DecodeGenericId(uintptr_t input) REQUIRES(!Locks::jni_id_lock_);
- template <typename ArtType> std::vector<ArtType*>& GetGenericMap() REQUIRES(Locks::jni_id_lock_);
- template <typename ArtType> uintptr_t GetNextId() REQUIRES(Locks::jni_id_lock_);
- template <typename ArtType>
- size_t GetLinearSearchStartId(ArtType* t) REQUIRES(Locks::jni_id_lock_);
-
- void StartDefer() REQUIRES(!Locks::jni_id_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
- void EndDefer() REQUIRES(!Locks::jni_id_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
-
- uintptr_t next_method_id_ GUARDED_BY(Locks::jni_id_lock_) = 1u;
- std::vector<ArtMethod*> method_id_map_ GUARDED_BY(Locks::jni_id_lock_);
- uintptr_t next_field_id_ GUARDED_BY(Locks::jni_id_lock_) = 1u;
- std::vector<ArtField*> field_id_map_ GUARDED_BY(Locks::jni_id_lock_);
-
- // If non-zero indicates that some thread is trying to allocate ids without being able to update
- // the method->id mapping (due to not being able to allocate or something). In this case decode
- // and encode need to do a linear scan of the lists. The ScopedEnableSuspendAllJniIdQueries struct
- // will deal with fixing everything up.
- size_t deferred_allocation_refcount_ GUARDED_BY(Locks::jni_id_lock_) = 0;
- // min jmethodID that might not have it's method->id mapping filled in.
- uintptr_t deferred_allocation_method_id_start_ GUARDED_BY(Locks::jni_id_lock_) = 0u;
- // min jfieldID that might not have it's field->id mapping filled in.
- uintptr_t deferred_allocation_field_id_start_ GUARDED_BY(Locks::jni_id_lock_) = 0u;
-
- friend class ScopedEnableSuspendAllJniIdQueries;
-};
-
-// A scope that will enable using the Encode/Decode JNI id functions with all threads suspended.
-// This is required since normally we need to be able to allocate to encode new ids. This should
-// only be used when absolutely required, for example to invoke user-callbacks during heap walking
-// or similar.
-class ScopedEnableSuspendAllJniIdQueries {
- public:
- ScopedEnableSuspendAllJniIdQueries() REQUIRES_SHARED(Locks::mutator_lock_);
- ~ScopedEnableSuspendAllJniIdQueries() REQUIRES_SHARED(Locks::mutator_lock_);
-
- private:
- JniIdManager* manager_;
-};
-
-} // namespace jni
-} // namespace art
-
-#endif // ART_RUNTIME_JNI_JNI_ID_MANAGER_H_
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index cd775d6..af335f6 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -428,7 +428,6 @@
return h_klass.Get();
}
-template<bool kEnableIndexIds>
static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
const char* name, const char* sig, bool is_static)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -450,16 +449,14 @@
ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
return nullptr;
}
- return jni::EncodeArtMethod<kEnableIndexIds>(method);
+ return jni::EncodeArtMethod(method);
}
-template<bool kEnableIndexIds>
static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa)
REQUIRES_SHARED(Locks::mutator_lock_) {
ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
// If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
- if (method ==
- jni::DecodeArtMethod<kEnableIndexIds>(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
+ if (method == jni::DecodeArtMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
}
// If we have a method, use its ClassLoader for context.
@@ -485,7 +482,6 @@
return nullptr;
}
-template<bool kEnableIndexIds>
static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
const char* sig, bool is_static)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -538,7 +534,7 @@
sig, name, c->GetDescriptor(&temp));
return nullptr;
}
- return jni::EncodeArtField<kEnableIndexIds>(field);
+ return jni::EncodeArtField(field);
}
static void ThrowAIOOBE(ScopedObjectAccess& soa,
@@ -645,7 +641,6 @@
return nullptr;
}
-template <bool kEnableIndexIds>
class JNI {
public:
static jint GetVersion(JNIEnv*) {
@@ -666,7 +661,7 @@
ObjPtr<mirror::Class> c = nullptr;
if (runtime->IsStarted()) {
StackHandleScope<1> hs(soa.Self());
- Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader<kEnableIndexIds>(soa)));
+ Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
} else {
c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
@@ -677,7 +672,7 @@
static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
CHECK_NON_NULL_ARGUMENT(jlr_method);
ScopedObjectAccess soa(env);
- return jni::EncodeArtMethod<kEnableIndexIds>(ArtMethod::FromReflectedMethod(soa, jlr_method));
+ return jni::EncodeArtMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
}
static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
@@ -689,7 +684,7 @@
return nullptr;
}
ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(obj_field);
- return jni::EncodeArtField<kEnableIndexIds>(field->GetArtField());
+ return jni::EncodeArtField(field->GetArtField());
}
static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
@@ -940,7 +935,7 @@
}
if (c->IsStringClass()) {
// Replace calls to String.<init> with equivalent StringFactory call.
- jmethodID sf_mid = jni::EncodeArtMethod<kEnableIndexIds>(
+ jmethodID sf_mid = jni::EncodeArtMethod(
WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
}
@@ -967,7 +962,7 @@
}
if (c->IsStringClass()) {
// Replace calls to String.<init> with equivalent StringFactory call.
- jmethodID sf_mid = jni::EncodeArtMethod<kEnableIndexIds>(
+ jmethodID sf_mid = jni::EncodeArtMethod(
WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
}
@@ -988,7 +983,7 @@
CHECK_NON_NULL_ARGUMENT(name);
CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
- return FindMethodID<kEnableIndexIds>(soa, java_class, name, sig, false);
+ return FindMethodID(soa, java_class, name, sig, false);
}
static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
@@ -997,7 +992,7 @@
CHECK_NON_NULL_ARGUMENT(name);
CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
- return FindMethodID<kEnableIndexIds>(soa, java_class, name, sig, true);
+ return FindMethodID(soa, java_class, name, sig, true);
}
static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
@@ -1529,7 +1524,7 @@
CHECK_NON_NULL_ARGUMENT(name);
CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
- return FindFieldID<kEnableIndexIds>(soa, java_class, name, sig, false);
+ return FindFieldID(soa, java_class, name, sig, false);
}
static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
@@ -1538,14 +1533,14 @@
CHECK_NON_NULL_ARGUMENT(name);
CHECK_NON_NULL_ARGUMENT(sig);
ScopedObjectAccess soa(env);
- return FindFieldID<kEnableIndexIds>(soa, java_class, name, sig, true);
+ return FindFieldID(soa, java_class, name, sig, true);
}
static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
CHECK_NON_NULL_ARGUMENT(obj);
CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
+ ArtField* f = jni::DecodeArtField(fid);
NotifyGetField(f, obj);
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj);
return soa.AddLocalReference<jobject>(f->GetObject(o));
@@ -1554,7 +1549,7 @@
static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
+ ArtField* f = jni::DecodeArtField(fid);
NotifyGetField(f, nullptr);
return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
}
@@ -1563,7 +1558,7 @@
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
ScopedObjectAccess soa(env);
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
+ ArtField* f = jni::DecodeArtField(fid);
NotifySetObjectField(f, java_object, java_value);
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
@@ -1573,7 +1568,7 @@
static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
ScopedObjectAccess soa(env);
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid);
+ ArtField* f = jni::DecodeArtField(fid);
NotifySetObjectField(f, nullptr, java_value);
ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
f->SetObject<false>(f->GetDeclaringClass(), v);
@@ -1583,7 +1578,7 @@
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
ScopedObjectAccess soa(env); \
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
+ ArtField* f = jni::DecodeArtField(fid); \
NotifyGetField(f, instance); \
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
return f->Get ##fn (o)
@@ -1591,7 +1586,7 @@
#define GET_STATIC_PRIMITIVE_FIELD(fn) \
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
ScopedObjectAccess soa(env); \
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
+ ArtField* f = jni::DecodeArtField(fid); \
NotifyGetField(f, nullptr); \
return f->Get ##fn (f->GetDeclaringClass())
@@ -1599,7 +1594,7 @@
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
ScopedObjectAccess soa(env); \
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
+ ArtField* f = jni::DecodeArtField(fid); \
NotifySetPrimitiveField(f, instance, JValue::FromPrimitive<decltype(value)>(value)); \
ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
f->Set ##fn <false>(o, value)
@@ -1607,7 +1602,7 @@
#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
ScopedObjectAccess soa(env); \
- ArtField* f = jni::DecodeArtField<kEnableIndexIds>(fid); \
+ ArtField* f = jni::DecodeArtField(fid); \
NotifySetPrimitiveField(f, nullptr, JValue::FromPrimitive<decltype(value)>(value)); \
f->Set ##fn <false>(f->GetDeclaringClass(), value)
@@ -2886,253 +2881,244 @@
}
};
-template<bool kEnableIndexIds>
-struct JniNativeInterfaceFunctions {
- using JNIImpl = JNI<kEnableIndexIds>;
- static constexpr JNINativeInterface gJniNativeInterface = {
- nullptr, // reserved0.
- nullptr, // reserved1.
- nullptr, // reserved2.
- nullptr, // reserved3.
- JNIImpl::GetVersion,
- JNIImpl::DefineClass,
- JNIImpl::FindClass,
- JNIImpl::FromReflectedMethod,
- JNIImpl::FromReflectedField,
- JNIImpl::ToReflectedMethod,
- JNIImpl::GetSuperclass,
- JNIImpl::IsAssignableFrom,
- JNIImpl::ToReflectedField,
- JNIImpl::Throw,
- JNIImpl::ThrowNew,
- JNIImpl::ExceptionOccurred,
- JNIImpl::ExceptionDescribe,
- JNIImpl::ExceptionClear,
- JNIImpl::FatalError,
- JNIImpl::PushLocalFrame,
- JNIImpl::PopLocalFrame,
- JNIImpl::NewGlobalRef,
- JNIImpl::DeleteGlobalRef,
- JNIImpl::DeleteLocalRef,
- JNIImpl::IsSameObject,
- JNIImpl::NewLocalRef,
- JNIImpl::EnsureLocalCapacity,
- JNIImpl::AllocObject,
- JNIImpl::NewObject,
- JNIImpl::NewObjectV,
- JNIImpl::NewObjectA,
- JNIImpl::GetObjectClass,
- JNIImpl::IsInstanceOf,
- JNIImpl::GetMethodID,
- JNIImpl::CallObjectMethod,
- JNIImpl::CallObjectMethodV,
- JNIImpl::CallObjectMethodA,
- JNIImpl::CallBooleanMethod,
- JNIImpl::CallBooleanMethodV,
- JNIImpl::CallBooleanMethodA,
- JNIImpl::CallByteMethod,
- JNIImpl::CallByteMethodV,
- JNIImpl::CallByteMethodA,
- JNIImpl::CallCharMethod,
- JNIImpl::CallCharMethodV,
- JNIImpl::CallCharMethodA,
- JNIImpl::CallShortMethod,
- JNIImpl::CallShortMethodV,
- JNIImpl::CallShortMethodA,
- JNIImpl::CallIntMethod,
- JNIImpl::CallIntMethodV,
- JNIImpl::CallIntMethodA,
- JNIImpl::CallLongMethod,
- JNIImpl::CallLongMethodV,
- JNIImpl::CallLongMethodA,
- JNIImpl::CallFloatMethod,
- JNIImpl::CallFloatMethodV,
- JNIImpl::CallFloatMethodA,
- JNIImpl::CallDoubleMethod,
- JNIImpl::CallDoubleMethodV,
- JNIImpl::CallDoubleMethodA,
- JNIImpl::CallVoidMethod,
- JNIImpl::CallVoidMethodV,
- JNIImpl::CallVoidMethodA,
- JNIImpl::CallNonvirtualObjectMethod,
- JNIImpl::CallNonvirtualObjectMethodV,
- JNIImpl::CallNonvirtualObjectMethodA,
- JNIImpl::CallNonvirtualBooleanMethod,
- JNIImpl::CallNonvirtualBooleanMethodV,
- JNIImpl::CallNonvirtualBooleanMethodA,
- JNIImpl::CallNonvirtualByteMethod,
- JNIImpl::CallNonvirtualByteMethodV,
- JNIImpl::CallNonvirtualByteMethodA,
- JNIImpl::CallNonvirtualCharMethod,
- JNIImpl::CallNonvirtualCharMethodV,
- JNIImpl::CallNonvirtualCharMethodA,
- JNIImpl::CallNonvirtualShortMethod,
- JNIImpl::CallNonvirtualShortMethodV,
- JNIImpl::CallNonvirtualShortMethodA,
- JNIImpl::CallNonvirtualIntMethod,
- JNIImpl::CallNonvirtualIntMethodV,
- JNIImpl::CallNonvirtualIntMethodA,
- JNIImpl::CallNonvirtualLongMethod,
- JNIImpl::CallNonvirtualLongMethodV,
- JNIImpl::CallNonvirtualLongMethodA,
- JNIImpl::CallNonvirtualFloatMethod,
- JNIImpl::CallNonvirtualFloatMethodV,
- JNIImpl::CallNonvirtualFloatMethodA,
- JNIImpl::CallNonvirtualDoubleMethod,
- JNIImpl::CallNonvirtualDoubleMethodV,
- JNIImpl::CallNonvirtualDoubleMethodA,
- JNIImpl::CallNonvirtualVoidMethod,
- JNIImpl::CallNonvirtualVoidMethodV,
- JNIImpl::CallNonvirtualVoidMethodA,
- JNIImpl::GetFieldID,
- JNIImpl::GetObjectField,
- JNIImpl::GetBooleanField,
- JNIImpl::GetByteField,
- JNIImpl::GetCharField,
- JNIImpl::GetShortField,
- JNIImpl::GetIntField,
- JNIImpl::GetLongField,
- JNIImpl::GetFloatField,
- JNIImpl::GetDoubleField,
- JNIImpl::SetObjectField,
- JNIImpl::SetBooleanField,
- JNIImpl::SetByteField,
- JNIImpl::SetCharField,
- JNIImpl::SetShortField,
- JNIImpl::SetIntField,
- JNIImpl::SetLongField,
- JNIImpl::SetFloatField,
- JNIImpl::SetDoubleField,
- JNIImpl::GetStaticMethodID,
- JNIImpl::CallStaticObjectMethod,
- JNIImpl::CallStaticObjectMethodV,
- JNIImpl::CallStaticObjectMethodA,
- JNIImpl::CallStaticBooleanMethod,
- JNIImpl::CallStaticBooleanMethodV,
- JNIImpl::CallStaticBooleanMethodA,
- JNIImpl::CallStaticByteMethod,
- JNIImpl::CallStaticByteMethodV,
- JNIImpl::CallStaticByteMethodA,
- JNIImpl::CallStaticCharMethod,
- JNIImpl::CallStaticCharMethodV,
- JNIImpl::CallStaticCharMethodA,
- JNIImpl::CallStaticShortMethod,
- JNIImpl::CallStaticShortMethodV,
- JNIImpl::CallStaticShortMethodA,
- JNIImpl::CallStaticIntMethod,
- JNIImpl::CallStaticIntMethodV,
- JNIImpl::CallStaticIntMethodA,
- JNIImpl::CallStaticLongMethod,
- JNIImpl::CallStaticLongMethodV,
- JNIImpl::CallStaticLongMethodA,
- JNIImpl::CallStaticFloatMethod,
- JNIImpl::CallStaticFloatMethodV,
- JNIImpl::CallStaticFloatMethodA,
- JNIImpl::CallStaticDoubleMethod,
- JNIImpl::CallStaticDoubleMethodV,
- JNIImpl::CallStaticDoubleMethodA,
- JNIImpl::CallStaticVoidMethod,
- JNIImpl::CallStaticVoidMethodV,
- JNIImpl::CallStaticVoidMethodA,
- JNIImpl::GetStaticFieldID,
- JNIImpl::GetStaticObjectField,
- JNIImpl::GetStaticBooleanField,
- JNIImpl::GetStaticByteField,
- JNIImpl::GetStaticCharField,
- JNIImpl::GetStaticShortField,
- JNIImpl::GetStaticIntField,
- JNIImpl::GetStaticLongField,
- JNIImpl::GetStaticFloatField,
- JNIImpl::GetStaticDoubleField,
- JNIImpl::SetStaticObjectField,
- JNIImpl::SetStaticBooleanField,
- JNIImpl::SetStaticByteField,
- JNIImpl::SetStaticCharField,
- JNIImpl::SetStaticShortField,
- JNIImpl::SetStaticIntField,
- JNIImpl::SetStaticLongField,
- JNIImpl::SetStaticFloatField,
- JNIImpl::SetStaticDoubleField,
- JNIImpl::NewString,
- JNIImpl::GetStringLength,
- JNIImpl::GetStringChars,
- JNIImpl::ReleaseStringChars,
- JNIImpl::NewStringUTF,
- JNIImpl::GetStringUTFLength,
- JNIImpl::GetStringUTFChars,
- JNIImpl::ReleaseStringUTFChars,
- JNIImpl::GetArrayLength,
- JNIImpl::NewObjectArray,
- JNIImpl::GetObjectArrayElement,
- JNIImpl::SetObjectArrayElement,
- JNIImpl::NewBooleanArray,
- JNIImpl::NewByteArray,
- JNIImpl::NewCharArray,
- JNIImpl::NewShortArray,
- JNIImpl::NewIntArray,
- JNIImpl::NewLongArray,
- JNIImpl::NewFloatArray,
- JNIImpl::NewDoubleArray,
- JNIImpl::GetBooleanArrayElements,
- JNIImpl::GetByteArrayElements,
- JNIImpl::GetCharArrayElements,
- JNIImpl::GetShortArrayElements,
- JNIImpl::GetIntArrayElements,
- JNIImpl::GetLongArrayElements,
- JNIImpl::GetFloatArrayElements,
- JNIImpl::GetDoubleArrayElements,
- JNIImpl::ReleaseBooleanArrayElements,
- JNIImpl::ReleaseByteArrayElements,
- JNIImpl::ReleaseCharArrayElements,
- JNIImpl::ReleaseShortArrayElements,
- JNIImpl::ReleaseIntArrayElements,
- JNIImpl::ReleaseLongArrayElements,
- JNIImpl::ReleaseFloatArrayElements,
- JNIImpl::ReleaseDoubleArrayElements,
- JNIImpl::GetBooleanArrayRegion,
- JNIImpl::GetByteArrayRegion,
- JNIImpl::GetCharArrayRegion,
- JNIImpl::GetShortArrayRegion,
- JNIImpl::GetIntArrayRegion,
- JNIImpl::GetLongArrayRegion,
- JNIImpl::GetFloatArrayRegion,
- JNIImpl::GetDoubleArrayRegion,
- JNIImpl::SetBooleanArrayRegion,
- JNIImpl::SetByteArrayRegion,
- JNIImpl::SetCharArrayRegion,
- JNIImpl::SetShortArrayRegion,
- JNIImpl::SetIntArrayRegion,
- JNIImpl::SetLongArrayRegion,
- JNIImpl::SetFloatArrayRegion,
- JNIImpl::SetDoubleArrayRegion,
- JNIImpl::RegisterNatives,
- JNIImpl::UnregisterNatives,
- JNIImpl::MonitorEnter,
- JNIImpl::MonitorExit,
- JNIImpl::GetJavaVM,
- JNIImpl::GetStringRegion,
- JNIImpl::GetStringUTFRegion,
- JNIImpl::GetPrimitiveArrayCritical,
- JNIImpl::ReleasePrimitiveArrayCritical,
- JNIImpl::GetStringCritical,
- JNIImpl::ReleaseStringCritical,
- JNIImpl::NewWeakGlobalRef,
- JNIImpl::DeleteWeakGlobalRef,
- JNIImpl::ExceptionCheck,
- JNIImpl::NewDirectByteBuffer,
- JNIImpl::GetDirectBufferAddress,
- JNIImpl::GetDirectBufferCapacity,
- JNIImpl::GetObjectRefType,
- };
+const JNINativeInterface gJniNativeInterface = {
+ nullptr, // reserved0.
+ nullptr, // reserved1.
+ nullptr, // reserved2.
+ nullptr, // reserved3.
+ JNI::GetVersion,
+ JNI::DefineClass,
+ JNI::FindClass,
+ JNI::FromReflectedMethod,
+ JNI::FromReflectedField,
+ JNI::ToReflectedMethod,
+ JNI::GetSuperclass,
+ JNI::IsAssignableFrom,
+ JNI::ToReflectedField,
+ JNI::Throw,
+ JNI::ThrowNew,
+ JNI::ExceptionOccurred,
+ JNI::ExceptionDescribe,
+ JNI::ExceptionClear,
+ JNI::FatalError,
+ JNI::PushLocalFrame,
+ JNI::PopLocalFrame,
+ JNI::NewGlobalRef,
+ JNI::DeleteGlobalRef,
+ JNI::DeleteLocalRef,
+ JNI::IsSameObject,
+ JNI::NewLocalRef,
+ JNI::EnsureLocalCapacity,
+ JNI::AllocObject,
+ JNI::NewObject,
+ JNI::NewObjectV,
+ JNI::NewObjectA,
+ JNI::GetObjectClass,
+ JNI::IsInstanceOf,
+ JNI::GetMethodID,
+ JNI::CallObjectMethod,
+ JNI::CallObjectMethodV,
+ JNI::CallObjectMethodA,
+ JNI::CallBooleanMethod,
+ JNI::CallBooleanMethodV,
+ JNI::CallBooleanMethodA,
+ JNI::CallByteMethod,
+ JNI::CallByteMethodV,
+ JNI::CallByteMethodA,
+ JNI::CallCharMethod,
+ JNI::CallCharMethodV,
+ JNI::CallCharMethodA,
+ JNI::CallShortMethod,
+ JNI::CallShortMethodV,
+ JNI::CallShortMethodA,
+ JNI::CallIntMethod,
+ JNI::CallIntMethodV,
+ JNI::CallIntMethodA,
+ JNI::CallLongMethod,
+ JNI::CallLongMethodV,
+ JNI::CallLongMethodA,
+ JNI::CallFloatMethod,
+ JNI::CallFloatMethodV,
+ JNI::CallFloatMethodA,
+ JNI::CallDoubleMethod,
+ JNI::CallDoubleMethodV,
+ JNI::CallDoubleMethodA,
+ JNI::CallVoidMethod,
+ JNI::CallVoidMethodV,
+ JNI::CallVoidMethodA,
+ JNI::CallNonvirtualObjectMethod,
+ JNI::CallNonvirtualObjectMethodV,
+ JNI::CallNonvirtualObjectMethodA,
+ JNI::CallNonvirtualBooleanMethod,
+ JNI::CallNonvirtualBooleanMethodV,
+ JNI::CallNonvirtualBooleanMethodA,
+ JNI::CallNonvirtualByteMethod,
+ JNI::CallNonvirtualByteMethodV,
+ JNI::CallNonvirtualByteMethodA,
+ JNI::CallNonvirtualCharMethod,
+ JNI::CallNonvirtualCharMethodV,
+ JNI::CallNonvirtualCharMethodA,
+ JNI::CallNonvirtualShortMethod,
+ JNI::CallNonvirtualShortMethodV,
+ JNI::CallNonvirtualShortMethodA,
+ JNI::CallNonvirtualIntMethod,
+ JNI::CallNonvirtualIntMethodV,
+ JNI::CallNonvirtualIntMethodA,
+ JNI::CallNonvirtualLongMethod,
+ JNI::CallNonvirtualLongMethodV,
+ JNI::CallNonvirtualLongMethodA,
+ JNI::CallNonvirtualFloatMethod,
+ JNI::CallNonvirtualFloatMethodV,
+ JNI::CallNonvirtualFloatMethodA,
+ JNI::CallNonvirtualDoubleMethod,
+ JNI::CallNonvirtualDoubleMethodV,
+ JNI::CallNonvirtualDoubleMethodA,
+ JNI::CallNonvirtualVoidMethod,
+ JNI::CallNonvirtualVoidMethodV,
+ JNI::CallNonvirtualVoidMethodA,
+ JNI::GetFieldID,
+ JNI::GetObjectField,
+ JNI::GetBooleanField,
+ JNI::GetByteField,
+ JNI::GetCharField,
+ JNI::GetShortField,
+ JNI::GetIntField,
+ JNI::GetLongField,
+ JNI::GetFloatField,
+ JNI::GetDoubleField,
+ JNI::SetObjectField,
+ JNI::SetBooleanField,
+ JNI::SetByteField,
+ JNI::SetCharField,
+ JNI::SetShortField,
+ JNI::SetIntField,
+ JNI::SetLongField,
+ JNI::SetFloatField,
+ JNI::SetDoubleField,
+ JNI::GetStaticMethodID,
+ JNI::CallStaticObjectMethod,
+ JNI::CallStaticObjectMethodV,
+ JNI::CallStaticObjectMethodA,
+ JNI::CallStaticBooleanMethod,
+ JNI::CallStaticBooleanMethodV,
+ JNI::CallStaticBooleanMethodA,
+ JNI::CallStaticByteMethod,
+ JNI::CallStaticByteMethodV,
+ JNI::CallStaticByteMethodA,
+ JNI::CallStaticCharMethod,
+ JNI::CallStaticCharMethodV,
+ JNI::CallStaticCharMethodA,
+ JNI::CallStaticShortMethod,
+ JNI::CallStaticShortMethodV,
+ JNI::CallStaticShortMethodA,
+ JNI::CallStaticIntMethod,
+ JNI::CallStaticIntMethodV,
+ JNI::CallStaticIntMethodA,
+ JNI::CallStaticLongMethod,
+ JNI::CallStaticLongMethodV,
+ JNI::CallStaticLongMethodA,
+ JNI::CallStaticFloatMethod,
+ JNI::CallStaticFloatMethodV,
+ JNI::CallStaticFloatMethodA,
+ JNI::CallStaticDoubleMethod,
+ JNI::CallStaticDoubleMethodV,
+ JNI::CallStaticDoubleMethodA,
+ JNI::CallStaticVoidMethod,
+ JNI::CallStaticVoidMethodV,
+ JNI::CallStaticVoidMethodA,
+ JNI::GetStaticFieldID,
+ JNI::GetStaticObjectField,
+ JNI::GetStaticBooleanField,
+ JNI::GetStaticByteField,
+ JNI::GetStaticCharField,
+ JNI::GetStaticShortField,
+ JNI::GetStaticIntField,
+ JNI::GetStaticLongField,
+ JNI::GetStaticFloatField,
+ JNI::GetStaticDoubleField,
+ JNI::SetStaticObjectField,
+ JNI::SetStaticBooleanField,
+ JNI::SetStaticByteField,
+ JNI::SetStaticCharField,
+ JNI::SetStaticShortField,
+ JNI::SetStaticIntField,
+ JNI::SetStaticLongField,
+ JNI::SetStaticFloatField,
+ JNI::SetStaticDoubleField,
+ JNI::NewString,
+ JNI::GetStringLength,
+ JNI::GetStringChars,
+ JNI::ReleaseStringChars,
+ JNI::NewStringUTF,
+ JNI::GetStringUTFLength,
+ JNI::GetStringUTFChars,
+ JNI::ReleaseStringUTFChars,
+ JNI::GetArrayLength,
+ JNI::NewObjectArray,
+ JNI::GetObjectArrayElement,
+ JNI::SetObjectArrayElement,
+ JNI::NewBooleanArray,
+ JNI::NewByteArray,
+ JNI::NewCharArray,
+ JNI::NewShortArray,
+ JNI::NewIntArray,
+ JNI::NewLongArray,
+ JNI::NewFloatArray,
+ JNI::NewDoubleArray,
+ JNI::GetBooleanArrayElements,
+ JNI::GetByteArrayElements,
+ JNI::GetCharArrayElements,
+ JNI::GetShortArrayElements,
+ JNI::GetIntArrayElements,
+ JNI::GetLongArrayElements,
+ JNI::GetFloatArrayElements,
+ JNI::GetDoubleArrayElements,
+ JNI::ReleaseBooleanArrayElements,
+ JNI::ReleaseByteArrayElements,
+ JNI::ReleaseCharArrayElements,
+ JNI::ReleaseShortArrayElements,
+ JNI::ReleaseIntArrayElements,
+ JNI::ReleaseLongArrayElements,
+ JNI::ReleaseFloatArrayElements,
+ JNI::ReleaseDoubleArrayElements,
+ JNI::GetBooleanArrayRegion,
+ JNI::GetByteArrayRegion,
+ JNI::GetCharArrayRegion,
+ JNI::GetShortArrayRegion,
+ JNI::GetIntArrayRegion,
+ JNI::GetLongArrayRegion,
+ JNI::GetFloatArrayRegion,
+ JNI::GetDoubleArrayRegion,
+ JNI::SetBooleanArrayRegion,
+ JNI::SetByteArrayRegion,
+ JNI::SetCharArrayRegion,
+ JNI::SetShortArrayRegion,
+ JNI::SetIntArrayRegion,
+ JNI::SetLongArrayRegion,
+ JNI::SetFloatArrayRegion,
+ JNI::SetDoubleArrayRegion,
+ JNI::RegisterNatives,
+ JNI::UnregisterNatives,
+ JNI::MonitorEnter,
+ JNI::MonitorExit,
+ JNI::GetJavaVM,
+ JNI::GetStringRegion,
+ JNI::GetStringUTFRegion,
+ JNI::GetPrimitiveArrayCritical,
+ JNI::ReleasePrimitiveArrayCritical,
+ JNI::GetStringCritical,
+ JNI::ReleaseStringCritical,
+ JNI::NewWeakGlobalRef,
+ JNI::DeleteWeakGlobalRef,
+ JNI::ExceptionCheck,
+ JNI::NewDirectByteBuffer,
+ JNI::GetDirectBufferAddress,
+ JNI::GetDirectBufferCapacity,
+ JNI::GetObjectRefType,
};
const JNINativeInterface* GetJniNativeInterface() {
- // The template argument is passed down through the Encode/DecodeArtMethod/Field calls so if
- // JniIdsAreIndices is false the calls will be a simple cast with no branches. This ensures that
- // the normal case is still fast.
- return Runtime::Current()->JniIdsAreIndices()
- ? &JniNativeInterfaceFunctions<true>::gJniNativeInterface
- : &JniNativeInterfaceFunctions<false>::gJniNativeInterface;
+ return &gJniNativeInterface;
}
void (*gJniSleepForeverStub[])() = {
diff --git a/runtime/jni/jni_internal.h b/runtime/jni/jni_internal.h
index b6e106c..4359074 100644
--- a/runtime/jni/jni_internal.h
+++ b/runtime/jni/jni_internal.h
@@ -20,9 +20,7 @@
#include <jni.h>
#include <iosfwd>
-#include "base/locks.h"
#include "base/macros.h"
-#include "runtime.h"
namespace art {
@@ -43,61 +41,24 @@
namespace jni {
-// We want to maintain a branchless fast-path for performance reasons. The JniIdManager is the
-// ultimate source of truth for how the IDs are handed out but we inline the normal non-index cases
-// here.
-
-template <bool kEnableIndexIds>
-ALWAYS_INLINE
-static bool IsIndexId(jmethodID mid) {
- return kEnableIndexIds && ((reinterpret_cast<uintptr_t>(mid) % 2) != 0);
-}
-
-template <bool kEnableIndexIds>
-ALWAYS_INLINE
-static bool IsIndexId(jfieldID fid) {
- return kEnableIndexIds && ((reinterpret_cast<uintptr_t>(fid) % 2) != 0);
-}
-
-template <bool kEnableIndexIds = true>
ALWAYS_INLINE
static inline ArtField* DecodeArtField(jfieldID fid) {
- if (IsIndexId<kEnableIndexIds>(fid)) {
- return Runtime::Current()->GetJniIdManager()->DecodeFieldId(fid);
- } else {
- return reinterpret_cast<ArtField*>(fid);
- }
+ return reinterpret_cast<ArtField*>(fid);
}
-template <bool kEnableIndexIds = true>
ALWAYS_INLINE
-static inline jfieldID EncodeArtField(ArtField* field) REQUIRES_SHARED(Locks::mutator_lock_) {
- if (kEnableIndexIds && Runtime::Current()->JniIdsAreIndices()) {
- return Runtime::Current()->GetJniIdManager()->EncodeFieldId(field);
- } else {
- return reinterpret_cast<jfieldID>(field);
- }
+static inline jfieldID EncodeArtField(ArtField* field) {
+ return reinterpret_cast<jfieldID>(field);
}
-template <bool kEnableIndexIds = true>
ALWAYS_INLINE
-static inline jmethodID EncodeArtMethod(ArtMethod* art_method)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- if (kEnableIndexIds && Runtime::Current()->JniIdsAreIndices()) {
- return Runtime::Current()->GetJniIdManager()->EncodeMethodId(art_method);
- } else {
- return reinterpret_cast<jmethodID>(art_method);
- }
+static inline jmethodID EncodeArtMethod(ArtMethod* art_method) {
+ return reinterpret_cast<jmethodID>(art_method);
}
-template <bool kEnableIndexIds = true>
ALWAYS_INLINE
static inline ArtMethod* DecodeArtMethod(jmethodID method_id) {
- if (IsIndexId<kEnableIndexIds>(method_id)) {
- return Runtime::Current()->GetJniIdManager()->DecodeMethodId(method_id);
- } else {
- return reinterpret_cast<ArtMethod*>(method_id);
- }
+ return reinterpret_cast<ArtMethod*>(method_id);
}
} // namespace jni
diff --git a/runtime/jni_id_type.h b/runtime/jni_id_type.h
deleted file mode 100644
index 7802ec6..0000000
--- a/runtime/jni_id_type.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2017 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_JNI_ID_TYPE_H_
-#define ART_RUNTIME_JNI_ID_TYPE_H_
-
-#include <iosfwd>
-
-namespace art {
-
-enum class JniIdType {
- // All Jni method/field IDs are pointers to the corresponding Art{Field,Method} type
- kPointer,
-
- // All Jni method/field IDs are indices into a table.
- kIndices,
-
- // The current default provider. Used if you run -XjdwpProvider:default
- kDefault = kPointer,
-};
-
-std::ostream& operator<<(std::ostream& os, const JniIdType& rhs);
-
-} // namespace art
-#endif // ART_RUNTIME_JNI_ID_TYPE_H_
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index c0a950d..a36fe12 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -16,17 +16,14 @@
#include "class.h"
-#include "android-base/macros.h"
#include "android-base/stringprintf.h"
-#include "array-inl.h"
#include "art_field-inl.h"
#include "art_method-inl.h"
-#include "base/enums.h"
#include "base/logging.h" // For VLOG.
#include "base/utils.h"
#include "class-inl.h"
-#include "class_ext-inl.h"
+#include "class_ext.h"
#include "class_linker-inl.h"
#include "class_loader.h"
#include "class_root.h"
@@ -1550,126 +1547,5 @@
(new_access_flags & kAccVerificationAttempted) != 0);
}
-ObjPtr<PointerArray> Class::GetMethodIds() {
- ObjPtr<ClassExt> ext(GetExtData());
- if (ext.IsNull()) {
- return nullptr;
- } else {
- return ext->GetJMethodIDs();
- }
-}
-ObjPtr<PointerArray> Class::GetOrCreateMethodIds() {
- DCHECK(Runtime::Current()->JniIdsAreIndices()) << "JNI Ids are pointers!";
- Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<Class> h_this(hs.NewHandle(this));
- ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self));
- if (ext.IsNull()) {
- self->AssertPendingOOMException();
- return nullptr;
- }
- return ext->EnsureJMethodIDsArrayPresent(NumMethods());
-}
-
-ObjPtr<PointerArray> Class::GetStaticFieldIds() {
- ObjPtr<ClassExt> ext(GetExtData());
- if (ext.IsNull()) {
- return nullptr;
- } else {
- return ext->GetStaticJFieldIDs();
- }
-}
-ObjPtr<PointerArray> Class::GetOrCreateStaticFieldIds() {
- DCHECK(Runtime::Current()->JniIdsAreIndices()) << "JNI Ids are pointers!";
- Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<Class> h_this(hs.NewHandle(this));
- ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self));
- if (ext.IsNull()) {
- self->AssertPendingOOMException();
- return nullptr;
- }
- return ext->EnsureStaticJFieldIDsArrayPresent(NumStaticFields());
-}
-ObjPtr<PointerArray> Class::GetInstanceFieldIds() {
- ObjPtr<ClassExt> ext(GetExtData());
- if (ext.IsNull()) {
- return nullptr;
- } else {
- return ext->GetInstanceJFieldIDs();
- }
-}
-ObjPtr<PointerArray> Class::GetOrCreateInstanceFieldIds() {
- DCHECK(Runtime::Current()->JniIdsAreIndices()) << "JNI Ids are pointers!";
- Thread* self = Thread::Current();
- StackHandleScope<1> hs(self);
- Handle<Class> h_this(hs.NewHandle(this));
- ObjPtr<ClassExt> ext(EnsureExtDataPresent(h_this, self));
- if (ext.IsNull()) {
- self->AssertPendingOOMException();
- return nullptr;
- }
- return ext->EnsureInstanceJFieldIDsArrayPresent(NumInstanceFields());
-}
-
-size_t Class::GetStaticFieldIdOffset(ArtField* field) {
- DCHECK_LT(reinterpret_cast<uintptr_t>(field),
- reinterpret_cast<uintptr_t>(&*GetSFieldsPtr()->end()))
- << "field not part of the current class. " << field->PrettyField() << " class is "
- << PrettyClass();
- DCHECK_GE(reinterpret_cast<uintptr_t>(field),
- reinterpret_cast<uintptr_t>(&*GetSFieldsPtr()->begin()))
- << "field not part of the current class. " << field->PrettyField() << " class is "
- << PrettyClass();
- uintptr_t start = reinterpret_cast<uintptr_t>(&GetSFieldsPtr()->At(0));
- uintptr_t fld = reinterpret_cast<uintptr_t>(field);
- size_t res = (fld - start) / sizeof(ArtField);
- DCHECK_EQ(&GetSFieldsPtr()->At(res), field)
- << "Incorrect field computation expected: " << field->PrettyField()
- << " got: " << GetSFieldsPtr()->At(res).PrettyField();
- return res;
-}
-
-size_t Class::GetInstanceFieldIdOffset(ArtField* field) {
- DCHECK_LT(reinterpret_cast<uintptr_t>(field),
- reinterpret_cast<uintptr_t>(&*GetIFieldsPtr()->end()))
- << "field not part of the current class. " << field->PrettyField() << " class is "
- << PrettyClass();
- DCHECK_GE(reinterpret_cast<uintptr_t>(field),
- reinterpret_cast<uintptr_t>(&*GetIFieldsPtr()->begin()))
- << "field not part of the current class. " << field->PrettyField() << " class is "
- << PrettyClass();
- uintptr_t start = reinterpret_cast<uintptr_t>(&GetIFieldsPtr()->At(0));
- uintptr_t fld = reinterpret_cast<uintptr_t>(field);
- size_t res = (fld - start) / sizeof(ArtField);
- DCHECK_EQ(&GetIFieldsPtr()->At(res), field)
- << "Incorrect field computation expected: " << field->PrettyField()
- << " got: " << GetIFieldsPtr()->At(res).PrettyField();
- return res;
-}
-
-size_t Class::GetMethodIdOffset(ArtMethod* method, PointerSize pointer_size) {
- DCHECK(GetMethodsSlice(kRuntimePointerSize).Contains(method))
- << "method not part of the current class. " << method->PrettyMethod() << "( " << reinterpret_cast<void*>(method) << ")" << " class is "
- << PrettyClass() << [&]() REQUIRES_SHARED(Locks::mutator_lock_) {
- std::ostringstream os;
- os << " Methods are [";
- for (ArtMethod& m : GetMethodsSlice(kRuntimePointerSize)) {
- os << m.PrettyMethod() << "( " << reinterpret_cast<void*>(&m) << "), ";
- }
- os << "]";
- return os.str();
- }();
- uintptr_t start = reinterpret_cast<uintptr_t>(&*GetMethodsSlice(pointer_size).begin());
- uintptr_t fld = reinterpret_cast<uintptr_t>(method);
- size_t art_method_size = ArtMethod::Size(pointer_size);
- size_t art_method_align = ArtMethod::Alignment(pointer_size);
- size_t res = (fld - start) / art_method_size;
- DCHECK_EQ(&GetMethodsPtr()->At(res, art_method_size, art_method_align), method)
- << "Incorrect method computation expected: " << method->PrettyMethod()
- << " got: " << GetMethodsPtr()->At(res, art_method_size, art_method_align).PrettyMethod();
- return res;
-}
-
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 144350f..09d5532 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -1229,23 +1229,6 @@
void FixupNativePointers(Class* dest, PointerSize pointer_size, const Visitor& visitor)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Get or create the various jni id arrays in a lock-less thread safe manner.
- ObjPtr<PointerArray> GetOrCreateMethodIds() REQUIRES_SHARED(Locks::mutator_lock_);
- ObjPtr<PointerArray> GetMethodIds() REQUIRES_SHARED(Locks::mutator_lock_);
- ObjPtr<PointerArray> GetOrCreateStaticFieldIds() REQUIRES_SHARED(Locks::mutator_lock_);
- ObjPtr<PointerArray> GetStaticFieldIds() REQUIRES_SHARED(Locks::mutator_lock_);
- ObjPtr<PointerArray> GetOrCreateInstanceFieldIds() REQUIRES_SHARED(Locks::mutator_lock_);
- ObjPtr<PointerArray> GetInstanceFieldIds() REQUIRES_SHARED(Locks::mutator_lock_);
-
- // Calculate the index in the ifields_, methods_ or sfields_ arrays a method is located at. This
- // is to be used with the above Get{,OrCreate}...Ids functions.
- size_t GetStaticFieldIdOffset(ArtField* field)
- REQUIRES_SHARED(Locks::mutator_lock_);
- size_t GetInstanceFieldIdOffset(ArtField* field)
- REQUIRES_SHARED(Locks::mutator_lock_);
- size_t GetMethodIdOffset(ArtMethod* method, PointerSize pointer_size)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
private:
template <typename T, VerifyObjectFlags kVerifyFlags, typename Visitor>
void FixupNativePointer(
diff --git a/runtime/mirror/class_ext-inl.h b/runtime/mirror/class_ext-inl.h
index ead02ee..bf51654 100644
--- a/runtime/mirror/class_ext-inl.h
+++ b/runtime/mirror/class_ext-inl.h
@@ -19,81 +19,12 @@
#include "class_ext.h"
-#include "array-inl.h"
#include "art_method-inl.h"
-#include "handle_scope.h"
#include "object-inl.h"
namespace art {
namespace mirror {
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline ObjPtr<PointerArray> ClassExt::EnsureJniIdsArrayPresent(MemberOffset off, size_t count) {
- ObjPtr<PointerArray> existing(
- GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(off));
- if (!existing.IsNull()) {
- return existing;
- }
- Thread* self = Thread::Current();
- StackHandleScope<2> hs(self);
- Handle<ClassExt> h_this(hs.NewHandle(this));
- Handle<PointerArray> new_arr(
- hs.NewHandle(Runtime::Current()->GetClassLinker()->AllocPointerArray(self, count)));
- if (new_arr.IsNull()) {
- // Fail.
- self->AssertPendingOOMException();
- return nullptr;
- }
- bool set;
- // Set the ext_data_ field using CAS semantics.
- if (Runtime::Current()->IsActiveTransaction()) {
- set = h_this->CasFieldObject<true>(
- off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst);
- } else {
- set = h_this->CasFieldObject<false>(
- off, nullptr, new_arr.Get(), CASMode::kStrong, std::memory_order_seq_cst);
- }
- ObjPtr<PointerArray> ret(
- set ? new_arr.Get()
- : h_this->GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(off));
- CHECK(!ret.IsNull());
- return ret;
-}
-
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline ObjPtr<PointerArray> ClassExt::EnsureJMethodIDsArrayPresent(size_t count) {
- return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
- MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_)), count);
-}
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline ObjPtr<PointerArray> ClassExt::EnsureStaticJFieldIDsArrayPresent(size_t count) {
- return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
- MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_)), count);
-}
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline ObjPtr<PointerArray> ClassExt::EnsureInstanceJFieldIDsArrayPresent(size_t count) {
- return EnsureJniIdsArrayPresent<kVerifyFlags, kReadBarrierOption>(
- MemberOffset(OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_)), count);
-}
-
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline ObjPtr<PointerArray> ClassExt::GetInstanceJFieldIDs() {
- return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
- OFFSET_OF_OBJECT_MEMBER(ClassExt, instance_jfield_ids_));
-}
-
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline ObjPtr<PointerArray> ClassExt::GetStaticJFieldIDs() {
- return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
- OFFSET_OF_OBJECT_MEMBER(ClassExt, static_jfield_ids_));
-}
-
-template <VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline ObjPtr<PointerArray> ClassExt::GetJMethodIDs() {
- return GetFieldObject<PointerArray, kVerifyFlags, kReadBarrierOption>(
- OFFSET_OF_OBJECT_MEMBER(ClassExt, jmethod_ids_));
-}
-
inline ObjPtr<Object> ClassExt::GetVerifyError() {
return GetFieldObject<ClassExt>(OFFSET_OF_OBJECT_MEMBER(ClassExt, verify_error_));
}
diff --git a/runtime/mirror/class_ext.h b/runtime/mirror/class_ext.h
index 6fb225f..70bea33 100644
--- a/runtime/mirror/class_ext.h
+++ b/runtime/mirror/class_ext.h
@@ -48,33 +48,6 @@
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- ObjPtr<PointerArray> EnsureInstanceJFieldIDsArrayPresent(size_t count)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- ObjPtr<PointerArray> GetInstanceJFieldIDs() REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- ObjPtr<PointerArray> EnsureStaticJFieldIDsArrayPresent(size_t count)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- ObjPtr<PointerArray> GetStaticJFieldIDs() REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- ObjPtr<PointerArray> EnsureJMethodIDsArrayPresent(size_t count)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- ObjPtr<PointerArray> GetJMethodIDs() REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
ObjPtr<PointerArray> GetObsoleteMethods() REQUIRES_SHARED(Locks::mutator_lock_);
ObjPtr<Object> GetOriginalDexFile() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -109,36 +82,19 @@
static ObjPtr<ClassExt> Alloc(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
private:
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- ObjPtr<PointerArray> EnsureJniIdsArrayPresent(MemberOffset off, size_t count)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- // An array containing the jfieldIDs assigned to each field in the corresponding position in the
- // classes ifields_ array or '0' if no id has been assigned to that field yet.
- HeapReference<PointerArray> instance_jfield_ids_;
-
- // An array containing the jmethodIDs assigned to each method in the corresponding position in
- // the classes methods_ array or '0' if no id has been assigned to that method yet.
- HeapReference<PointerArray> jmethod_ids_;
-
HeapReference<ObjectArray<DexCache>> obsolete_dex_caches_;
HeapReference<PointerArray> obsolete_methods_;
HeapReference<Object> original_dex_file_;
- // An array containing the jfieldIDs assigned to each field in the corresponding position in the
- // classes sfields_ array or '0' if no id has been assigned to that field yet.
- HeapReference<PointerArray> static_jfield_ids_;
-
// The saved verification error of this class.
HeapReference<Object> verify_error_;
// Native pointer to DexFile and ClassDef index of this class before it was JVMTI-redefined.
- int32_t pre_redefine_class_def_index_;
int64_t pre_redefine_dex_file_ptr_;
+ int32_t pre_redefine_class_def_index_;
friend struct art::ClassExtOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassExt);
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index afcf40d..a5e9d95 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -367,10 +367,6 @@
.WithType<bool>()
.WithValueMap({{"false", false}, {"true", true}})
.IntoKey(M::FastClassNotFoundException)
- .Define("-Xopaque-jni-ids:_")
- .WithType<bool>()
- .WithValueMap({{"true", true}, {"false", false}})
- .IntoKey(M::OpaqueJniIds)
.Ignore({
"-ea", "-da", "-enableassertions", "-disableassertions", "--runtime-arg", "-esa",
"-dsa", "-enablesystemassertions", "-disablesystemassertions", "-Xrs", "-Xint:_",
@@ -788,7 +784,6 @@
"(Enable new and experimental agent support)\n");
UsageMessage(stream, " -Xexperimental:agents"
"(Enable new and experimental agent support)\n");
- UsageMessage(stream, " -Xopaque-jni-ids:{true,false} (Use opauque integers for jni ids)\n");
UsageMessage(stream, "\n");
UsageMessage(stream, "The following previously supported Dalvik options are ignored:\n");
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index ad20575..12fda43 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -94,9 +94,7 @@
#include "jit/jit_code_cache.h"
#include "jit/profile_saver.h"
#include "jni/java_vm_ext.h"
-#include "jni/jni_id_manager.h"
#include "jni/jni_internal.h"
-#include "jni_id_type.h"
#include "linear_alloc.h"
#include "memory_representation.h"
#include "mirror/array.h"
@@ -1183,8 +1181,6 @@
oat_file_manager_ = new OatFileManager;
- jni_id_manager_ = new jni::JniIdManager;
-
Thread::SetSensitiveThreadHook(runtime_options.GetOrDefault(Opt::HookIsSensitiveThread));
Monitor::Init(runtime_options.GetOrDefault(Opt::LockProfThreshold),
runtime_options.GetOrDefault(Opt::StackDumpLockProfThreshold));
@@ -1306,13 +1302,6 @@
is_low_memory_mode_ = runtime_options.Exists(Opt::LowMemoryMode);
madvise_random_access_ = runtime_options.GetOrDefault(Opt::MadviseRandomAccess);
- if (!runtime_options.Exists(Opt::OpaqueJniIds)) {
- jni_ids_indirection_ = JniIdType::kDefault;
- } else {
- jni_ids_indirection_ = *runtime_options.Get(Opt::OpaqueJniIds) ? JniIdType::kIndices
- : JniIdType::kPointer;
- }
-
plugins_ = runtime_options.ReleaseOrDefault(Opt::Plugins);
agent_specs_ = runtime_options.ReleaseOrDefault(Opt::AgentPath);
// TODO Add back in -agentlib
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 65e3541..6e27a9f 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -37,8 +37,6 @@
#include "gc_root.h"
#include "instrumentation.h"
#include "jdwp_provider.h"
-#include "jni/jni_id_manager.h"
-#include "jni_id_type.h"
#include "obj_ptr.h"
#include "offsets.h"
#include "process_state.h"
@@ -281,10 +279,6 @@
return class_linker_;
}
- jni::JniIdManager* GetJniIdManager() const {
- return jni_id_manager_;
- }
-
size_t GetDefaultStackSize() const {
return default_stack_size_;
}
@@ -840,10 +834,6 @@
return jdwp_provider_;
}
- bool JniIdsAreIndices() const {
- return jni_ids_indirection_ != JniIdType::kPointer;
- }
-
uint32_t GetVerifierLoggingThresholdMs() const {
return verifier_logging_threshold_ms_;
}
@@ -1015,8 +1005,6 @@
SignalCatcher* signal_catcher_;
- jni::JniIdManager* jni_id_manager_;
-
std::unique_ptr<JavaVMExt> java_vm_;
std::unique_ptr<jit::Jit> jit_;
@@ -1200,10 +1188,6 @@
// The jdwp provider we were configured with.
JdwpProvider jdwp_provider_;
- // True if jmethodID and jfieldID are opaque Indices. When false (the default) these are simply
- // pointers. This is set by -Xopaque-jni-ids:{true,false}.
- JniIdType jni_ids_indirection_;
-
// Saved environment.
class EnvSnapshot {
public:
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index d2594b2..43a7229 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -77,7 +77,6 @@
RUNTIME_OPTIONS_KEY (bool, UseJitCompilation, true)
RUNTIME_OPTIONS_KEY (bool, DumpNativeStackOnSigQuit, true)
RUNTIME_OPTIONS_KEY (bool, MadviseRandomAccess, false)
-RUNTIME_OPTIONS_KEY (bool, OpaqueJniIds, false) // -Xopaque-jni-ids:{true, false}
RUNTIME_OPTIONS_KEY (unsigned int, JITCompileThreshold)
RUNTIME_OPTIONS_KEY (unsigned int, JITWarmupThreshold)
RUNTIME_OPTIONS_KEY (unsigned int, JITOsrThreshold)
diff --git a/runtime/thread.cc b/runtime/thread.cc
index d5aea19..3e83f65 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -4280,16 +4280,8 @@
self_->ClearException();
}
-void ScopedExceptionStorage::SuppressOldException(const char* message) {
- CHECK(self_->IsExceptionPending()) << *self_;
- ObjPtr<mirror::Throwable> old_suppressed(excp_.Get());
- excp_.Assign(self_->GetException());
- LOG(WARNING) << message << "Suppressing old exception: " << old_suppressed->Dump();
- self_->ClearException();
-}
-
ScopedExceptionStorage::~ScopedExceptionStorage() {
- CHECK(!self_->IsExceptionPending()) << *self_;
+ CHECK(!self_->IsExceptionPending()) << self_;
if (!excp_.IsNull()) {
self_->SetException(excp_.Get());
}
diff --git a/runtime/thread.h b/runtime/thread.h
index 9a230e2..8fe9466 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -1901,13 +1901,12 @@
class ScopedExceptionStorage {
public:
explicit ScopedExceptionStorage(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
- void SuppressOldException(const char* message = "") REQUIRES_SHARED(Locks::mutator_lock_);
~ScopedExceptionStorage() REQUIRES_SHARED(Locks::mutator_lock_);
private:
Thread* self_;
StackHandleScope<1> hs_;
- MutableHandle<mirror::Throwable> excp_;
+ Handle<mirror::Throwable> excp_;
};
std::ostream& operator<<(std::ostream& os, const Thread& thread);