summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/dex_to_dex_compiler.cc2
-rw-r--r--compiler/dex/mir_field_info.cc4
-rw-r--r--compiler/dex/verified_method.cc2
-rw-r--r--compiler/driver/compiler_driver-inl.h23
-rw-r--r--compiler/driver/compiler_driver.cc41
-rw-r--r--compiler/driver/compiler_driver.h22
-rw-r--r--compiler/driver/compiler_driver_test.cc2
-rw-r--r--compiler/image_test.cc1
-rw-r--r--compiler/image_writer.cc256
-rw-r--r--compiler/image_writer.h29
-rw-r--r--compiler/optimizing/builder.cc22
-rw-r--r--compiler/utils/dex_cache_arrays_layout-inl.h50
-rw-r--r--compiler/utils/dex_cache_arrays_layout.h18
-rw-r--r--imgdiag/imgdiag.cc7
-rw-r--r--oatdump/oatdump.cc30
-rw-r--r--patchoat/patchoat.cc87
-rw-r--r--patchoat/patchoat.h23
-rw-r--r--runtime/Android.mk3
-rw-r--r--runtime/arch/stub_test.cc296
-rw-r--r--runtime/art_field-inl.h (renamed from runtime/mirror/art_field-inl.h)89
-rw-r--r--runtime/art_field.cc (renamed from runtime/mirror/art_field.cc)43
-rw-r--r--runtime/art_field.h (renamed from runtime/mirror/art_field.h)142
-rw-r--r--runtime/asm_support.h6
-rw-r--r--runtime/base/arena_allocator.cc29
-rw-r--r--runtime/base/arena_allocator.h8
-rw-r--r--runtime/base/mutex.h1
-rw-r--r--runtime/check_jni.cc17
-rw-r--r--runtime/class_linker-inl.h29
-rw-r--r--runtime/class_linker.cc393
-rw-r--r--runtime/class_linker.h30
-rw-r--r--runtime/class_linker_test.cc86
-rw-r--r--runtime/common_runtime_test.cc13
-rw-r--r--runtime/common_throws.cc17
-rw-r--r--runtime/common_throws.h10
-rw-r--r--runtime/debugger.cc55
-rw-r--r--runtime/debugger.h10
-rw-r--r--runtime/dex_file.cc10
-rw-r--r--runtime/dex_file.h4
-rw-r--r--runtime/entrypoints/entrypoint_utils-inl.h12
-rw-r--r--runtime/entrypoints/entrypoint_utils.cc2
-rw-r--r--runtime/entrypoints/entrypoint_utils.h8
-rw-r--r--runtime/entrypoints/quick/quick_field_entrypoints.cc82
-rw-r--r--runtime/gc/accounting/mod_union_table.cc1
-rw-r--r--runtime/gc/accounting/remembered_set.cc1
-rw-r--r--runtime/gc/accounting/space_bitmap.cc34
-rw-r--r--runtime/gc/collector/concurrent_copying.cc2
-rw-r--r--runtime/gc/collector/mark_compact.cc2
-rw-r--r--runtime/gc/collector/mark_sweep-inl.h3
-rw-r--r--runtime/gc/collector/mark_sweep.cc1
-rw-r--r--runtime/gc/heap.cc18
-rw-r--r--runtime/gc/space/image_space.cc38
-rw-r--r--runtime/gc/space/image_space.h2
-rw-r--r--runtime/globals.h2
-rw-r--r--runtime/hprof/hprof.cc8
-rw-r--r--runtime/image.cc6
-rw-r--r--runtime/image.h20
-rw-r--r--runtime/instrumentation.cc4
-rw-r--r--runtime/instrumentation.h14
-rw-r--r--runtime/interpreter/interpreter_common.cc5
-rw-r--r--runtime/interpreter/interpreter_common.h3
-rw-r--r--runtime/interpreter/unstarted_runtime.cc14
-rw-r--r--runtime/jdwp/jdwp.h4
-rw-r--r--runtime/jdwp/jdwp_event.cc6
-rw-r--r--runtime/jit/jit_instrumentation.h6
-rw-r--r--runtime/jni_internal.cc22
-rw-r--r--runtime/linear_alloc.cc36
-rw-r--r--runtime/linear_alloc.h49
-rw-r--r--runtime/mem_map.cc2
-rw-r--r--runtime/mirror/array-inl.h2
-rw-r--r--runtime/mirror/array.h2
-rw-r--r--runtime/mirror/art_method.cc2
-rw-r--r--runtime/mirror/class-inl.h110
-rw-r--r--runtime/mirror/class.h85
-rw-r--r--runtime/mirror/dex_cache-inl.h38
-rw-r--r--runtime/mirror/dex_cache.cc9
-rw-r--r--runtime/mirror/dex_cache.h31
-rw-r--r--runtime/mirror/dex_cache_test.cc5
-rw-r--r--runtime/mirror/field-inl.h7
-rw-r--r--runtime/mirror/field.cc2
-rw-r--r--runtime/mirror/field.h6
-rw-r--r--runtime/mirror/object-inl.h21
-rw-r--r--runtime/mirror/object.cc50
-rw-r--r--runtime/mirror/object.h8
-rw-r--r--runtime/mirror/object_array-inl.h5
-rw-r--r--runtime/mirror/object_test.cc14
-rw-r--r--runtime/native/dalvik_system_VMRuntime.cc8
-rw-r--r--runtime/native/java_lang_Class.cc63
-rw-r--r--runtime/native/java_lang_reflect_Array.cc2
-rw-r--r--runtime/native/java_lang_reflect_Constructor.cc2
-rw-r--r--runtime/oat_file_assistant_test.cc10
-rw-r--r--runtime/primitive.h22
-rw-r--r--runtime/proxy_test.cc38
-rw-r--r--runtime/quick/inline_method_analyser.cc10
-rw-r--r--runtime/read_barrier.h1
-rw-r--r--runtime/reflection.cc17
-rw-r--r--runtime/reflection.h4
-rw-r--r--runtime/runtime.cc17
-rw-r--r--runtime/runtime.h11
-rw-r--r--runtime/scoped_thread_state_change.h12
-rw-r--r--runtime/thread.cc12
-rw-r--r--runtime/trace.cc4
-rw-r--r--runtime/trace.h6
-rw-r--r--runtime/transaction_test.cc56
-rw-r--r--runtime/utils.cc4
-rw-r--r--runtime/utils.h4
-rw-r--r--runtime/utils_test.cc2
-rw-r--r--runtime/verifier/method_verifier.cc43
-rw-r--r--runtime/verifier/method_verifier.h10
108 files changed, 1644 insertions, 1428 deletions
diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc
index 548b6f8b63..ef94d8b66f 100644
--- a/compiler/dex/dex_to_dex_compiler.cc
+++ b/compiler/dex/dex_to_dex_compiler.cc
@@ -14,13 +14,13 @@
* limitations under the License.
*/
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/mutex.h"
#include "dex_file-inl.h"
#include "dex_instruction-inl.h"
#include "driver/compiler_driver.h"
#include "driver/dex_compilation_unit.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/dex_cache.h"
diff --git a/compiler/dex/mir_field_info.cc b/compiler/dex/mir_field_info.cc
index a9ab3bb0d4..4dfec176af 100644
--- a/compiler/dex/mir_field_info.cc
+++ b/compiler/dex/mir_field_info.cc
@@ -56,7 +56,7 @@ void MirIFieldLoweringInfo::Resolve(CompilerDriver* compiler_driver,
// definition) we still want to resolve fields and record all available info.
for (auto it = field_infos, end = field_infos + count; it != end; ++it) {
uint32_t field_idx;
- mirror::ArtField* resolved_field;
+ ArtField* resolved_field;
if (!it->IsQuickened()) {
field_idx = it->field_idx_;
resolved_field = compiler_driver->ResolveField(soa, dex_cache, class_loader, mUnit,
@@ -121,7 +121,7 @@ void MirSFieldLoweringInfo::Resolve(CompilerDriver* compiler_driver,
for (auto it = field_infos, end = field_infos + count; it != end; ++it) {
uint32_t field_idx = it->field_idx_;
- mirror::ArtField* resolved_field =
+ ArtField* resolved_field =
compiler_driver->ResolveField(soa, dex_cache, class_loader, mUnit, field_idx, true);
if (UNLIKELY(resolved_field == nullptr)) {
continue;
diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc
index 5b90ba92e0..ae814b4029 100644
--- a/compiler/dex/verified_method.cc
+++ b/compiler/dex/verified_method.cc
@@ -222,7 +222,7 @@ bool VerifiedMethod::GenerateDequickenMap(verifier::MethodVerifier* method_verif
} else if (IsInstructionIGetQuickOrIPutQuick(inst->Opcode())) {
uint32_t dex_pc = inst->GetDexPc(insns);
verifier::RegisterLine* line = method_verifier->GetRegLine(dex_pc);
- mirror::ArtField* field = method_verifier->GetQuickFieldAccess(inst, line);
+ ArtField* field = method_verifier->GetQuickFieldAccess(inst, line);
if (field == nullptr) {
// It can be null if the line wasn't verified since it was unreachable.
return false;
diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h
index 8babc28db9..b4d46954f1 100644
--- a/compiler/driver/compiler_driver-inl.h
+++ b/compiler/driver/compiler_driver-inl.h
@@ -19,12 +19,11 @@
#include "compiler_driver.h"
+#include "art_field-inl.h"
#include "dex_compilation_unit.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class_loader.h"
#include "mirror/dex_cache-inl.h"
-#include "mirror/art_field-inl.h"
#include "scoped_thread_state_change.h"
#include "handle_scope-inl.h"
@@ -65,12 +64,12 @@ inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass(
return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit);
}
-inline mirror::ArtField* CompilerDriver::ResolveFieldWithDexFile(
+inline ArtField* CompilerDriver::ResolveFieldWithDexFile(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file,
uint32_t field_idx, bool is_static) {
DCHECK_EQ(dex_cache->GetDexFile(), dex_file);
- mirror::ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField(
+ ArtField* resolved_field = Runtime::Current()->GetClassLinker()->ResolveField(
*dex_file, field_idx, dex_cache, class_loader, is_static);
DCHECK_EQ(resolved_field == nullptr, soa.Self()->IsExceptionPending());
if (UNLIKELY(resolved_field == nullptr)) {
@@ -90,7 +89,7 @@ inline mirror::DexCache* CompilerDriver::FindDexCache(const DexFile* dex_file) {
return Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
}
-inline mirror::ArtField* CompilerDriver::ResolveField(
+inline ArtField* CompilerDriver::ResolveField(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t field_idx, bool is_static) {
@@ -100,7 +99,7 @@ inline mirror::ArtField* CompilerDriver::ResolveField(
}
inline void CompilerDriver::GetResolvedFieldDexFileLocation(
- mirror::ArtField* resolved_field, const DexFile** declaring_dex_file,
+ ArtField* resolved_field, const DexFile** declaring_dex_file,
uint16_t* declaring_class_idx, uint16_t* declaring_field_idx) {
mirror::Class* declaring_class = resolved_field->GetDeclaringClass();
*declaring_dex_file = declaring_class->GetDexCache()->GetDexFile();
@@ -108,17 +107,17 @@ inline void CompilerDriver::GetResolvedFieldDexFileLocation(
*declaring_field_idx = resolved_field->GetDexFieldIndex();
}
-inline bool CompilerDriver::IsFieldVolatile(mirror::ArtField* field) {
+inline bool CompilerDriver::IsFieldVolatile(ArtField* field) {
return field->IsVolatile();
}
-inline MemberOffset CompilerDriver::GetFieldOffset(mirror::ArtField* field) {
+inline MemberOffset CompilerDriver::GetFieldOffset(ArtField* field) {
return field->GetOffset();
}
inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
- mirror::ArtField* resolved_field, uint16_t field_idx) {
+ ArtField* resolved_field, uint16_t field_idx) {
DCHECK(!resolved_field->IsStatic());
mirror::Class* fields_class = resolved_field->GetDeclaringClass();
bool fast_get = referrer_class != nullptr &&
@@ -130,7 +129,7 @@ inline std::pair<bool, bool> CompilerDriver::IsFastInstanceField(
inline std::pair<bool, bool> CompilerDriver::IsFastStaticField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
- mirror::ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) {
+ ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index) {
DCHECK(resolved_field->IsStatic());
if (LIKELY(referrer_class != nullptr)) {
mirror::Class* fields_class = resolved_field->GetDeclaringClass();
@@ -177,14 +176,14 @@ inline std::pair<bool, bool> CompilerDriver::IsFastStaticField(
}
inline bool CompilerDriver::IsStaticFieldInReferrerClass(mirror::Class* referrer_class,
- mirror::ArtField* resolved_field) {
+ ArtField* resolved_field) {
DCHECK(resolved_field->IsStatic());
mirror::Class* fields_class = resolved_field->GetDeclaringClass();
return referrer_class == fields_class;
}
inline bool CompilerDriver::IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
- mirror::ArtField* resolved_field) {
+ ArtField* resolved_field) {
DCHECK(resolved_field->IsStatic());
mirror::Class* fields_class = resolved_field->GetDeclaringClass();
return fields_class == referrer_class || fields_class->IsInitialized();
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index f263f6d329..6d7924890e 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -27,6 +27,7 @@
#include <malloc.h> // For mallinfo
#endif
+#include "art_field-inl.h"
#include "base/stl_util.h"
#include "base/timing_logger.h"
#include "class_linker.h"
@@ -48,7 +49,6 @@
#include "gc/accounting/card_table-inl.h"
#include "gc/accounting/heap_bitmap.h"
#include "gc/space/space.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class_loader.h"
#include "mirror/class-inl.h"
@@ -1183,7 +1183,7 @@ uint32_t CompilerDriver::GetReferenceDisableFlagOffset() const {
DexCacheArraysLayout CompilerDriver::GetDexCacheArraysLayout(const DexFile* dex_file) {
// Currently only image dex caches have fixed array layout.
return IsImage() && GetSupportBootImageFixup()
- ? DexCacheArraysLayout(dex_file)
+ ? DexCacheArraysLayout(GetInstructionSetPointerSize(instruction_set_), dex_file)
: DexCacheArraysLayout();
}
@@ -1209,12 +1209,11 @@ void CompilerDriver::ProcessedInvoke(InvokeType invoke_type, int flags) {
stats_->ProcessedInvoke(invoke_type, flags);
}
-mirror::ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
- const DexCompilationUnit* mUnit,
- bool is_put,
- const ScopedObjectAccess& soa) {
+ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
+ const DexCompilationUnit* mUnit, bool is_put,
+ const ScopedObjectAccess& soa) {
// Try to resolve the field and compiling method's class.
- mirror::ArtField* resolved_field;
+ ArtField* resolved_field;
mirror::Class* referrer_class;
mirror::DexCache* dex_cache;
{
@@ -1223,11 +1222,10 @@ mirror::ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx,
hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
Handle<mirror::ClassLoader> class_loader_handle(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
- Handle<mirror::ArtField> resolved_field_handle(hs.NewHandle(
- ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, false)));
- referrer_class = (resolved_field_handle.Get() != nullptr)
+ resolved_field =
+ ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, false);
+ referrer_class = resolved_field != nullptr
? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
- resolved_field = resolved_field_handle.Get();
dex_cache = dex_cache_handle.Get();
}
bool can_link = false;
@@ -1244,11 +1242,9 @@ bool CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, const DexCompi
bool is_put, MemberOffset* field_offset,
bool* is_volatile) {
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- Handle<mirror::ArtField> resolved_field =
- hs.NewHandle(ComputeInstanceFieldInfo(field_idx, mUnit, is_put, soa));
+ ArtField* resolved_field = ComputeInstanceFieldInfo(field_idx, mUnit, is_put, soa);
- if (resolved_field.Get() == nullptr) {
+ if (resolved_field == nullptr) {
// Conservative defaults.
*is_volatile = true;
*field_offset = MemberOffset(static_cast<size_t>(-1));
@@ -1267,20 +1263,19 @@ bool CompilerDriver::ComputeStaticFieldInfo(uint32_t field_idx, const DexCompila
Primitive::Type* type) {
ScopedObjectAccess soa(Thread::Current());
// Try to resolve the field and compiling method's class.
- mirror::ArtField* resolved_field;
+ ArtField* resolved_field;
mirror::Class* referrer_class;
mirror::DexCache* dex_cache;
{
- StackHandleScope<3> hs(soa.Self());
+ StackHandleScope<2> hs(soa.Self());
Handle<mirror::DexCache> dex_cache_handle(
hs.NewHandle(mUnit->GetClassLinker()->FindDexCache(*mUnit->GetDexFile())));
Handle<mirror::ClassLoader> class_loader_handle(
hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())));
- Handle<mirror::ArtField> resolved_field_handle(hs.NewHandle(
- ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, true)));
- referrer_class = (resolved_field_handle.Get() != nullptr)
+ resolved_field =
+ ResolveField(soa, dex_cache_handle, class_loader_handle, mUnit, field_idx, true);
+ referrer_class = resolved_field != nullptr
? ResolveCompilingMethodsClass(soa, dex_cache_handle, class_loader_handle, mUnit) : nullptr;
- resolved_field = resolved_field_handle.Get();
dex_cache = dex_cache_handle.Get();
}
bool result = false;
@@ -1728,7 +1723,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag
ClassDataItemIterator it(dex_file, class_data);
while (it.HasNextStaticField()) {
if (resolve_fields_and_methods) {
- mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
+ ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
dex_cache, class_loader, true);
if (field == nullptr) {
CheckAndClearResolveException(soa.Self());
@@ -1743,7 +1738,7 @@ static void ResolveClassFieldsAndMethods(const ParallelCompilationManager* manag
requires_constructor_barrier = true;
}
if (resolve_fields_and_methods) {
- mirror::ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
+ ArtField* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(),
dex_cache, class_loader, false);
if (field == nullptr) {
CheckAndClearResolveException(soa.Self());
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index a6ed5590dc..f1066a5005 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -239,14 +239,14 @@ class CompilerDriver {
// Resolve a field. Returns nullptr on failure, including incompatible class change.
// NOTE: Unlike ClassLinker's ResolveField(), this method enforces is_static.
- mirror::ArtField* ResolveField(
+ ArtField* ResolveField(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit,
uint32_t field_idx, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a field with a given dex file.
- mirror::ArtField* ResolveFieldWithDexFile(
+ ArtField* ResolveFieldWithDexFile(
const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader, const DexFile* dex_file,
uint32_t field_idx, bool is_static)
@@ -254,12 +254,12 @@ class CompilerDriver {
// Get declaration location of a resolved field.
void GetResolvedFieldDexFileLocation(
- mirror::ArtField* resolved_field, const DexFile** declaring_dex_file,
+ ArtField* resolved_field, const DexFile** declaring_dex_file,
uint16_t* declaring_class_idx, uint16_t* declaring_field_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsFieldVolatile(mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- MemberOffset GetFieldOffset(mirror::ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool IsFieldVolatile(ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ MemberOffset GetFieldOffset(ArtField* field) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Find a dex cache for a dex file.
inline mirror::DexCache* FindDexCache(const DexFile* dex_file)
@@ -268,23 +268,23 @@ class CompilerDriver {
// Can we fast-path an IGET/IPUT access to an instance field? If yes, compute the field offset.
std::pair<bool, bool> IsFastInstanceField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
- mirror::ArtField* resolved_field, uint16_t field_idx)
+ ArtField* resolved_field, uint16_t field_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Can we fast-path an SGET/SPUT access to a static field? If yes, compute the type index
// of the declaring class in the referrer's dex file.
std::pair<bool, bool> IsFastStaticField(
mirror::DexCache* dex_cache, mirror::Class* referrer_class,
- mirror::ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index)
+ ArtField* resolved_field, uint16_t field_idx, uint32_t* storage_index)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Is static field's in referrer's class?
- bool IsStaticFieldInReferrerClass(mirror::Class* referrer_class, mirror::ArtField* resolved_field)
+ bool IsStaticFieldInReferrerClass(mirror::Class* referrer_class, ArtField* resolved_field)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Is static field's class initialized?
bool IsStaticFieldsClassInitialized(mirror::Class* referrer_class,
- mirror::ArtField* resolved_field)
+ ArtField* resolved_field)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a method. Returns nullptr on failure, including incompatible class change.
@@ -331,7 +331,7 @@ class CompilerDriver {
void ComputeFieldInfo(uint32_t field_idx, const DexCompilationUnit* mUnit,
const ScopedObjectAccess& soa, bool is_static,
- mirror::ArtField** resolved_field,
+ ArtField** resolved_field,
mirror::Class** referrer_class,
mirror::DexCache** dex_cache)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -341,7 +341,7 @@ class CompilerDriver {
MemberOffset* field_offset, bool* is_volatile)
LOCKS_EXCLUDED(Locks::mutator_lock_);
- mirror::ArtField* ComputeInstanceFieldInfo(uint32_t field_idx,
+ ArtField* ComputeInstanceFieldInfo(uint32_t field_idx,
const DexCompilationUnit* mUnit,
bool is_put,
const ScopedObjectAccess& soa)
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 5ebc029fcf..7200cdaa9f 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -132,7 +132,7 @@ TEST_F(CompilerDriverTest, DISABLED_LARGE_CompileDexLibCore) {
}
EXPECT_EQ(dex.NumFieldIds(), dex_cache->NumResolvedFields());
for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
- mirror::ArtField* field = dex_cache->GetResolvedField(i);
+ ArtField* field = Runtime::Current()->GetClassLinker()->GetResolvedField(i, dex_cache);
EXPECT_TRUE(field != NULL) << "field_idx=" << i
<< " " << dex.GetFieldDeclaringClassDescriptor(dex.GetFieldId(i))
<< " " << dex.GetFieldName(dex.GetFieldId(i));
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index cf979430ad..627a42e8de 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -205,6 +205,7 @@ TEST_F(ImageTest, ImageHeaderIsValid) {
uint32_t oat_file_end = ART_BASE_ADDRESS + (10 * KB);
ImageHeader image_header(image_begin,
image_size_,
+ 0u, 0u,
image_bitmap_offset,
image_bitmap_size,
image_roots,
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 1ede228c4f..6f8884a9ab 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -22,6 +22,7 @@
#include <numeric>
#include <vector>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
@@ -40,8 +41,8 @@
#include "globals.h"
#include "image.h"
#include "intern_table.h"
+#include "linear_alloc.h"
#include "lock_word.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
@@ -57,7 +58,6 @@
#include "handle_scope-inl.h"
#include "utils/dex_cache_arrays_layout-inl.h"
-using ::art::mirror::ArtField;
using ::art::mirror::ArtMethod;
using ::art::mirror::Class;
using ::art::mirror::DexCache;
@@ -164,6 +164,9 @@ bool ImageWriter::Write(const std::string& image_filename,
Thread::Current()->TransitionFromSuspendedToRunnable();
CreateHeader(oat_loaded_size, oat_data_offset);
+ // TODO: heap validation can't handle these fix up passes.
+ Runtime::Current()->GetHeap()->DisableObjectValidation();
+ CopyAndFixupNativeData();
CopyAndFixupObjects();
Thread::Current()->TransitionFromRunnableToSuspended(kNative);
@@ -186,9 +189,10 @@ bool ImageWriter::Write(const std::string& image_filename,
return EXIT_FAILURE;
}
- // Write out the image.
+ // Write out the image + fields.
+ const auto write_count = image_header->GetImageSize() + image_header->GetArtFieldsSize();
CHECK_EQ(image_end_, image_header->GetImageSize());
- if (!image_file->WriteFully(image_->Begin(), image_end_)) {
+ if (!image_file->WriteFully(image_->Begin(), write_count)) {
PLOG(ERROR) << "Failed to write image file " << image_filename;
image_file->Erase();
return false;
@@ -204,6 +208,8 @@ bool ImageWriter::Write(const std::string& image_filename,
return false;
}
+ CHECK_EQ(image_header->GetImageBitmapOffset() + image_header->GetImageBitmapSize(),
+ static_cast<size_t>(image_file->GetLength()));
if (image_file->FlushCloseOrErase() != 0) {
PLOG(ERROR) << "Failed to flush and close image file " << image_filename;
return false;
@@ -219,6 +225,8 @@ void ImageWriter::SetImageOffset(mirror::Object* object,
mirror::Object* obj = reinterpret_cast<mirror::Object*>(image_->Begin() + offset);
DCHECK_ALIGNED(obj, kObjectAlignment);
+ static size_t max_offset = 0;
+ max_offset = std::max(max_offset, offset);
image_bitmap_->Set(obj); // Mark the obj as mutated, since we will end up changing it.
{
// Remember the object-inside-of-the-image's hash code so we can restore it after the copy.
@@ -302,13 +310,26 @@ void ImageWriter::PrepareDexCacheArraySlots() {
DexCache* dex_cache = class_linker->GetDexCache(idx);
const DexFile* dex_file = dex_cache->GetDexFile();
dex_cache_array_starts_.Put(dex_file, size);
- DexCacheArraysLayout layout(dex_file);
+ DexCacheArraysLayout layout(target_ptr_size_, dex_file);
DCHECK(layout.Valid());
- dex_cache_array_indexes_.Put(dex_cache->GetResolvedTypes(), size + layout.TypesOffset());
- dex_cache_array_indexes_.Put(dex_cache->GetResolvedMethods(), size + layout.MethodsOffset());
- dex_cache_array_indexes_.Put(dex_cache->GetResolvedFields(), size + layout.FieldsOffset());
- dex_cache_array_indexes_.Put(dex_cache->GetStrings(), size + layout.StringsOffset());
+ auto types_size = layout.TypesSize(dex_file->NumTypeIds());
+ auto methods_size = layout.MethodsSize(dex_file->NumMethodIds());
+ auto fields_size = layout.FieldsSize(dex_file->NumFieldIds());
+ auto strings_size = layout.StringsSize(dex_file->NumStringIds());
+ dex_cache_array_indexes_.Put(
+ dex_cache->GetResolvedTypes(),
+ DexCacheArrayLocation {size + layout.TypesOffset(), types_size});
+ dex_cache_array_indexes_.Put(
+ dex_cache->GetResolvedMethods(),
+ DexCacheArrayLocation {size + layout.MethodsOffset(), methods_size});
+ dex_cache_array_indexes_.Put(
+ dex_cache->GetResolvedFields(),
+ DexCacheArrayLocation {size + layout.FieldsOffset(), fields_size});
+ dex_cache_array_indexes_.Put(
+ dex_cache->GetStrings(),
+ DexCacheArrayLocation {size + layout.StringsOffset(), strings_size});
size += layout.Size();
+ CHECK_EQ(layout.Size(), types_size + methods_size + fields_size + strings_size);
}
// Set the slot size early to avoid DCHECK() failures in IsImageBinSlotAssigned()
// when AssignImageBinSlot() assigns their indexes out or order.
@@ -405,12 +426,20 @@ void ImageWriter::AssignImageBinSlot(mirror::Object* object) {
}
} else if (object->GetClass<kVerifyNone>()->IsStringClass()) {
bin = kBinString; // Strings are almost always immutable (except for object header).
- } else if (object->IsObjectArray()) {
- auto it = dex_cache_array_indexes_.find(object);
- if (it != dex_cache_array_indexes_.end()) {
- bin = kBinDexCacheArray;
- current_offset = it->second; // Use prepared offset defined by the DexCacheLayout.
- } // else bin = kBinRegular
+ } else if (object->IsArrayInstance()) {
+ mirror::Class* klass = object->GetClass<kVerifyNone>();
+ auto* component_type = klass->GetComponentType();
+ if (!component_type->IsPrimitive() || component_type->IsPrimitiveInt() ||
+ component_type->IsPrimitiveLong()) {
+ auto it = dex_cache_array_indexes_.find(object);
+ if (it != dex_cache_array_indexes_.end()) {
+ bin = kBinDexCacheArray;
+ // Use prepared offset defined by the DexCacheLayout.
+ current_offset = it->second.offset_;
+ // Override incase of cross compilation.
+ object_size = it->second.length_;
+ } // else bin = kBinRegular
+ }
} // else bin = kBinRegular
}
@@ -465,7 +494,10 @@ ImageWriter::BinSlot ImageWriter::GetImageBinSlot(mirror::Object* object) const
}
bool ImageWriter::AllocMemory() {
- size_t length = RoundUp(Runtime::Current()->GetHeap()->GetTotalMemory(), kPageSize);
+ auto* runtime = Runtime::Current();
+ const size_t heap_size = runtime->GetHeap()->GetTotalMemory();
+ // Add linear alloc usage since we need to have room for the ArtFields.
+ const size_t length = RoundUp(heap_size + runtime->GetLinearAlloc()->GetUsedMemory(), kPageSize);
std::string error_msg;
image_.reset(MemMap::MapAnonymous("image writer image", nullptr, length, PROT_READ | PROT_WRITE,
false, false, &error_msg));
@@ -476,7 +508,7 @@ bool ImageWriter::AllocMemory() {
// Create the image bitmap.
image_bitmap_.reset(gc::accounting::ContinuousSpaceBitmap::Create("image bitmap", image_->Begin(),
- length));
+ RoundUp(length, kPageSize)));
if (image_bitmap_.get() == nullptr) {
LOG(ERROR) << "Failed to allocate memory for image bitmap";
return false;
@@ -698,9 +730,9 @@ void ImageWriter::PruneNonImageClasses() {
}
}
for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
- ArtField* field = dex_cache->GetResolvedField(i);
- if (field != NULL && !IsImageClass(field->GetDeclaringClass())) {
- dex_cache->SetResolvedField(i, NULL);
+ ArtField* field = dex_cache->GetResolvedField(i, sizeof(void*));
+ if (field != nullptr && !IsImageClass(field->GetDeclaringClass())) {
+ dex_cache->SetResolvedField(i, nullptr, sizeof(void*));
}
}
// Clean the dex field. It might have been populated during the initialization phase, but
@@ -786,7 +818,7 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const {
// caches. We check that the number of dex caches does not change.
size_t dex_cache_count;
{
- ReaderMutexLock mu(Thread::Current(), *class_linker->DexLock());
+ ReaderMutexLock mu(self, *class_linker->DexLock());
dex_cache_count = class_linker->GetDexCacheCount();
}
Handle<ObjectArray<Object>> dex_caches(
@@ -794,7 +826,7 @@ ObjectArray<Object>* ImageWriter::CreateImageRoots() const {
dex_cache_count)));
CHECK(dex_caches.Get() != nullptr) << "Failed to allocate a dex cache array.";
{
- ReaderMutexLock mu(Thread::Current(), *class_linker->DexLock());
+ ReaderMutexLock mu(self, *class_linker->DexLock());
CHECK_EQ(dex_cache_count, class_linker->GetDexCacheCount())
<< "The number of dex caches changed.";
for (size_t i = 0; i < dex_cache_count; ++i) {
@@ -861,9 +893,9 @@ void ImageWriter::WalkFieldsInOrder(mirror::Object* obj) {
WalkInstanceFields(h_obj.Get(), klass.Get());
// Walk static fields of a Class.
if (h_obj->IsClass()) {
- size_t num_static_fields = klass->NumReferenceStaticFields();
+ size_t num_reference_static_fields = klass->NumReferenceStaticFields();
MemberOffset field_offset = klass->GetFirstReferenceStaticFieldOffset();
- for (size_t i = 0; i < num_static_fields; ++i) {
+ for (size_t i = 0; i < num_reference_static_fields; ++i) {
mirror::Object* value = h_obj->GetFieldObject<mirror::Object>(field_offset);
if (value != nullptr) {
WalkFieldsInOrder(value);
@@ -871,6 +903,21 @@ void ImageWriter::WalkFieldsInOrder(mirror::Object* obj) {
field_offset = MemberOffset(field_offset.Uint32Value() +
sizeof(mirror::HeapReference<mirror::Object>));
}
+
+ // Visit and assign offsets for fields.
+ ArtField* fields[2] = { h_obj->AsClass()->GetSFields(), h_obj->AsClass()->GetIFields() };
+ size_t num_fields[2] = { h_obj->AsClass()->NumStaticFields(),
+ h_obj->AsClass()->NumInstanceFields() };
+ for (size_t i = 0; i < 2; ++i) {
+ for (size_t j = 0; j < num_fields[i]; ++j) {
+ auto* field = fields[i] + j;
+ auto it = art_field_reloc_.find(field);
+ CHECK(it == art_field_reloc_.end()) << "Field at index " << i << ":" << j
+ << " already assigned " << PrettyField(field);
+ art_field_reloc_.emplace(field, bin_slot_sizes_[kBinArtField]);
+ bin_slot_sizes_[kBinArtField] += sizeof(ArtField);
+ }
+ }
} else if (h_obj->IsObjectArray()) {
// Walk elements of an object array.
int32_t length = h_obj->AsObjectArray<mirror::Object>()->GetLength();
@@ -921,7 +968,6 @@ void ImageWriter::CalculateNewObjectOffsets() {
// know where image_roots is going to end up
image_end_ += RoundUp(sizeof(ImageHeader), kObjectAlignment); // 64-bit-alignment
- // TODO: Image spaces only?
DCHECK_LT(image_end_, image_->Size());
image_objects_offset_begin_ = image_end_;
// Prepare bin slots for dex cache arrays.
@@ -935,34 +981,47 @@ void ImageWriter::CalculateNewObjectOffsets() {
previous_sizes += bin_slot_sizes_[i];
}
DCHECK_EQ(previous_sizes, GetBinSizeSum());
+ DCHECK_EQ(image_end_, GetBinSizeSum(kBinMirrorCount) + image_objects_offset_begin_);
+
// Transform each object's bin slot into an offset which will be used to do the final copy.
heap->VisitObjects(UnbinObjectsIntoOffsetCallback, this);
DCHECK(saved_hashes_map_.empty()); // All binslot hashes should've been put into vector by now.
- DCHECK_GT(image_end_, GetBinSizeSum());
+ DCHECK_EQ(image_end_, GetBinSizeSum(kBinMirrorCount) + image_objects_offset_begin_);
image_roots_address_ = PointerToLowMemUInt32(GetImageAddress(image_roots.Get()));
- // Note that image_end_ is left at end of used space
+ // Note that image_end_ is left at end of used mirror space
}
void ImageWriter::CreateHeader(size_t oat_loaded_size, size_t oat_data_offset) {
CHECK_NE(0U, oat_loaded_size);
const uint8_t* oat_file_begin = GetOatFileBegin();
const uint8_t* oat_file_end = oat_file_begin + oat_loaded_size;
-
oat_data_begin_ = oat_file_begin + oat_data_offset;
const uint8_t* oat_data_end = oat_data_begin_ + oat_file_->Size();
-
+ // Write out sections.
+ size_t cur_pos = image_end_;
+ // Add fields.
+ auto fields_offset = cur_pos;
+ CHECK_EQ(image_objects_offset_begin_ + GetBinSizeSum(kBinArtField), fields_offset);
+ auto fields_size = bin_slot_sizes_[kBinArtField];
+ cur_pos += fields_size;
// Return to write header at start of image with future location of image_roots. At this point,
- // image_end_ is the size of the image (excluding bitmaps).
+ // image_end_ is the size of the image (excluding bitmaps, ArtFields).
+ /*
const size_t heap_bytes_per_bitmap_byte = kBitsPerByte * kObjectAlignment;
const size_t bitmap_bytes = RoundUp(image_end_, heap_bytes_per_bitmap_byte) /
heap_bytes_per_bitmap_byte;
+ */
+ const size_t bitmap_bytes = image_bitmap_->Size();
+ auto bitmap_offset = RoundUp(cur_pos, kPageSize);
+ auto bitmap_size = RoundUp(bitmap_bytes, kPageSize);
+ cur_pos += bitmap_size;
new (image_->Begin()) ImageHeader(PointerToLowMemUInt32(image_begin_),
static_cast<uint32_t>(image_end_),
- RoundUp(image_end_, kPageSize),
- RoundUp(bitmap_bytes, kPageSize),
+ fields_offset, fields_size,
+ bitmap_offset, bitmap_size,
image_roots_address_,
oat_file_->GetOatHeader().GetChecksum(),
PointerToLowMemUInt32(oat_file_begin),
@@ -972,11 +1031,21 @@ void ImageWriter::CreateHeader(size_t oat_loaded_size, size_t oat_data_offset) {
compile_pic_);
}
+void ImageWriter::CopyAndFixupNativeData() {
+ // Copy ArtFields to their locations and update the array for convenience.
+ auto fields_offset = image_objects_offset_begin_ + GetBinSizeSum(kBinArtField);
+ for (auto& pair : art_field_reloc_) {
+ pair.second += fields_offset;
+ auto* dest = image_->Begin() + pair.second;
+ DCHECK_GE(dest, image_->Begin() + image_end_);
+ memcpy(dest, pair.first, sizeof(ArtField));
+ reinterpret_cast<ArtField*>(dest)->SetDeclaringClass(
+ down_cast<Class*>(GetImageAddress(pair.first->GetDeclaringClass())));
+ }
+}
+
void ImageWriter::CopyAndFixupObjects() {
gc::Heap* heap = Runtime::Current()->GetHeap();
- // TODO: heap validation can't handle this fix up pass
- heap->DisableObjectValidation();
- // TODO: Image spaces only?
heap->VisitObjects(CopyAndFixupObjectsCallback, this);
// Fix up the object previously had hash codes.
for (const std::pair<mirror::Object*, uint32_t>& hash_pair : saved_hashes_) {
@@ -990,26 +1059,88 @@ void ImageWriter::CopyAndFixupObjects() {
void ImageWriter::CopyAndFixupObjectsCallback(Object* obj, void* arg) {
DCHECK(obj != nullptr);
DCHECK(arg != nullptr);
- ImageWriter* image_writer = reinterpret_cast<ImageWriter*>(arg);
+ reinterpret_cast<ImageWriter*>(arg)->CopyAndFixupObject(obj);
+}
+
+bool ImageWriter::CopyAndFixupIfDexCacheFieldArray(mirror::Object* dst, mirror::Object* obj,
+ mirror::Class* klass) {
+ if (!klass->IsArrayClass()) {
+ return false;
+ }
+ auto* component_type = klass->GetComponentType();
+ bool is_int_arr = component_type->IsPrimitiveInt();
+ bool is_long_arr = component_type->IsPrimitiveLong();
+ if (!is_int_arr && !is_long_arr) {
+ return false;
+ }
+ auto it = dex_cache_array_indexes_.find(obj); // Is this a dex cache array?
+ if (it == dex_cache_array_indexes_.end()) {
+ return false;
+ }
+ mirror::Array* arr = obj->AsArray();
+ CHECK_EQ(reinterpret_cast<Object*>(
+ image_->Begin() + it->second.offset_ + image_objects_offset_begin_), dst);
+ dex_cache_array_indexes_.erase(it);
+ // Fixup int pointers for the field array.
+ CHECK(!arr->IsObjectArray());
+ const size_t num_elements = arr->GetLength();
+ if (target_ptr_size_ == 4) {
+ // Will get fixed up by fixup object.
+ dst->SetClass(down_cast<mirror::Class*>(
+ GetImageAddress(mirror::IntArray::GetArrayClass())));
+ } else {
+ DCHECK_EQ(target_ptr_size_, 8u);
+ dst->SetClass(down_cast<mirror::Class*>(
+ GetImageAddress(mirror::LongArray::GetArrayClass())));
+ }
+ mirror::Array* dest_array = down_cast<mirror::Array*>(dst);
+ dest_array->SetLength(num_elements);
+ for (size_t i = 0, count = num_elements; i < count; ++i) {
+ ArtField* field = reinterpret_cast<ArtField*>(is_int_arr ?
+ arr->AsIntArray()->GetWithoutChecks(i) : arr->AsLongArray()->GetWithoutChecks(i));
+ uint8_t* fixup_location = nullptr;
+ if (field != nullptr) {
+ auto it2 = art_field_reloc_.find(field);
+ CHECK(it2 != art_field_reloc_.end()) << "No relocation for field " << PrettyField(field);
+ fixup_location = image_begin_ + it2->second;
+ }
+ if (target_ptr_size_ == 4) {
+ down_cast<mirror::IntArray*>(dest_array)->SetWithoutChecks<kVerifyNone>(
+ i, static_cast<uint32_t>(reinterpret_cast<uint64_t>(fixup_location)));
+ } else {
+ down_cast<mirror::LongArray*>(dest_array)->SetWithoutChecks<kVerifyNone>(
+ i, reinterpret_cast<uint64_t>(fixup_location));
+ }
+ }
+ dst->SetLockWord(LockWord::Default(), false);
+ return true;
+}
+
+void ImageWriter::CopyAndFixupObject(Object* obj) {
// see GetLocalAddress for similar computation
- size_t offset = image_writer->GetImageOffset(obj);
- uint8_t* dst = image_writer->image_->Begin() + offset;
+ size_t offset = GetImageOffset(obj);
+ auto* dst = reinterpret_cast<Object*>(image_->Begin() + offset);
const uint8_t* src = reinterpret_cast<const uint8_t*>(obj);
size_t n;
- if (obj->IsArtMethod()) {
+ mirror::Class* klass = obj->GetClass();
+
+ if (CopyAndFixupIfDexCacheFieldArray(dst, obj, klass)) {
+ return;
+ }
+ if (klass->IsArtMethodClass()) {
// Size without pointer fields since we don't want to overrun the buffer if target art method
// is 32 bits but source is 64 bits.
- n = mirror::ArtMethod::SizeWithoutPointerFields(image_writer->target_ptr_size_);
+ n = mirror::ArtMethod::SizeWithoutPointerFields(target_ptr_size_);
} else {
n = obj->SizeOf();
}
- DCHECK_LT(offset + n, image_writer->image_->Size());
+ DCHECK_LE(offset + n, image_->Size());
memcpy(dst, src, n);
- Object* copy = reinterpret_cast<Object*>(dst);
+
// Write in a hash code of objects which have inflated monitors or a hash code in their monitor
// word.
- copy->SetLockWord(LockWord::Default(), false);
- image_writer->FixupObject(obj, copy);
+ dst->SetLockWord(LockWord::Default(), false);
+ FixupObject(obj, dst);
}
// Rewrite all the references in the copied object to point to their image address equivalent
@@ -1045,15 +1176,10 @@ class FixupClassVisitor FINAL : public FixupVisitor {
FixupClassVisitor(ImageWriter* image_writer, Object* copy) : FixupVisitor(image_writer, copy) {
}
- void operator()(Object* obj, MemberOffset offset, bool /*is_static*/) const
+ void operator()(Object* obj, MemberOffset offset, bool is_static ATTRIBUTE_UNUSED) const
EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
DCHECK(obj->IsClass());
FixupVisitor::operator()(obj, offset, /*is_static*/false);
-
- // TODO: Remove dead code
- if (offset.Uint32Value() < mirror::Class::EmbeddedVTableOffset().Uint32Value()) {
- return;
- }
}
void operator()(mirror::Class* klass ATTRIBUTE_UNUSED,
@@ -1064,6 +1190,31 @@ class FixupClassVisitor FINAL : public FixupVisitor {
}
};
+void ImageWriter::FixupClass(mirror::Class* orig, mirror::Class* copy) {
+ // Copy and fix up ArtFields in the class.
+ ArtField* fields[2] = { orig->AsClass()->GetSFields(), orig->AsClass()->GetIFields() };
+ size_t num_fields[2] = { orig->AsClass()->NumStaticFields(),
+ orig->AsClass()->NumInstanceFields() };
+ // Update the arrays.
+ for (size_t i = 0; i < 2; ++i) {
+ if (num_fields[i] == 0) {
+ CHECK(fields[i] == nullptr);
+ continue;
+ }
+ auto it = art_field_reloc_.find(fields[i]);
+ CHECK(it != art_field_reloc_.end()) << PrettyClass(orig->AsClass()) << " : "
+ << PrettyField(fields[i]);
+ auto* image_fields = reinterpret_cast<ArtField*>(image_begin_ + it->second);
+ if (i == 0) {
+ down_cast<Class*>(copy)->SetSFieldsUnchecked(image_fields);
+ } else {
+ down_cast<Class*>(copy)->SetIFieldsUnchecked(image_fields);
+ }
+ }
+ FixupClassVisitor visitor(this, copy);
+ static_cast<mirror::Object*>(orig)->VisitReferences<true /*visit class*/>(visitor, visitor);
+}
+
void ImageWriter::FixupObject(Object* orig, Object* copy) {
DCHECK(orig != nullptr);
DCHECK(copy != nullptr);
@@ -1075,9 +1226,8 @@ void ImageWriter::FixupObject(Object* orig, Object* copy) {
DCHECK_EQ(copy->GetReadBarrierPointer(), GetImageAddress(orig));
}
}
- if (orig->IsClass() && orig->AsClass()->ShouldHaveEmbeddedImtAndVTable()) {
- FixupClassVisitor visitor(this, copy);
- orig->VisitReferences<true /*visit class*/>(visitor, visitor);
+ if (orig->IsClass()) {
+ FixupClass(orig->AsClass<kVerifyNone>(), down_cast<mirror::Class*>(copy));
} else {
FixupVisitor visitor(this, copy);
orig->VisitReferences<true /*visit class*/>(visitor, visitor);
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index 71044f7b6e..a2d99eeb96 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -90,7 +90,7 @@ class ImageWriter FINAL {
}
uint8_t* GetOatFileBegin() const {
- return image_begin_ + RoundUp(image_end_, kPageSize);
+ return image_begin_ + RoundUp(image_end_ + bin_slot_sizes_[kBinArtField], kPageSize);
}
bool Write(const std::string& image_filename,
@@ -127,12 +127,16 @@ class ImageWriter FINAL {
kBinArtMethodNative, // Art method that is actually native
kBinArtMethodNotInitialized, // Art method with a declaring class that wasn't initialized
// Add more bins here if we add more segregation code.
+ // Non mirror fields must be below. ArtFields should be always clean.
+ kBinArtField,
kBinSize,
+ // Number of bins which are for mirror objects.
+ kBinMirrorCount = kBinArtField,
};
friend std::ostream& operator<<(std::ostream& stream, const Bin& bin);
- static constexpr size_t kBinBits = MinimumBitsToStore(kBinSize - 1);
+ static constexpr size_t kBinBits = MinimumBitsToStore(kBinMirrorCount - 1);
// uint32 = typeof(lockword_)
static constexpr size_t kBinShift = BitSizeOf<uint32_t>() - kBinBits;
// 111000.....0
@@ -251,11 +255,18 @@ class ImageWriter FINAL {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Creates the contiguous image in memory and adjusts pointers.
+ void CopyAndFixupNativeData() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void CopyAndFixupObjects() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void CopyAndFixupObject(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool CopyAndFixupIfDexCacheFieldArray(mirror::Object* dst, mirror::Object* obj,
+ mirror::Class* klass)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupMethod(mirror::ArtMethod* orig, mirror::ArtMethod* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void FixupClass(mirror::Class* orig, mirror::Class* copy)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FixupObject(mirror::Object* orig, mirror::Object* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -295,8 +306,13 @@ class ImageWriter FINAL {
// Memory mapped for generating the image.
std::unique_ptr<MemMap> image_;
- // Indexes for dex cache arrays (objects are inside of the image so that they don't move).
- SafeMap<mirror::Object*, size_t> dex_cache_array_indexes_;
+ // Indexes, lengths for dex cache arrays (objects are inside of the image so that they don't
+ // move).
+ struct DexCacheArrayLocation {
+ size_t offset_;
+ size_t length_;
+ };
+ SafeMap<mirror::Object*, DexCacheArrayLocation> dex_cache_array_indexes_;
// The start offsets of the dex cache arrays.
SafeMap<const DexFile*, size_t> dex_cache_array_starts_;
@@ -331,6 +347,11 @@ class ImageWriter FINAL {
size_t bin_slot_previous_sizes_[kBinSize]; // Number of bytes in previous bins.
size_t bin_slot_count_[kBinSize]; // Number of objects in a bin
+ // ArtField relocating map, ArtFields are allocated as array of structs but we want to have one
+ // entry per art field for convenience.
+ // ArtFields are placed right after the end of the image objects (aka sum of bin_slot_sizes_).
+ std::unordered_map<ArtField*, uintptr_t> art_field_reloc_;
+
void* string_data_array_; // The backing for the interned strings.
friend class FixupVisitor;
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index a912d4ccc4..8a64d81485 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -16,16 +16,13 @@
#include "builder.h"
+#include "art_field-inl.h"
#include "base/logging.h"
#include "class_linker.h"
-#include "dex_file.h"
#include "dex_file-inl.h"
-#include "dex_instruction.h"
#include "dex_instruction-inl.h"
#include "driver/compiler_driver-inl.h"
#include "driver/compiler_options.h"
-#include "mirror/art_field.h"
-#include "mirror/art_field-inl.h"
#include "mirror/class_loader.h"
#include "mirror/dex_cache.h"
#include "nodes.h"
@@ -656,11 +653,10 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
uint16_t field_index = instruction.VRegC_22c();
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<1> hs(soa.Self());
- Handle<mirror::ArtField> resolved_field(hs.NewHandle(
- compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa)));
+ ArtField* resolved_field =
+ compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa);
- if (resolved_field.Get() == nullptr) {
+ if (resolved_field == nullptr) {
MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
return false;
}
@@ -728,15 +724,15 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
uint16_t field_index = instruction.VRegB_21c();
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<5> hs(soa.Self());
+ StackHandleScope<4> hs(soa.Self());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(
dex_compilation_unit_->GetClassLinker()->FindDexCache(*dex_compilation_unit_->GetDexFile())));
Handle<mirror::ClassLoader> class_loader(hs.NewHandle(
soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader())));
- Handle<mirror::ArtField> resolved_field(hs.NewHandle(compiler_driver_->ResolveField(
- soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true)));
+ ArtField* resolved_field = compiler_driver_->ResolveField(
+ soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true);
- if (resolved_field.Get() == nullptr) {
+ if (resolved_field == nullptr) {
MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
return false;
}
@@ -758,7 +754,7 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
std::pair<bool, bool> pair = compiler_driver_->IsFastStaticField(
outer_dex_cache.Get(),
referrer_class.Get(),
- resolved_field.Get(),
+ resolved_field,
field_index,
&storage_index);
bool can_easily_access = is_put ? pair.second : pair.first;
diff --git a/compiler/utils/dex_cache_arrays_layout-inl.h b/compiler/utils/dex_cache_arrays_layout-inl.h
index 7d02ce35d8..2c50c96305 100644
--- a/compiler/utils/dex_cache_arrays_layout-inl.h
+++ b/compiler/utils/dex_cache_arrays_layout-inl.h
@@ -26,7 +26,6 @@
#include "utils.h"
namespace mirror {
-class ArtField;
class ArtMethod;
class Class;
class String;
@@ -34,40 +33,55 @@ class String;
namespace art {
-inline DexCacheArraysLayout::DexCacheArraysLayout(const DexFile* dex_file)
+inline DexCacheArraysLayout::DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file)
: /* types_offset_ is always 0u */
- methods_offset_(types_offset_ + ArraySize<mirror::Class>(dex_file->NumTypeIds())),
- strings_offset_(methods_offset_ + ArraySize<mirror::ArtMethod>(dex_file->NumMethodIds())),
- fields_offset_(strings_offset_ + ArraySize<mirror::String>(dex_file->NumStringIds())),
- size_(fields_offset_ + ArraySize<mirror::ArtField>(dex_file->NumFieldIds())) {
+ pointer_size_(pointer_size),
+ methods_offset_(types_offset_ + TypesSize(dex_file->NumTypeIds())),
+ strings_offset_(methods_offset_ + MethodsSize(dex_file->NumMethodIds())),
+ fields_offset_(strings_offset_ + StringsSize(dex_file->NumStringIds())),
+ size_(fields_offset_ + FieldsSize(dex_file->NumFieldIds())) {
+ DCHECK(pointer_size == 4u || pointer_size == 8u);
}
inline size_t DexCacheArraysLayout::TypeOffset(uint32_t type_idx) const {
- return types_offset_ + ElementOffset<mirror::Class>(type_idx);
+ return types_offset_ + ElementOffset(sizeof(mirror::HeapReference<mirror::Class>), type_idx);
+}
+
+inline size_t DexCacheArraysLayout::TypesSize(size_t num_elements) const {
+ return ArraySize(sizeof(mirror::HeapReference<mirror::Class>), num_elements);
}
inline size_t DexCacheArraysLayout::MethodOffset(uint32_t method_idx) const {
- return methods_offset_ + ElementOffset<mirror::ArtMethod>(method_idx);
+ return methods_offset_ + ElementOffset(
+ sizeof(mirror::HeapReference<mirror::ArtMethod>), method_idx);
+}
+
+inline size_t DexCacheArraysLayout::MethodsSize(size_t num_elements) const {
+ return ArraySize(sizeof(mirror::HeapReference<mirror::ArtMethod>), num_elements);
}
inline size_t DexCacheArraysLayout::StringOffset(uint32_t string_idx) const {
- return strings_offset_ + ElementOffset<mirror::String>(string_idx);
+ return strings_offset_ + ElementOffset(sizeof(mirror::HeapReference<mirror::String>), string_idx);
+}
+
+inline size_t DexCacheArraysLayout::StringsSize(size_t num_elements) const {
+ return ArraySize(sizeof(mirror::HeapReference<mirror::String>), num_elements);
}
inline size_t DexCacheArraysLayout::FieldOffset(uint32_t field_idx) const {
- return fields_offset_ + ElementOffset<mirror::ArtField>(field_idx);
+ return fields_offset_ + ElementOffset(pointer_size_, field_idx);
+}
+
+inline size_t DexCacheArraysLayout::FieldsSize(size_t num_elements) const {
+ return ArraySize(pointer_size_, num_elements);
}
-template <typename MirrorType>
-inline size_t DexCacheArraysLayout::ElementOffset(uint32_t idx) {
- return mirror::Array::DataOffset(sizeof(mirror::HeapReference<MirrorType>)).Uint32Value() +
- sizeof(mirror::HeapReference<MirrorType>) * idx;
+inline size_t DexCacheArraysLayout::ElementOffset(size_t element_size, uint32_t idx) {
+ return mirror::Array::DataOffset(element_size).Uint32Value() + element_size * idx;
}
-template <typename MirrorType>
-inline size_t DexCacheArraysLayout::ArraySize(uint32_t num_elements) {
- size_t array_size = mirror::ComputeArraySize(
- num_elements, ComponentSizeShiftWidth<sizeof(mirror::HeapReference<MirrorType>)>());
+inline size_t DexCacheArraysLayout::ArraySize(size_t element_size, uint32_t num_elements) {
+ size_t array_size = mirror::ComputeArraySize(num_elements, ComponentSizeShiftWidth(element_size));
DCHECK_NE(array_size, 0u); // No overflow expected for dex cache arrays.
return RoundUp(array_size, kObjectAlignment);
}
diff --git a/compiler/utils/dex_cache_arrays_layout.h b/compiler/utils/dex_cache_arrays_layout.h
index b461256f63..8f98ea11ba 100644
--- a/compiler/utils/dex_cache_arrays_layout.h
+++ b/compiler/utils/dex_cache_arrays_layout.h
@@ -29,6 +29,7 @@ class DexCacheArraysLayout {
// Construct an invalid layout.
DexCacheArraysLayout()
: /* types_offset_ is always 0u */
+ pointer_size_(0u),
methods_offset_(0u),
strings_offset_(0u),
fields_offset_(0u),
@@ -36,7 +37,7 @@ class DexCacheArraysLayout {
}
// Construct a layout for a particular dex file.
- explicit DexCacheArraysLayout(const DexFile* dex_file);
+ explicit DexCacheArraysLayout(size_t pointer_size, const DexFile* dex_file);
bool Valid() const {
return Size() != 0u;
@@ -52,36 +53,43 @@ class DexCacheArraysLayout {
size_t TypeOffset(uint32_t type_idx) const;
+ size_t TypesSize(size_t num_elements) const;
+
size_t MethodsOffset() const {
return methods_offset_;
}
size_t MethodOffset(uint32_t method_idx) const;
+ size_t MethodsSize(size_t num_elements) const;
+
size_t StringsOffset() const {
return strings_offset_;
}
size_t StringOffset(uint32_t string_idx) const;
+ size_t StringsSize(size_t num_elements) const;
+
size_t FieldsOffset() const {
return fields_offset_;
}
size_t FieldOffset(uint32_t field_idx) const;
+ size_t FieldsSize(size_t num_elements) const;
+
private:
static constexpr size_t types_offset_ = 0u;
+ const size_t pointer_size_; // Must be first for construction initialization order.
const size_t methods_offset_;
const size_t strings_offset_;
const size_t fields_offset_;
const size_t size_;
- template <typename MirrorType>
- static size_t ElementOffset(uint32_t idx);
+ static size_t ElementOffset(size_t element_size, uint32_t idx);
- template <typename MirrorType>
- static size_t ArraySize(uint32_t num_elements);
+ static size_t ArraySize(size_t element_size, uint32_t num_elements);
};
} // namespace art
diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc
index 9b57ecbbff..34a4c14f07 100644
--- a/imgdiag/imgdiag.cc
+++ b/imgdiag/imgdiag.cc
@@ -168,7 +168,10 @@ class ImgDiagDumper {
<< "\n\n";
const uint8_t* image_begin_unaligned = boot_image_header.GetImageBegin();
- const uint8_t* image_end_unaligned = image_begin_unaligned + boot_image_header.GetImageSize();
+ const uint8_t* image_mirror_end_unaligned = image_begin_unaligned +
+ boot_image_header.GetImageSize();
+ const uint8_t* image_end_unaligned = image_mirror_end_unaligned +
+ boot_image_header.GetArtFieldsSize();
// Adjust range to nearest page
const uint8_t* image_begin = AlignDown(image_begin_unaligned, kPageSize);
@@ -350,7 +353,7 @@ class ImgDiagDumper {
size_t dirty_object_bytes = 0;
{
const uint8_t* begin_image_ptr = image_begin_unaligned;
- const uint8_t* end_image_ptr = image_end_unaligned;
+ const uint8_t* end_image_ptr = image_mirror_end_unaligned;
const uint8_t* current = begin_image_ptr + RoundUp(sizeof(ImageHeader), kObjectAlignment);
while (reinterpret_cast<const uintptr_t>(current)
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 322d3aa8f1..a36e5b1ba0 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -26,6 +26,7 @@
#include <vector>
#include "arch/instruction_set_features.h"
+#include "art_field-inl.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "class_linker-inl.h"
@@ -40,7 +41,6 @@
#include "image.h"
#include "indenter.h"
#include "mapping_table.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
@@ -1549,9 +1549,6 @@ class ImageDumper {
} else if (type->IsClassClass()) {
mirror::Class* klass = value->AsClass();
os << StringPrintf("%p Class: %s\n", klass, PrettyDescriptor(klass).c_str());
- } else if (type->IsArtFieldClass()) {
- mirror::ArtField* field = value->AsArtField();
- os << StringPrintf("%p Field: %s\n", field, PrettyField(field).c_str());
} else if (type->IsArtMethodClass()) {
mirror::ArtMethod* method = value->AsArtMethod();
os << StringPrintf("%p Method: %s\n", method, PrettyMethod(method).c_str());
@@ -1560,7 +1557,7 @@ class ImageDumper {
}
}
- static void PrintField(std::ostream& os, mirror::ArtField* field, mirror::Object* obj)
+ static void PrintField(std::ostream& os, ArtField* field, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
os << StringPrintf("%s: ", field->GetName());
switch (field->GetTypeAsPrimitiveType()) {
@@ -1619,12 +1616,9 @@ class ImageDumper {
if (super != nullptr) {
DumpFields(os, obj, super);
}
- mirror::ObjectArray<mirror::ArtField>* fields = klass->GetIFields();
- if (fields != nullptr) {
- for (int32_t i = 0; i < fields->GetLength(); i++) {
- mirror::ArtField* field = fields->Get(i);
- PrintField(os, field, obj);
- }
+ ArtField* fields = klass->GetIFields();
+ for (size_t i = 0, count = klass->NumInstanceFields(); i < count; i++) {
+ PrintField(os, &fields[i], obj);
}
}
@@ -1686,9 +1680,6 @@ class ImageDumper {
mirror::Class* klass = obj->AsClass();
os << StringPrintf("%p: java.lang.Class \"%s\" (", obj, PrettyDescriptor(klass).c_str())
<< klass->GetStatus() << ")\n";
- } else if (obj->IsArtField()) {
- os << StringPrintf("%p: java.lang.reflect.ArtField %s\n", obj,
- PrettyField(obj->AsArtField()).c_str());
} else if (obj->IsArtMethod()) {
os << StringPrintf("%p: java.lang.reflect.ArtMethod %s\n", obj,
PrettyMethod(obj->AsArtMethod()).c_str());
@@ -1725,14 +1716,15 @@ class ImageDumper {
PrettyObjectValue(indent_os, value_class, value);
}
} else if (obj->IsClass()) {
- mirror::ObjectArray<mirror::ArtField>* sfields = obj->AsClass()->GetSFields();
- if (sfields != nullptr) {
+ mirror::Class* klass = obj->AsClass();
+ ArtField* sfields = klass->GetSFields();
+ const size_t num_fields = klass->NumStaticFields();
+ if (num_fields != 0) {
indent_os << "STATICS:\n";
Indenter indent2_filter(indent_os.rdbuf(), kIndentChar, kIndentBy1Count);
std::ostream indent2_os(&indent2_filter);
- for (int32_t i = 0; i < sfields->GetLength(); i++) {
- mirror::ArtField* field = sfields->Get(i);
- PrintField(indent2_os, field, field->GetDeclaringClass());
+ for (size_t i = 0; i < num_fields; i++) {
+ PrintField(indent2_os, &sfields[i], sfields[i].GetDeclaringClass());
}
}
} else if (obj->IsArtMethod()) {
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 9584064ec1..74c9c38255 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+#include "art_field-inl.h"
#include "base/dumpable.h"
#include "base/scoped_flock.h"
#include "base/stringpiece.h"
@@ -34,7 +35,6 @@
#include "elf_file_impl.h"
#include "gc/space/image_space.h"
#include "image.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/object-inl.h"
#include "mirror/reference.h"
@@ -415,13 +415,64 @@ bool PatchOat::ReplaceOatFileWithSymlink(const std::string& input_oat_filename,
return true;
}
+void PatchOat::PatchArtFields(const ImageHeader* image_header) {
+ const size_t art_field_size = image_header->GetArtFieldsSize();
+ const size_t art_field_offset = image_header->GetArtFieldsOffset();
+ for (size_t pos = 0; pos < art_field_size; pos += sizeof(ArtField)) {
+ auto* field = reinterpret_cast<ArtField*>(heap_->Begin() + art_field_offset + pos);
+ auto* dest_field = RelocatedCopyOf(field);
+ dest_field->SetDeclaringClass(RelocatedAddressOfPointer(field->GetDeclaringClass()));
+ }
+}
+
+void PatchOat::PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots) {
+ auto* dex_caches = down_cast<mirror::ObjectArray<mirror::DexCache>*>(
+ img_roots->Get(ImageHeader::kDexCaches));
+ for (size_t i = 0, count = dex_caches->GetLength(); i < count; ++i) {
+ auto* dex_cache = dex_caches->GetWithoutChecks(i);
+ auto* fields = dex_cache->GetResolvedFields();
+ if (fields == nullptr) {
+ continue;
+ }
+ CHECK(!fields->IsObjectArray());
+ CHECK(fields->IsArrayInstance());
+ auto* component_type = fields->GetClass()->GetComponentType();
+ if (component_type->IsPrimitiveInt()) {
+ mirror::IntArray* arr = fields->AsIntArray();
+ mirror::IntArray* copy_arr = down_cast<mirror::IntArray*>(RelocatedCopyOf(arr));
+ for (size_t j = 0, count2 = arr->GetLength(); j < count2; ++j) {
+ auto f = arr->GetWithoutChecks(j);
+ if (f != 0) {
+ copy_arr->SetWithoutChecks<false>(j, f + delta_);
+ }
+ }
+ } else {
+ CHECK(component_type->IsPrimitiveLong());
+ mirror::LongArray* arr = fields->AsLongArray();
+ mirror::LongArray* copy_arr = down_cast<mirror::LongArray*>(RelocatedCopyOf(arr));
+ for (size_t j = 0, count2 = arr->GetLength(); j < count2; ++j) {
+ auto f = arr->GetWithoutChecks(j);
+ if (f != 0) {
+ copy_arr->SetWithoutChecks<false>(j, f + delta_);
+ }
+ }
+ }
+ }
+}
+
bool PatchOat::PatchImage() {
ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin());
CHECK_GT(image_->Size(), sizeof(ImageHeader));
// These are the roots from the original file.
- mirror::Object* img_roots = image_header->GetImageRoots();
+ auto* img_roots = image_header->GetImageRoots();
image_header->RelocateImage(delta_);
+ // Patch and update ArtFields.
+ PatchArtFields(image_header);
+
+ // Patch dex file int/long arrays which point to ArtFields.
+ PatchDexFileArrays(img_roots);
+
VisitObject(img_roots);
if (!image_header->IsValid()) {
LOG(ERROR) << "reloction renders image header invalid";
@@ -448,7 +499,7 @@ void PatchOat::PatchVisitor::operator() (mirror::Object* obj, MemberOffset off,
bool is_static_unused ATTRIBUTE_UNUSED) const {
mirror::Object* referent = obj->GetFieldObject<mirror::Object, kVerifyNone>(off);
DCHECK(patcher_->InHeap(referent)) << "Referent is not in the heap.";
- mirror::Object* moved_object = patcher_->RelocatedAddressOf(referent);
+ mirror::Object* moved_object = patcher_->RelocatedAddressOfPointer(referent);
copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
}
@@ -457,30 +508,10 @@ void PatchOat::PatchVisitor::operator() (mirror::Class* cls ATTRIBUTE_UNUSED,
MemberOffset off = mirror::Reference::ReferentOffset();
mirror::Object* referent = ref->GetReferent();
DCHECK(patcher_->InHeap(referent)) << "Referent is not in the heap.";
- mirror::Object* moved_object = patcher_->RelocatedAddressOf(referent);
+ mirror::Object* moved_object = patcher_->RelocatedAddressOfPointer(referent);
copy_->SetFieldObjectWithoutWriteBarrier<false, true, kVerifyNone>(off, moved_object);
}
-mirror::Object* PatchOat::RelocatedCopyOf(mirror::Object* obj) {
- if (obj == nullptr) {
- return nullptr;
- }
- DCHECK_GT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->Begin()));
- DCHECK_LT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->End()));
- uintptr_t heap_off =
- reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(heap_->Begin());
- DCHECK_LT(heap_off, image_->Size());
- return reinterpret_cast<mirror::Object*>(image_->Begin() + heap_off);
-}
-
-mirror::Object* PatchOat::RelocatedAddressOf(mirror::Object* obj) {
- if (obj == nullptr) {
- return nullptr;
- } else {
- return reinterpret_cast<mirror::Object*>(reinterpret_cast<uint8_t*>(obj) + delta_);
- }
-}
-
const OatHeader* PatchOat::GetOatHeader(const ElfFile* elf_file) {
if (elf_file->Is64Bit()) {
return GetOatHeader<ElfFileImpl64>(elf_file->GetImpl64());
@@ -507,7 +538,7 @@ void PatchOat::VisitObject(mirror::Object* object) {
if (kUseBakerOrBrooksReadBarrier) {
object->AssertReadBarrierPointer();
if (kUseBrooksReadBarrier) {
- mirror::Object* moved_to = RelocatedAddressOf(object);
+ mirror::Object* moved_to = RelocatedAddressOfPointer(object);
copy->SetReadBarrierPointer(moved_to);
DCHECK_EQ(copy->GetReadBarrierPointer(), moved_to);
}
@@ -516,6 +547,12 @@ void PatchOat::VisitObject(mirror::Object* object) {
object->VisitReferences<true, kVerifyNone>(visitor, visitor);
if (object->IsArtMethod<kVerifyNone>()) {
FixupMethod(down_cast<mirror::ArtMethod*>(object), down_cast<mirror::ArtMethod*>(copy));
+ } else if (object->IsClass<kVerifyNone>()) {
+ mirror::Class* klass = down_cast<mirror::Class*>(object);
+ down_cast<mirror::Class*>(copy)->SetSFieldsUnchecked(
+ RelocatedAddressOfPointer(klass->GetSFields()));
+ down_cast<mirror::Class*>(copy)->SetIFieldsUnchecked(
+ RelocatedAddressOfPointer(klass->GetIFields()));
}
}
diff --git a/patchoat/patchoat.h b/patchoat/patchoat.h
index 578df3aef7..418650ac16 100644
--- a/patchoat/patchoat.h
+++ b/patchoat/patchoat.h
@@ -117,12 +117,31 @@ class PatchOat {
bool PatchOatHeader(ElfFileImpl* oat_file);
bool PatchImage() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void PatchArtFields(const ImageHeader* image_header) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void PatchDexFileArrays(mirror::ObjectArray<mirror::Object>* img_roots)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool WriteElf(File* out);
bool WriteImage(File* out);
- mirror::Object* RelocatedCopyOf(mirror::Object*);
- mirror::Object* RelocatedAddressOf(mirror::Object* obj);
+ template <typename T>
+ T* RelocatedCopyOf(T* obj) {
+ if (obj == nullptr) {
+ return nullptr;
+ }
+ DCHECK_GT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->Begin()));
+ DCHECK_LT(reinterpret_cast<uintptr_t>(obj), reinterpret_cast<uintptr_t>(heap_->End()));
+ uintptr_t heap_off =
+ reinterpret_cast<uintptr_t>(obj) - reinterpret_cast<uintptr_t>(heap_->Begin());
+ DCHECK_LT(heap_off, image_->Size());
+ return reinterpret_cast<T*>(image_->Begin() + heap_off);
+ }
+
+ template <typename T>
+ T* RelocatedAddressOfPointer(T* obj) {
+ return obj == nullptr ? nullptr :
+ reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(obj) + delta_);
+ }
// Look up the oat header from any elf file.
static const OatHeader* GetOatHeader(const ElfFile* elf_file);
diff --git a/runtime/Android.mk b/runtime/Android.mk
index c0e7f47c90..d3488fc71f 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -19,6 +19,7 @@ LOCAL_PATH := $(call my-dir)
include art/build/Android.common_build.mk
LIBART_COMMON_SRC_FILES := \
+ art_field.cc \
atomic.cc.arm \
barrier.cc \
base/allocator.cc \
@@ -96,9 +97,9 @@ LIBART_COMMON_SRC_FILES := \
jit/jit_instrumentation.cc \
jni_internal.cc \
jobject_comparator.cc \
+ linear_alloc.cc \
mem_map.cc \
memory_region.cc \
- mirror/art_field.cc \
mirror/art_method.cc \
mirror/array.cc \
mirror/class.cc \
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index 0769687716..d7de119449 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -16,9 +16,9 @@
#include <cstdio>
+#include "art_field-inl.h"
#include "common_runtime_test.h"
#include "entrypoints/quick/quick_entrypoints_enum.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/string-inl.h"
@@ -1305,7 +1305,7 @@ TEST_F(StubTest, StringCompareTo) {
}
-static void GetSetBooleanStatic(Handle<mirror::ArtField>* f, Thread* self,
+static void GetSetBooleanStatic(ArtField* f, Thread* self,
mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
@@ -1313,14 +1313,14 @@ static void GetSetBooleanStatic(Handle<mirror::ArtField>* f, Thread* self,
uint8_t values[num_values] = { 0, 1, 2, 128, 0xFF };
for (size_t i = 0; i < num_values; ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
static_cast<size_t>(values[i]),
0U,
StubTest::GetEntrypoint(self, kQuickSet8Static),
self,
referrer);
- size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
0U, 0U,
StubTest::GetEntrypoint(self, kQuickGetBooleanStatic),
self,
@@ -1335,21 +1335,21 @@ static void GetSetBooleanStatic(Handle<mirror::ArtField>* f, Thread* self,
std::cout << "Skipping set_boolean_static as I don't know how to do that on " << kRuntimeISA << std::endl;
#endif
}
-static void GetSetByteStatic(Handle<mirror::ArtField>* f, Thread* self,
- mirror::ArtMethod* referrer, StubTest* test)
+static void GetSetByteStatic(ArtField* f, Thread* self, mirror::ArtMethod* referrer,
+ StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
int8_t values[] = { -128, -64, 0, 64, 127 };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
static_cast<size_t>(values[i]),
0U,
StubTest::GetEntrypoint(self, kQuickSet8Static),
self,
referrer);
- size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
0U, 0U,
StubTest::GetEntrypoint(self, kQuickGetByteStatic),
self,
@@ -1365,26 +1365,26 @@ static void GetSetByteStatic(Handle<mirror::ArtField>* f, Thread* self,
}
-static void GetSetBooleanInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
- Thread* self, mirror::ArtMethod* referrer, StubTest* test)
+static void GetSetBooleanInstance(Handle<mirror::Object>* obj, ArtField* f, Thread* self,
+ mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
uint8_t values[] = { 0, true, 2, 128, 0xFF };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
static_cast<size_t>(values[i]),
StubTest::GetEntrypoint(self, kQuickSet8Instance),
self,
referrer);
- uint8_t res = f->Get()->GetBoolean(obj->Get());
+ uint8_t res = f->GetBoolean(obj->Get());
EXPECT_EQ(values[i], res) << "Iteration " << i;
- f->Get()->SetBoolean<false>(obj->Get(), res);
+ f->SetBoolean<false>(obj->Get(), res);
- size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
0U,
StubTest::GetEntrypoint(self, kQuickGetBooleanInstance),
@@ -1399,25 +1399,25 @@ static void GetSetBooleanInstance(Handle<mirror::Object>* obj, Handle<mirror::Ar
std::cout << "Skipping set_boolean_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
#endif
}
-static void GetSetByteInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+static void GetSetByteInstance(Handle<mirror::Object>* obj, ArtField* f,
Thread* self, mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
int8_t values[] = { -128, -64, 0, 64, 127 };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
static_cast<size_t>(values[i]),
StubTest::GetEntrypoint(self, kQuickSet8Instance),
self,
referrer);
- int8_t res = f->Get()->GetByte(obj->Get());
+ int8_t res = f->GetByte(obj->Get());
EXPECT_EQ(res, values[i]) << "Iteration " << i;
- f->Get()->SetByte<false>(obj->Get(), ++res);
+ f->SetByte<false>(obj->Get(), ++res);
- size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
0U,
StubTest::GetEntrypoint(self, kQuickGetByteInstance),
@@ -1433,21 +1433,21 @@ static void GetSetByteInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtFi
#endif
}
-static void GetSetCharStatic(Handle<mirror::ArtField>* f, Thread* self, mirror::ArtMethod* referrer,
+static void GetSetCharStatic(ArtField* f, Thread* self, mirror::ArtMethod* referrer,
StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
uint16_t values[] = { 0, 1, 2, 255, 32768, 0xFFFF };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
static_cast<size_t>(values[i]),
0U,
StubTest::GetEntrypoint(self, kQuickSet16Static),
self,
referrer);
- size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
0U, 0U,
StubTest::GetEntrypoint(self, kQuickGetCharStatic),
self,
@@ -1462,21 +1462,21 @@ static void GetSetCharStatic(Handle<mirror::ArtField>* f, Thread* self, mirror::
std::cout << "Skipping set_char_static as I don't know how to do that on " << kRuntimeISA << std::endl;
#endif
}
-static void GetSetShortStatic(Handle<mirror::ArtField>* f, Thread* self,
+static void GetSetShortStatic(ArtField* f, Thread* self,
mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
int16_t values[] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
static_cast<size_t>(values[i]),
0U,
StubTest::GetEntrypoint(self, kQuickSet16Static),
self,
referrer);
- size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
0U, 0U,
StubTest::GetEntrypoint(self, kQuickGetShortStatic),
self,
@@ -1492,25 +1492,25 @@ static void GetSetShortStatic(Handle<mirror::ArtField>* f, Thread* self,
#endif
}
-static void GetSetCharInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
- Thread* self, mirror::ArtMethod* referrer, StubTest* test)
+static void GetSetCharInstance(Handle<mirror::Object>* obj, ArtField* f,
+ Thread* self, mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
uint16_t values[] = { 0, 1, 2, 255, 32768, 0xFFFF };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
static_cast<size_t>(values[i]),
StubTest::GetEntrypoint(self, kQuickSet16Instance),
self,
referrer);
- uint16_t res = f->Get()->GetChar(obj->Get());
+ uint16_t res = f->GetChar(obj->Get());
EXPECT_EQ(res, values[i]) << "Iteration " << i;
- f->Get()->SetChar<false>(obj->Get(), ++res);
+ f->SetChar<false>(obj->Get(), ++res);
- size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
0U,
StubTest::GetEntrypoint(self, kQuickGetCharInstance),
@@ -1525,25 +1525,25 @@ static void GetSetCharInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtFi
std::cout << "Skipping set_char_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
#endif
}
-static void GetSetShortInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+static void GetSetShortInstance(Handle<mirror::Object>* obj, ArtField* f,
Thread* self, mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
int16_t values[] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
static_cast<size_t>(values[i]),
StubTest::GetEntrypoint(self, kQuickSet16Instance),
self,
referrer);
- int16_t res = f->Get()->GetShort(obj->Get());
+ int16_t res = f->GetShort(obj->Get());
EXPECT_EQ(res, values[i]) << "Iteration " << i;
- f->Get()->SetShort<false>(obj->Get(), ++res);
+ f->SetShort<false>(obj->Get(), ++res);
- size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
0U,
StubTest::GetEntrypoint(self, kQuickGetShortInstance),
@@ -1559,21 +1559,21 @@ static void GetSetShortInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtF
#endif
}
-static void GetSet32Static(Handle<mirror::ArtField>* f, Thread* self, mirror::ArtMethod* referrer,
+static void GetSet32Static(ArtField* f, Thread* self, mirror::ArtMethod* referrer,
StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
uint32_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
static_cast<size_t>(values[i]),
0U,
StubTest::GetEntrypoint(self, kQuickSet32Static),
self,
referrer);
- size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
0U, 0U,
StubTest::GetEntrypoint(self, kQuickGet32Static),
self,
@@ -1590,27 +1590,27 @@ static void GetSet32Static(Handle<mirror::ArtField>* f, Thread* self, mirror::Ar
}
-static void GetSet32Instance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+static void GetSet32Instance(Handle<mirror::Object>* obj, ArtField* f,
Thread* self, mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
uint32_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
static_cast<size_t>(values[i]),
StubTest::GetEntrypoint(self, kQuickSet32Instance),
self,
referrer);
- int32_t res = f->Get()->GetInt(obj->Get());
+ int32_t res = f->GetInt(obj->Get());
EXPECT_EQ(res, static_cast<int32_t>(values[i])) << "Iteration " << i;
res++;
- f->Get()->SetInt<false>(obj->Get(), res);
+ f->SetInt<false>(obj->Get(), res);
- size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
0U,
StubTest::GetEntrypoint(self, kQuickGet32Instance),
@@ -1649,17 +1649,17 @@ static void set_and_check_static(uint32_t f_idx, mirror::Object* val, Thread* se
}
#endif
-static void GetSetObjStatic(Handle<mirror::ArtField>* f, Thread* self, mirror::ArtMethod* referrer,
+static void GetSetObjStatic(ArtField* f, Thread* self, mirror::ArtMethod* referrer,
StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
- set_and_check_static((*f)->GetDexFieldIndex(), nullptr, self, referrer, test);
+ set_and_check_static(f->GetDexFieldIndex(), nullptr, self, referrer, test);
// Allocate a string object for simplicity.
mirror::String* str = mirror::String::AllocFromModifiedUtf8(self, "Test");
- set_and_check_static((*f)->GetDexFieldIndex(), str, self, referrer, test);
+ set_and_check_static(f->GetDexFieldIndex(), str, self, referrer, test);
- set_and_check_static((*f)->GetDexFieldIndex(), nullptr, self, referrer, test);
+ set_and_check_static(f->GetDexFieldIndex(), nullptr, self, referrer, test);
#else
UNUSED(f, self, referrer, test);
LOG(INFO) << "Skipping setObjstatic as I don't know how to do that on " << kRuntimeISA;
@@ -1670,18 +1670,18 @@ static void GetSetObjStatic(Handle<mirror::ArtField>* f, Thread* self, mirror::A
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
-static void set_and_check_instance(Handle<mirror::ArtField>* f, mirror::Object* trg,
+static void set_and_check_instance(ArtField* f, mirror::Object* trg,
mirror::Object* val, Thread* self, mirror::ArtMethod* referrer,
StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(trg),
reinterpret_cast<size_t>(val),
StubTest::GetEntrypoint(self, kQuickSetObjInstance),
self,
referrer);
- size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(trg),
0U,
StubTest::GetEntrypoint(self, kQuickGetObjInstance),
@@ -1690,11 +1690,11 @@ static void set_and_check_instance(Handle<mirror::ArtField>* f, mirror::Object*
EXPECT_EQ(res, reinterpret_cast<size_t>(val)) << "Value " << val;
- EXPECT_EQ(val, f->Get()->GetObj(trg));
+ EXPECT_EQ(val, f->GetObj(trg));
}
#endif
-static void GetSetObjInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+static void GetSetObjInstance(Handle<mirror::Object>* obj, ArtField* f,
Thread* self, mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
@@ -1716,20 +1716,20 @@ static void GetSetObjInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtFie
// TODO: Complete these tests for 32b architectures.
-static void GetSet64Static(Handle<mirror::ArtField>* f, Thread* self, mirror::ArtMethod* referrer,
+static void GetSet64Static(ArtField* f, Thread* self, mirror::ArtMethod* referrer,
StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if (defined(__x86_64__) && !defined(__APPLE__)) || defined(__aarch64__)
uint64_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF, 0xFFFFFFFFFFFF };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3UWithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3UWithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
values[i],
StubTest::GetEntrypoint(self, kQuickSet64Static),
self,
referrer);
- size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
0U, 0U,
StubTest::GetEntrypoint(self, kQuickGet64Static),
self,
@@ -1746,27 +1746,27 @@ static void GetSet64Static(Handle<mirror::ArtField>* f, Thread* self, mirror::Ar
}
-static void GetSet64Instance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+static void GetSet64Instance(Handle<mirror::Object>* obj, ArtField* f,
Thread* self, mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if (defined(__x86_64__) && !defined(__APPLE__)) || defined(__aarch64__)
uint64_t values[] = { 0, 1, 2, 255, 32768, 1000000, 0xFFFFFFFF, 0xFFFFFFFFFFFF };
for (size_t i = 0; i < arraysize(values); ++i) {
- test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
static_cast<size_t>(values[i]),
StubTest::GetEntrypoint(self, kQuickSet64Instance),
self,
referrer);
- int64_t res = f->Get()->GetLong(obj->Get());
+ int64_t res = f->GetLong(obj->Get());
EXPECT_EQ(res, static_cast<int64_t>(values[i])) << "Iteration " << i;
res++;
- f->Get()->SetLong<false>(obj->Get(), res);
+ f->SetLong<false>(obj->Get(), res);
- size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>(f->GetDexFieldIndex()),
reinterpret_cast<size_t>(obj->Get()),
0U,
StubTest::GetEntrypoint(self, kQuickGet64Instance),
@@ -1792,7 +1792,7 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type)
CHECK(o != NULL);
ScopedObjectAccess soa(self);
- StackHandleScope<5> hs(self);
+ StackHandleScope<4> hs(self);
Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object*>(o)));
Handle<mirror::Class> c(hs.NewHandle(obj->GetClass()));
// Need a method as a referrer
@@ -1801,112 +1801,80 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type)
// Play with it...
// Static fields.
- {
- Handle<mirror::ObjectArray<mirror::ArtField>> fields(hs.NewHandle(c.Get()->GetSFields()));
- int32_t num_fields = fields->GetLength();
- for (int32_t i = 0; i < num_fields; ++i) {
- StackHandleScope<1> hs2(self);
- Handle<mirror::ArtField> f(hs2.NewHandle(fields->Get(i)));
-
- Primitive::Type type = f->GetTypeAsPrimitiveType();
- switch (type) {
- case Primitive::Type::kPrimBoolean:
- if (test_type == type) {
- GetSetBooleanStatic(&f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimByte:
- if (test_type == type) {
- GetSetByteStatic(&f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimChar:
- if (test_type == type) {
- GetSetCharStatic(&f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimShort:
- if (test_type == type) {
- GetSetShortStatic(&f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimInt:
- if (test_type == type) {
- GetSet32Static(&f, self, m.Get(), test);
- }
- break;
-
- case Primitive::Type::kPrimLong:
- if (test_type == type) {
- GetSet64Static(&f, self, m.Get(), test);
- }
- break;
-
- case Primitive::Type::kPrimNot:
- // Don't try array.
- if (test_type == type && f->GetTypeDescriptor()[0] != '[') {
- GetSetObjStatic(&f, self, m.Get(), test);
- }
- break;
-
- default:
- break; // Skip.
- }
+ ArtField* fields = c->GetSFields();
+ size_t num_fields = c->NumStaticFields();
+ for (size_t i = 0; i < num_fields; ++i) {
+ ArtField* f = &fields[i];
+ Primitive::Type type = f->GetTypeAsPrimitiveType();
+ if (test_type != type) {
+ continue;
+ }
+ switch (type) {
+ case Primitive::Type::kPrimBoolean:
+ GetSetBooleanStatic(f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimByte:
+ GetSetByteStatic(f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimChar:
+ GetSetCharStatic(f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimShort:
+ GetSetShortStatic(f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimInt:
+ GetSet32Static(f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimLong:
+ GetSet64Static(f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimNot:
+ // Don't try array.
+ if (f->GetTypeDescriptor()[0] != '[') {
+ GetSetObjStatic(f, self, m.Get(), test);
+ }
+ break;
+ default:
+ break; // Skip.
}
}
// Instance fields.
- {
- Handle<mirror::ObjectArray<mirror::ArtField>> fields(hs.NewHandle(c.Get()->GetIFields()));
- int32_t num_fields = fields->GetLength();
- for (int32_t i = 0; i < num_fields; ++i) {
- StackHandleScope<1> hs2(self);
- Handle<mirror::ArtField> f(hs2.NewHandle(fields->Get(i)));
-
- Primitive::Type type = f->GetTypeAsPrimitiveType();
- switch (type) {
- case Primitive::Type::kPrimBoolean:
- if (test_type == type) {
- GetSetBooleanInstance(&obj, &f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimByte:
- if (test_type == type) {
- GetSetByteInstance(&obj, &f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimChar:
- if (test_type == type) {
- GetSetCharInstance(&obj, &f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimShort:
- if (test_type == type) {
- GetSetShortInstance(&obj, &f, self, m.Get(), test);
- }
- break;
- case Primitive::Type::kPrimInt:
- if (test_type == type) {
- GetSet32Instance(&obj, &f, self, m.Get(), test);
- }
- break;
-
- case Primitive::Type::kPrimLong:
- if (test_type == type) {
- GetSet64Instance(&obj, &f, self, m.Get(), test);
- }
- break;
-
- case Primitive::Type::kPrimNot:
- // Don't try array.
- if (test_type == type && f->GetTypeDescriptor()[0] != '[') {
- GetSetObjInstance(&obj, &f, self, m.Get(), test);
- }
- break;
-
- default:
- break; // Skip.
- }
+ fields = c->GetIFields();
+ num_fields = c->NumInstanceFields();
+ for (size_t i = 0; i < num_fields; ++i) {
+ ArtField* f = &fields[i];
+ Primitive::Type type = f->GetTypeAsPrimitiveType();
+ if (test_type != type) {
+ continue;
+ }
+ switch (type) {
+ case Primitive::Type::kPrimBoolean:
+ GetSetBooleanInstance(&obj, f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimByte:
+ GetSetByteInstance(&obj, f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimChar:
+ GetSetCharInstance(&obj, f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimShort:
+ GetSetShortInstance(&obj, f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimInt:
+ GetSet32Instance(&obj, f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimLong:
+ GetSet64Instance(&obj, f, self, m.Get(), test);
+ break;
+ case Primitive::Type::kPrimNot:
+ // Don't try array.
+ if (f->GetTypeDescriptor()[0] != '[') {
+ GetSetObjInstance(&obj, f, self, m.Get(), test);
+ }
+ break;
+ default:
+ break; // Skip.
}
}
diff --git a/runtime/mirror/art_field-inl.h b/runtime/art_field-inl.h
index 986852f200..aeb127358c 100644
--- a/runtime/mirror/art_field-inl.h
+++ b/runtime/art_field-inl.h
@@ -14,57 +14,51 @@
* limitations under the License.
*/
-#ifndef ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
-#define ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
+#ifndef ART_RUNTIME_ART_FIELD_INL_H_
+#define ART_RUNTIME_ART_FIELD_INL_H_
#include "art_field.h"
#include "base/logging.h"
#include "class_linker.h"
-#include "dex_cache.h"
#include "gc/accounting/card_table-inl.h"
#include "jvalue.h"
-#include "object-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/object-inl.h"
#include "primitive.h"
#include "thread-inl.h"
#include "scoped_thread_state_change.h"
#include "well_known_classes.h"
namespace art {
-namespace mirror {
-inline uint32_t ArtField::ClassSize() {
- uint32_t vtable_entries = Object::kVTableLength;
- return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0);
-}
-
-inline Class* ArtField::GetDeclaringClass() {
- Class* result = GetFieldObject<Class>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_));
- DCHECK(result != NULL);
+inline mirror::Class* ArtField::GetDeclaringClass() {
+ mirror::Class* result = declaring_class_.Read();
+ DCHECK(result != nullptr);
DCHECK(result->IsLoaded() || result->IsErroneous());
return result;
}
-inline void ArtField::SetDeclaringClass(Class *new_declaring_class) {
- SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, declaring_class_), new_declaring_class);
+inline void ArtField::SetDeclaringClass(mirror::Class* new_declaring_class) {
+ declaring_class_ = GcRoot<mirror::Class>(new_declaring_class);
}
inline uint32_t ArtField::GetAccessFlags() {
DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, access_flags_));
+ return access_flags_;
}
inline MemberOffset ArtField::GetOffset() {
DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
- return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
+ return MemberOffset(offset_);
}
inline MemberOffset ArtField::GetOffsetDuringLinking() {
DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
- return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_)));
+ return MemberOffset(offset_);
}
-inline uint32_t ArtField::Get32(Object* object) {
+inline uint32_t ArtField::Get32(mirror::Object* object) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -74,7 +68,7 @@ inline uint32_t ArtField::Get32(Object* object) {
}
template<bool kTransactionActive>
-inline void ArtField::Set32(Object* object, uint32_t new_value) {
+inline void ArtField::Set32(mirror::Object* object, uint32_t new_value) {
DCHECK(object != nullptr) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -84,7 +78,7 @@ inline void ArtField::Set32(Object* object, uint32_t new_value) {
}
}
-inline uint64_t ArtField::Get64(Object* object) {
+inline uint64_t ArtField::Get64(mirror::Object* object) {
DCHECK(object != NULL) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -94,7 +88,7 @@ inline uint64_t ArtField::Get64(Object* object) {
}
template<bool kTransactionActive>
-inline void ArtField::Set64(Object* object, uint64_t new_value) {
+inline void ArtField::Set64(mirror::Object* object, uint64_t new_value) {
DCHECK(object != NULL) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -104,17 +98,17 @@ inline void ArtField::Set64(Object* object, uint64_t new_value) {
}
}
-inline Object* ArtField::GetObj(Object* object) {
+inline mirror::Object* ArtField::GetObj(mirror::Object* object) {
DCHECK(object != NULL) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
- return object->GetFieldObjectVolatile<Object>(GetOffset());
+ return object->GetFieldObjectVolatile<mirror::Object>(GetOffset());
}
- return object->GetFieldObject<Object>(GetOffset());
+ return object->GetFieldObject<mirror::Object>(GetOffset());
}
template<bool kTransactionActive>
-inline void ArtField::SetObj(Object* object, Object* new_value) {
+inline void ArtField::SetObj(mirror::Object* object, mirror::Object* new_value) {
DCHECK(object != NULL) << PrettyField(this);
DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
if (UNLIKELY(IsVolatile())) {
@@ -143,46 +137,46 @@ inline void ArtField::SetObj(Object* object, Object* new_value) {
object->SetField ## type<kTransactionActive>(GetOffset(), value); \
}
-inline uint8_t ArtField::GetBoolean(Object* object) {
+inline uint8_t ArtField::GetBoolean(mirror::Object* object) {
FIELD_GET(object, Boolean);
}
template<bool kTransactionActive>
-inline void ArtField::SetBoolean(Object* object, uint8_t z) {
+inline void ArtField::SetBoolean(mirror::Object* object, uint8_t z) {
FIELD_SET(object, Boolean, z);
}
-inline int8_t ArtField::GetByte(Object* object) {
+inline int8_t ArtField::GetByte(mirror::Object* object) {
FIELD_GET(object, Byte);
}
template<bool kTransactionActive>
-inline void ArtField::SetByte(Object* object, int8_t b) {
+inline void ArtField::SetByte(mirror::Object* object, int8_t b) {
FIELD_SET(object, Byte, b);
}
-inline uint16_t ArtField::GetChar(Object* object) {
+inline uint16_t ArtField::GetChar(mirror::Object* object) {
FIELD_GET(object, Char);
}
template<bool kTransactionActive>
-inline void ArtField::SetChar(Object* object, uint16_t c) {
+inline void ArtField::SetChar(mirror::Object* object, uint16_t c) {
FIELD_SET(object, Char, c);
}
-inline int16_t ArtField::GetShort(Object* object) {
+inline int16_t ArtField::GetShort(mirror::Object* object) {
FIELD_GET(object, Short);
}
template<bool kTransactionActive>
-inline void ArtField::SetShort(Object* object, int16_t s) {
+inline void ArtField::SetShort(mirror::Object* object, int16_t s) {
FIELD_SET(object, Short, s);
}
#undef FIELD_GET
#undef FIELD_SET
-inline int32_t ArtField::GetInt(Object* object) {
+inline int32_t ArtField::GetInt(mirror::Object* object) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
@@ -191,7 +185,7 @@ inline int32_t ArtField::GetInt(Object* object) {
}
template<bool kTransactionActive>
-inline void ArtField::SetInt(Object* object, int32_t i) {
+inline void ArtField::SetInt(mirror::Object* object, int32_t i) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
@@ -199,7 +193,7 @@ inline void ArtField::SetInt(Object* object, int32_t i) {
Set32<kTransactionActive>(object, i);
}
-inline int64_t ArtField::GetLong(Object* object) {
+inline int64_t ArtField::GetLong(mirror::Object* object) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
@@ -208,7 +202,7 @@ inline int64_t ArtField::GetLong(Object* object) {
}
template<bool kTransactionActive>
-inline void ArtField::SetLong(Object* object, int64_t j) {
+inline void ArtField::SetLong(mirror::Object* object, int64_t j) {
if (kIsDebugBuild) {
Primitive::Type type = GetTypeAsPrimitiveType();
CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
@@ -216,7 +210,7 @@ inline void ArtField::SetLong(Object* object, int64_t j) {
Set64<kTransactionActive>(object, j);
}
-inline float ArtField::GetFloat(Object* object) {
+inline float ArtField::GetFloat(mirror::Object* object) {
DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetI(Get32(object));
@@ -224,14 +218,14 @@ inline float ArtField::GetFloat(Object* object) {
}
template<bool kTransactionActive>
-inline void ArtField::SetFloat(Object* object, float f) {
+inline void ArtField::SetFloat(mirror::Object* object, float f) {
DCHECK_EQ(Primitive::kPrimFloat, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetF(f);
Set32<kTransactionActive>(object, bits.GetI());
}
-inline double ArtField::GetDouble(Object* object) {
+inline double ArtField::GetDouble(mirror::Object* object) {
DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetJ(Get64(object));
@@ -239,20 +233,20 @@ inline double ArtField::GetDouble(Object* object) {
}
template<bool kTransactionActive>
-inline void ArtField::SetDouble(Object* object, double d) {
+inline void ArtField::SetDouble(mirror::Object* object, double d) {
DCHECK_EQ(Primitive::kPrimDouble, GetTypeAsPrimitiveType()) << PrettyField(this);
JValue bits;
bits.SetD(d);
Set64<kTransactionActive>(object, bits.GetJ());
}
-inline Object* ArtField::GetObject(Object* object) {
+inline mirror::Object* ArtField::GetObject(mirror::Object* object) {
DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
return GetObj(object);
}
template<bool kTransactionActive>
-inline void ArtField::SetObject(Object* object, Object* l) {
+inline void ArtField::SetObject(mirror::Object* object, mirror::Object* l) {
DCHECK_EQ(Primitive::kPrimNot, GetTypeAsPrimitiveType()) << PrettyField(this);
SetObj<kTransactionActive>(object, l);
}
@@ -291,7 +285,7 @@ inline bool ArtField::IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_loc
}
template <bool kResolve>
-inline Class* ArtField::GetType() {
+inline mirror::Class* ArtField::GetType() {
const uint32_t field_index = GetDexFieldIndex();
auto* declaring_class = GetDeclaringClass();
if (UNLIKELY(declaring_class->IsProxyClass())) {
@@ -321,7 +315,7 @@ inline const DexFile* ArtField::GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutato
return GetDexCache()->GetDexFile();
}
-inline String* ArtField::GetStringName(Thread* self, bool resolve) {
+inline mirror::String* ArtField::GetStringName(Thread* self, bool resolve) {
auto dex_field_index = GetDexFieldIndex();
CHECK_NE(dex_field_index, DexFile::kDexNoIndex);
auto* dex_cache = GetDexCache();
@@ -336,7 +330,6 @@ inline String* ArtField::GetStringName(Thread* self, bool resolve) {
return name;
}
-} // namespace mirror
} // namespace art
-#endif // ART_RUNTIME_MIRROR_ART_FIELD_INL_H_
+#endif // ART_RUNTIME_ART_FIELD_INL_H_
diff --git a/runtime/mirror/art_field.cc b/runtime/art_field.cc
index 83602d48dc..cdf8967384 100644
--- a/runtime/mirror/art_field.cc
+++ b/runtime/art_field.cc
@@ -18,28 +18,17 @@
#include "art_field-inl.h"
#include "gc/accounting/card_table-inl.h"
-#include "object-inl.h"
-#include "object_array-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "utils.h"
#include "well_known_classes.h"
namespace art {
-namespace mirror {
-// TODO: Get global references for these
-GcRoot<Class> ArtField::java_lang_reflect_ArtField_;
-
-void ArtField::SetClass(Class* java_lang_reflect_ArtField) {
- CHECK(java_lang_reflect_ArtField_.IsNull());
- CHECK(java_lang_reflect_ArtField != NULL);
- java_lang_reflect_ArtField_ = GcRoot<Class>(java_lang_reflect_ArtField);
-}
-
-void ArtField::ResetClass() {
- CHECK(!java_lang_reflect_ArtField_.IsNull());
- java_lang_reflect_ArtField_ = GcRoot<Class>(nullptr);
+ArtField::ArtField() : access_flags_(0), field_dex_idx_(0), offset_(0) {
+ declaring_class_ = GcRoot<mirror::Class>(nullptr);
}
void ArtField::SetOffset(MemberOffset num_bytes) {
@@ -52,32 +41,24 @@ void ArtField::SetOffset(MemberOffset num_bytes) {
}
}
// Not called within a transaction.
- SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_), num_bytes.Uint32Value());
+ offset_ = num_bytes.Uint32Value();
}
void ArtField::VisitRoots(RootVisitor* visitor) {
- java_lang_reflect_ArtField_.VisitRootIfNonNull(visitor, RootInfo(kRootStickyClass));
+ declaring_class_.VisitRoot(visitor, RootInfo(kRootStickyClass));
}
-// TODO: we could speed up the search if fields are ordered by offsets.
ArtField* ArtField::FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) {
DCHECK(klass != nullptr);
- ObjectArray<ArtField>* instance_fields = klass->GetIFields();
- if (instance_fields != nullptr) {
- for (int32_t i = 0, e = instance_fields->GetLength(); i < e; ++i) {
- mirror::ArtField* field = instance_fields->GetWithoutChecks(i);
- if (field->GetOffset().Uint32Value() == field_offset) {
- return field;
- }
+ auto* instance_fields = klass->GetIFields();
+ for (size_t i = 0, count = klass->NumInstanceFields(); i < count; ++i) {
+ if (instance_fields[i].GetOffset().Uint32Value() == field_offset) {
+ return &instance_fields[i];
}
}
// We did not find field in the class: look into superclass.
- if (klass->GetSuperClass() != NULL) {
- return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset);
- } else {
- return nullptr;
- }
+ return (klass->GetSuperClass() != nullptr) ?
+ FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset) : nullptr;
}
-} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/art_field.h b/runtime/art_field.h
index 9d95cb922b..5bdbe71255 100644
--- a/runtime/mirror/art_field.h
+++ b/runtime/art_field.h
@@ -14,48 +14,44 @@
* limitations under the License.
*/
-#ifndef ART_RUNTIME_MIRROR_ART_FIELD_H_
-#define ART_RUNTIME_MIRROR_ART_FIELD_H_
+#ifndef ART_RUNTIME_ART_FIELD_H_
+#define ART_RUNTIME_ART_FIELD_H_
#include <jni.h>
#include "gc_root.h"
#include "modifiers.h"
-#include "object.h"
#include "object_callbacks.h"
+#include "offsets.h"
#include "primitive.h"
#include "read_barrier_option.h"
namespace art {
-struct ArtFieldOffsets;
class DexFile;
class ScopedObjectAccessAlreadyRunnable;
namespace mirror {
-
+class Class;
class DexCache;
+class Object;
+class String;
+} // namespace mirror
-// C++ mirror of java.lang.reflect.ArtField
-class MANAGED ArtField FINAL : public Object {
+class ArtField {
public:
- // Size of java.lang.reflect.ArtField.class.
- static uint32_t ClassSize();
+ ArtField();
- // Size of an instance of java.lang.reflect.ArtField not including its value array.
- static constexpr uint32_t InstanceSize() {
- return sizeof(ArtField);
- }
+ mirror::Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetDeclaringClass(mirror::Class *new_declaring_class)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
uint32_t GetAccessFlags() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetAccessFlags(uint32_t new_access_flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Not called within a transaction.
- SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, access_flags_), new_access_flags);
+ access_flags_ = new_access_flags;
}
bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -70,13 +66,13 @@ class MANAGED ArtField FINAL : public Object {
return (GetAccessFlags() & kAccFinal) != 0;
}
- uint32_t GetDexFieldIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, field_dex_idx_));
+ uint32_t GetDexFieldIndex() {
+ return field_dex_idx_;
}
- void SetDexFieldIndex(uint32_t new_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void SetDexFieldIndex(uint32_t new_idx) {
// Not called within a transaction.
- SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, field_dex_idx_), new_idx);
+ field_dex_idx_ = new_idx;
}
// Offset to field within an Object.
@@ -91,54 +87,71 @@ class MANAGED ArtField FINAL : public Object {
void SetOffset(MemberOffset num_bytes) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// field access, null object for static fields
- uint8_t GetBoolean(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint8_t GetBoolean(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetBoolean(Object* object, uint8_t z) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int8_t GetByte(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetBoolean(mirror::Object* object, uint8_t z) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ int8_t GetByte(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetByte(Object* object, int8_t b) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint16_t GetChar(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetByte(mirror::Object* object, int8_t b) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ uint16_t GetChar(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetChar(Object* object, uint16_t c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int16_t GetShort(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetChar(mirror::Object* object, uint16_t c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ int16_t GetShort(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetShort(Object* object, int16_t s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int32_t GetInt(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetShort(mirror::Object* object, int16_t s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ int32_t GetInt(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetInt(Object* object, int32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int64_t GetLong(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetInt(mirror::Object* object, int32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ int64_t GetLong(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetLong(Object* object, int64_t j) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- float GetFloat(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetLong(mirror::Object* object, int64_t j) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ float GetFloat(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetFloat(Object* object, float f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- double GetDouble(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetFloat(mirror::Object* object, float f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ double GetDouble(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetDouble(Object* object, double d) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* GetObject(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetDouble(mirror::Object* object, double d) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ mirror::Object* GetObject(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetObject(Object* object, Object* l) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetObject(mirror::Object* object, mirror::Object* l)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Raw field accesses.
- uint32_t Get32(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<bool kTransactionActive>
- void Set32(Object* object, uint32_t new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint64_t Get64(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint32_t Get32(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void Set64(Object* object, uint64_t new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* GetObj(Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void Set32(mirror::Object* object, uint32_t new_value)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ uint64_t Get64(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
template<bool kTransactionActive>
- void SetObj(Object* object, Object* new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void Set64(mirror::Object* object, uint64_t new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- static Class* GetJavaLangReflectArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(!java_lang_reflect_ArtField_.IsNull());
- return java_lang_reflect_ArtField_.Read<kReadBarrierOption>();
- }
+ mirror::Object* GetObj(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void SetClass(Class* java_lang_reflect_ArtField);
- static void ResetClass();
- static void VisitRoots(RootVisitor* visitor)
+ template<bool kTransactionActive>
+ void SetObj(mirror::Object* object, mirror::Object* new_value)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void VisitRoots(RootVisitor* visitor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsVolatile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -152,7 +165,8 @@ class MANAGED ArtField FINAL : public Object {
const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolves / returns the name from the dex cache.
- String* GetStringName(Thread* self, bool resolve) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::String* GetStringName(Thread* self, bool resolve)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -161,7 +175,7 @@ class MANAGED ArtField FINAL : public Object {
bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template <bool kResolve>
- Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -169,10 +183,12 @@ class MANAGED ArtField FINAL : public Object {
const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ GcRoot<mirror::Class>& DeclaringClassRoot() {
+ return declaring_class_;
+ }
+
private:
- // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- // The class we are a part of
- HeapReference<Class> declaring_class_;
+ GcRoot<mirror::Class> declaring_class_;
uint32_t access_flags_;
@@ -181,14 +197,8 @@ class MANAGED ArtField FINAL : public Object {
// Offset of field within an instance or in the Class' static fields
uint32_t offset_;
-
- static GcRoot<Class> java_lang_reflect_ArtField_;
-
- friend struct art::ArtFieldOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(ArtField);
};
-} // namespace mirror
} // namespace art
-#endif // ART_RUNTIME_MIRROR_ART_FIELD_H_
+#endif // ART_RUNTIME_ART_FIELD_H_
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index dba4af8b4b..4c83e8856b 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -135,13 +135,13 @@ ADD_TEST_EQ(size_t(MIRROR_OBJECT_HEADER_SIZE), sizeof(art::mirror::Object))
#define MIRROR_CLASS_COMPONENT_TYPE_OFFSET (4 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_COMPONENT_TYPE_OFFSET,
art::mirror::Class::ComponentTypeOffset().Int32Value())
-#define MIRROR_CLASS_ACCESS_FLAGS_OFFSET (52 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_ACCESS_FLAGS_OFFSET (44 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_ACCESS_FLAGS_OFFSET,
art::mirror::Class::AccessFlagsOffset().Int32Value())
-#define MIRROR_CLASS_OBJECT_SIZE_OFFSET (80 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_OBJECT_SIZE_OFFSET (96 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_OBJECT_SIZE_OFFSET,
art::mirror::Class::ObjectSizeOffset().Int32Value())
-#define MIRROR_CLASS_STATUS_OFFSET (92 + MIRROR_OBJECT_HEADER_SIZE)
+#define MIRROR_CLASS_STATUS_OFFSET (108 + MIRROR_OBJECT_HEADER_SIZE)
ADD_TEST_EQ(MIRROR_CLASS_STATUS_OFFSET,
art::mirror::Class::StatusOffset().Int32Value())
diff --git a/runtime/base/arena_allocator.cc b/runtime/base/arena_allocator.cc
index dd29404cd9..59d38ad593 100644
--- a/runtime/base/arena_allocator.cc
+++ b/runtime/base/arena_allocator.cc
@@ -132,11 +132,10 @@ MallocArena::~MallocArena() {
free(reinterpret_cast<void*>(memory_));
}
-MemMapArena::MemMapArena(size_t size) {
+MemMapArena::MemMapArena(size_t size, bool low_4gb) {
std::string error_msg;
- map_.reset(
- MemMap::MapAnonymous("dalvik-LinearAlloc", nullptr, size, PROT_READ | PROT_WRITE, false,
- false, &error_msg));
+ map_.reset(MemMap::MapAnonymous(
+ "LinearAlloc", nullptr, size, PROT_READ | PROT_WRITE, low_4gb, false, &error_msg));
CHECK(map_.get() != nullptr) << error_msg;
memory_ = map_->Begin();
size_ = map_->Size();
@@ -156,8 +155,12 @@ void Arena::Reset() {
}
}
-ArenaPool::ArenaPool(bool use_malloc)
- : use_malloc_(use_malloc), lock_("Arena pool lock"), free_arenas_(nullptr) {
+ArenaPool::ArenaPool(bool use_malloc, bool low_4gb)
+ : use_malloc_(use_malloc), lock_("Arena pool lock", kArenaPoolLock), free_arenas_(nullptr),
+ low_4gb_(low_4gb) {
+ if (low_4gb) {
+ CHECK(!use_malloc) << "low4gb must use map implementation";
+ }
if (!use_malloc) {
MemMap::Init();
}
@@ -182,7 +185,8 @@ Arena* ArenaPool::AllocArena(size_t size) {
}
}
if (ret == nullptr) {
- ret = use_malloc_ ? static_cast<Arena*>(new MallocArena(size)) : new MemMapArena(size);
+ ret = use_malloc_ ? static_cast<Arena*>(new MallocArena(size)) :
+ new MemMapArena(size, low_4gb_);
}
ret->Reset();
return ret;
@@ -229,6 +233,17 @@ size_t ArenaAllocator::BytesAllocated() const {
return ArenaAllocatorStats::BytesAllocated();
}
+size_t ArenaAllocator::BytesUsed() const {
+ size_t total = ptr_ - begin_;
+ if (arena_head_ != nullptr) {
+ for (Arena* cur_arena = arena_head_->next_; cur_arena != nullptr;
+ cur_arena = cur_arena->next_) {
+ total += cur_arena->GetBytesAllocated();
+ }
+ }
+ return total;
+}
+
ArenaAllocator::ArenaAllocator(ArenaPool* pool)
: pool_(pool),
begin_(nullptr),
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index cc7b856e84..3a86b61e1a 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -165,7 +165,7 @@ class MallocArena FINAL : public Arena {
class MemMapArena FINAL : public Arena {
public:
- explicit MemMapArena(size_t size = Arena::kDefaultSize);
+ explicit MemMapArena(size_t size, bool low_4gb);
virtual ~MemMapArena() { }
void Release() OVERRIDE;
@@ -175,7 +175,7 @@ class MemMapArena FINAL : public Arena {
class ArenaPool {
public:
- explicit ArenaPool(bool use_malloc = true);
+ explicit ArenaPool(bool use_malloc = true, bool low_4gb = false);
~ArenaPool();
Arena* AllocArena(size_t size) LOCKS_EXCLUDED(lock_);
void FreeArenaChain(Arena* first) LOCKS_EXCLUDED(lock_);
@@ -188,6 +188,7 @@ class ArenaPool {
const bool use_malloc_;
mutable Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
Arena* free_arenas_ GUARDED_BY(lock_);
+ const bool low_4gb_;
DISALLOW_COPY_AND_ASSIGN(ArenaPool);
};
@@ -227,6 +228,9 @@ class ArenaAllocator : private DebugStackRefCounter, private ArenaAllocatorStats
void ObtainNewArenaForAllocation(size_t allocation_size);
size_t BytesAllocated() const;
MemStats GetMemStats() const;
+ // The BytesUsed method sums up bytes allocated from arenas in arena_head_ and nodes.
+ // TODO: Change BytesAllocated to this behavior?
+ size_t BytesUsed() const;
private:
static constexpr size_t kAlignment = 8;
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index af008347cd..6e4b96c2e6 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -73,6 +73,7 @@ enum LockLevel {
kRosAllocBulkFreeLock,
kAllocSpaceLock,
kBumpPointerSpaceBlockLock,
+ kArenaPoolLock,
kDexFileMethodInlinerLock,
kDexFileToMethodInlinerMapLock,
kMarkSweepMarkStackLock,
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index 2b0167d41e..f94ebeabbc 100644
--- a/runtime/check_jni.cc
+++ b/runtime/check_jni.cc
@@ -19,6 +19,7 @@
#include <sys/mman.h>
#include <zlib.h>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/to_str.h"
#include "class_linker.h"
@@ -27,7 +28,6 @@
#include "gc/space/space.h"
#include "java_vm_ext.h"
#include "jni_internal.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
@@ -169,7 +169,7 @@ class ScopedCheck {
return false;
}
- mirror::ArtField* f = CheckFieldID(soa, fid);
+ ArtField* f = CheckFieldID(soa, fid);
if (f == nullptr) {
return false;
}
@@ -248,7 +248,7 @@ class ScopedCheck {
bool CheckStaticFieldID(ScopedObjectAccess& soa, jclass java_class, jfieldID fid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
- mirror::ArtField* f = CheckFieldID(soa, fid);
+ ArtField* f = CheckFieldID(soa, fid);
if (f == nullptr) {
return false;
}
@@ -565,7 +565,7 @@ class ScopedCheck {
if (!is_static && !CheckInstanceFieldID(soa, obj, fid)) {
return false;
}
- mirror::ArtField* field = soa.DecodeField(fid);
+ ArtField* field = soa.DecodeField(fid);
DCHECK(field != nullptr); // Already checked by Check.
if (is_static != field->IsStatic()) {
AbortF("attempt to access %s field %s: %p",
@@ -817,7 +817,7 @@ class ScopedCheck {
}
case 'f': { // jfieldID
jfieldID fid = arg.f;
- mirror::ArtField* f = soa.DecodeField(fid);
+ ArtField* f = soa.DecodeField(fid);
*msg += PrettyField(f);
if (!entry) {
StringAppendF(msg, " (%p)", fid);
@@ -986,14 +986,15 @@ class ScopedCheck {
return true;
}
- mirror::ArtField* CheckFieldID(ScopedObjectAccess& soa, jfieldID fid)
+ ArtField* CheckFieldID(ScopedObjectAccess& soa, jfieldID fid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (fid == nullptr) {
AbortF("jfieldID was NULL");
return nullptr;
}
- mirror::ArtField* f = soa.DecodeField(fid);
- if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(f) || !f->IsArtField()) {
+ ArtField* f = soa.DecodeField(fid);
+ // TODO: Better check here.
+ if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(f->GetDeclaringClass())) {
Runtime::Current()->GetHeap()->DumpSpaces(LOG(ERROR));
AbortF("invalid jfieldID: %p", fid);
return nullptr;
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 51987692d1..87d1c4cd66 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -17,10 +17,10 @@
#ifndef ART_RUNTIME_CLASS_LINKER_INL_H_
#define ART_RUNTIME_CLASS_LINKER_INL_H_
+#include "art_field.h"
#include "class_linker.h"
#include "gc_root-inl.h"
#include "gc/heap-inl.h"
-#include "mirror/art_field.h"
#include "mirror/class_loader.h"
#include "mirror/dex_cache-inl.h"
#include "mirror/iftable.h"
@@ -88,7 +88,7 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx,
return resolved_type;
}
-inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, mirror::ArtField* referrer) {
+inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, ArtField* referrer) {
mirror::Class* declaring_class = referrer->GetDeclaringClass();
mirror::DexCache* dex_cache_ptr = declaring_class->GetDexCache();
mirror::Class* resolved_type = dex_cache_ptr->GetResolvedType(type_idx);
@@ -133,15 +133,19 @@ inline mirror::ArtMethod* ClassLinker::ResolveMethod(Thread* self, uint32_t meth
return resolved_method;
}
-inline mirror::ArtField* ClassLinker::GetResolvedField(uint32_t field_idx,
- mirror::Class* field_declaring_class) {
- return field_declaring_class->GetDexCache()->GetResolvedField(field_idx);
+inline ArtField* ClassLinker::GetResolvedField(uint32_t field_idx, mirror::DexCache* dex_cache) {
+ return dex_cache->GetResolvedField(field_idx, image_pointer_size_);
}
-inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer,
+inline ArtField* ClassLinker::GetResolvedField(
+ uint32_t field_idx, mirror::Class* field_declaring_class) {
+ return GetResolvedField(field_idx, field_declaring_class->GetDexCache());
+}
+
+inline ArtField* ClassLinker::ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer,
bool is_static) {
mirror::Class* declaring_class = referrer->GetDeclaringClass();
- mirror::ArtField* resolved_field = GetResolvedField(field_idx, declaring_class);
+ ArtField* resolved_field = GetResolvedField(field_idx, declaring_class);
if (UNLIKELY(resolved_field == NULL)) {
StackHandleScope<2> hs(Thread::Current());
Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache()));
@@ -187,17 +191,6 @@ inline mirror::IfTable* ClassLinker::AllocIfTable(Thread* self, size_t ifcount)
ifcount * mirror::IfTable::kMax));
}
-inline mirror::ObjectArray<mirror::ArtField>* ClassLinker::AllocArtFieldArray(Thread* self,
- size_t length) {
- gc::Heap* const heap = Runtime::Current()->GetHeap();
- // Can't have movable field arrays for mark compact since we need these arrays to always be valid
- // so that we can do Object::VisitReferences in the case where the fields don't fit in the
- // reference offsets word.
- return mirror::ObjectArray<mirror::ArtField>::Alloc(
- self, GetClassRoot(kJavaLangReflectArtFieldArrayClass), length,
- kMoveFieldArrays ? heap->GetCurrentAllocator() : heap->GetCurrentNonMovingAllocator());
-}
-
inline mirror::Class* ClassLinker::GetClassRoot(ClassRoot class_root)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(!class_roots_.IsNull());
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 12fa546460..935c401825 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -25,6 +25,7 @@
#include <utility>
#include <vector>
+#include "art_field-inl.h"
#include "base/casts.h"
#include "base/logging.h"
#include "base/scoped_flock.h"
@@ -46,11 +47,11 @@
#include "jit/jit.h"
#include "jit/jit_code_cache.h"
#include "leb128.h"
+#include "linear_alloc.h"
#include "oat.h"
#include "oat_file.h"
#include "oat_file_assistant.h"
#include "object_lock.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class.h"
#include "mirror/class-inl.h"
@@ -77,6 +78,8 @@
namespace art {
+static constexpr bool kSanityCheckObjects = kIsDebugBuild;
+
static void ThrowNoClassDefFoundError(const char* fmt, ...)
__attribute__((__format__(__printf__, 1, 2)))
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -186,7 +189,7 @@ static void AddFieldGap(uint32_t gap_start, uint32_t gap_end, FieldGaps* gaps) {
template<int n>
static void ShuffleForward(size_t* current_field_idx,
MemberOffset* field_offset,
- std::deque<mirror::ArtField*>* grouped_and_sorted_fields,
+ std::deque<ArtField*>* grouped_and_sorted_fields,
FieldGaps* gaps)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(current_field_idx != nullptr);
@@ -196,7 +199,7 @@ static void ShuffleForward(size_t* current_field_idx,
DCHECK(IsPowerOfTwo(n));
while (!grouped_and_sorted_fields->empty()) {
- mirror::ArtField* field = grouped_and_sorted_fields->front();
+ ArtField* field = grouped_and_sorted_fields->front();
Primitive::Type type = field->GetTypeAsPrimitiveType();
if (Primitive::ComponentSize(type) < n) {
break;
@@ -357,6 +360,13 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b
mirror::IntArray::SetArrayClass(int_array_class.Get());
SetClassRoot(kIntArrayClass, int_array_class.Get());
+ // Create long array type for AllocDexCache (done in AppendToBootClassPath).
+ Handle<mirror::Class> long_array_class(hs.NewHandle(
+ AllocClass(self, java_lang_Class.Get(), mirror::Array::ClassSize())));
+ long_array_class->SetComponentType(GetClassRoot(kPrimitiveLong));
+ mirror::LongArray::SetArrayClass(long_array_class.Get());
+ SetClassRoot(kLongArrayClass, long_array_class.Get());
+
// now that these are registered, we can use AllocClass() and AllocObjectArray
// Set up DexCache. This cannot be done later since AppendToBootClassPath calls AllocDexCache.
@@ -366,15 +376,8 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b
java_lang_DexCache->SetObjectSize(mirror::DexCache::InstanceSize());
mirror::Class::SetStatus(java_lang_DexCache, mirror::Class::kStatusResolved, self);
- // Constructor, Field, Method, and AbstractMethod are necessary so
+ // Constructor, Method, and AbstractMethod are necessary so
// that FindClass can link members.
- Handle<mirror::Class> java_lang_reflect_ArtField(hs.NewHandle(
- AllocClass(self, java_lang_Class.Get(), mirror::ArtField::ClassSize())));
- CHECK(java_lang_reflect_ArtField.Get() != nullptr);
- java_lang_reflect_ArtField->SetObjectSize(mirror::ArtField::InstanceSize());
- SetClassRoot(kJavaLangReflectArtField, java_lang_reflect_ArtField.Get());
- mirror::Class::SetStatus(java_lang_reflect_ArtField, mirror::Class::kStatusResolved, self);
- mirror::ArtField::SetClass(java_lang_reflect_ArtField.Get());
Handle<mirror::Class> java_lang_reflect_ArtMethod(hs.NewHandle(
AllocClass(self, java_lang_Class.Get(), mirror::ArtMethod::ClassSize())));
@@ -398,12 +401,6 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b
object_array_art_method->SetComponentType(java_lang_reflect_ArtMethod.Get());
SetClassRoot(kJavaLangReflectArtMethodArrayClass, object_array_art_method.Get());
- Handle<mirror::Class> object_array_art_field(hs.NewHandle(
- AllocClass(self, java_lang_Class.Get(),
- mirror::ObjectArray<mirror::ArtField>::ClassSize())));
- object_array_art_field->SetComponentType(java_lang_reflect_ArtField.Get());
- SetClassRoot(kJavaLangReflectArtFieldArrayClass, object_array_art_field.Get());
-
// Setup boot_class_path_ and register class_path now that we can use AllocObjectArray to create
// DexCache instances. Needs to be after String, Field, Method arrays since AllocDexCache uses
// these roots.
@@ -471,8 +468,8 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b
mirror::Class* found_int_array_class = FindSystemClass(self, "[I");
CHECK_EQ(int_array_class.Get(), found_int_array_class);
- SetClassRoot(kLongArrayClass, FindSystemClass(self, "[J"));
- mirror::LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
+ mirror::Class* found_long_array_class = FindSystemClass(self, "[J");
+ CHECK_EQ(long_array_class.Get(), found_long_array_class);
SetClassRoot(kFloatArrayClass, FindSystemClass(self, "[F"));
mirror::FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
@@ -513,10 +510,6 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b
mirror::Class* Art_method_class = FindSystemClass(self, "Ljava/lang/reflect/ArtMethod;");
CHECK_EQ(java_lang_reflect_ArtMethod.Get(), Art_method_class);
- mirror::Class::SetStatus(java_lang_reflect_ArtField, mirror::Class::kStatusNotReady, self);
- mirror::Class* Art_field_class = FindSystemClass(self, "Ljava/lang/reflect/ArtField;");
- CHECK_EQ(java_lang_reflect_ArtField.Get(), Art_field_class);
-
mirror::Class* String_array_class =
FindSystemClass(self, GetClassRootDescriptor(kJavaLangStringArrayClass));
CHECK_EQ(object_array_string.Get(), String_array_class);
@@ -525,10 +518,6 @@ void ClassLinker::InitWithoutImage(std::vector<std::unique_ptr<const DexFile>> b
FindSystemClass(self, GetClassRootDescriptor(kJavaLangReflectArtMethodArrayClass));
CHECK_EQ(object_array_art_method.Get(), Art_method_array_class);
- mirror::Class* Art_field_array_class =
- FindSystemClass(self, GetClassRootDescriptor(kJavaLangReflectArtFieldArrayClass));
- CHECK_EQ(object_array_art_field.Get(), Art_field_array_class);
-
// End of special init trickery, subsequent classes may be loaded via FindSystemClass.
// Create java.lang.reflect.Proxy root.
@@ -624,23 +613,23 @@ void ClassLinker::FinishInit(Thread* self) {
mirror::Class* java_lang_ref_FinalizerReference =
FindSystemClass(self, "Ljava/lang/ref/FinalizerReference;");
- mirror::ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
+ ArtField* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
CHECK_STREQ(pendingNext->GetName(), "pendingNext");
CHECK_STREQ(pendingNext->GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
- mirror::ArtField* queue = java_lang_ref_Reference->GetInstanceField(1);
+ ArtField* queue = java_lang_ref_Reference->GetInstanceField(1);
CHECK_STREQ(queue->GetName(), "queue");
CHECK_STREQ(queue->GetTypeDescriptor(), "Ljava/lang/ref/ReferenceQueue;");
- mirror::ArtField* queueNext = java_lang_ref_Reference->GetInstanceField(2);
+ ArtField* queueNext = java_lang_ref_Reference->GetInstanceField(2);
CHECK_STREQ(queueNext->GetName(), "queueNext");
CHECK_STREQ(queueNext->GetTypeDescriptor(), "Ljava/lang/ref/Reference;");
- mirror::ArtField* referent = java_lang_ref_Reference->GetInstanceField(3);
+ ArtField* referent = java_lang_ref_Reference->GetInstanceField(3);
CHECK_STREQ(referent->GetName(), "referent");
CHECK_STREQ(referent->GetTypeDescriptor(), "Ljava/lang/Object;");
- mirror::ArtField* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
+ ArtField* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
CHECK_STREQ(zombie->GetName(), "zombie");
CHECK_STREQ(zombie->GetTypeDescriptor(), "Ljava/lang/Object;");
@@ -802,6 +791,23 @@ void ClassLinker::InitFromImageInterpretOnlyCallback(mirror::Object* obj, void*
}
}
+void SanityCheckObjectsCallback(mirror::Object* obj, void* arg ATTRIBUTE_UNUSED)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(obj != nullptr);
+ CHECK(obj->GetClass() != nullptr) << "Null class " << obj;
+ CHECK(obj->GetClass()->GetClass() != nullptr) << "Null class class " << obj;
+ if (obj->IsClass()) {
+ auto klass = obj->AsClass();
+ ArtField* fields[2] = { klass->GetSFields(), klass->GetIFields() };
+ size_t num_fields[2] = { klass->NumStaticFields(), klass->NumInstanceFields() };
+ for (size_t i = 0; i < 2; ++i) {
+ for (size_t j = 0; j < num_fields[i]; ++j) {
+ CHECK_EQ(fields[i][j].GetDeclaringClass(), klass);
+ }
+ }
+ }
+}
+
void ClassLinker::InitFromImage() {
VLOG(startup) << "ClassLinker::InitFromImage entering";
CHECK(!init_done_);
@@ -882,6 +888,18 @@ void ClassLinker::InitFromImage() {
if (!runtime->IsAotCompiler() && runtime->GetInstrumentation()->InterpretOnly()) {
heap->VisitObjects(InitFromImageInterpretOnlyCallback, this);
}
+ if (kSanityCheckObjects) {
+ for (int32_t i = 0; i < dex_caches->GetLength(); i++) {
+ auto* dex_cache = dex_caches->Get(i);
+ for (size_t j = 0; j < dex_cache->NumResolvedFields(); ++j) {
+ auto* field = dex_cache->GetResolvedField(j, image_pointer_size_);
+ if (field != nullptr) {
+ CHECK(field->GetDeclaringClass()->GetClass() != nullptr);
+ }
+ }
+ }
+ heap->VisitObjects(SanityCheckObjectsCallback, nullptr);
+ }
// reinit class_roots_
mirror::Class::SetClassClass(class_roots->Get(kJavaLangClass));
@@ -894,7 +912,6 @@ void ClassLinker::InitFromImage() {
mirror::Field::SetClass(GetClassRoot(kJavaLangReflectField));
mirror::Field::SetArrayClass(GetClassRoot(kJavaLangReflectFieldArrayClass));
mirror::Reference::SetClass(GetClassRoot(kJavaLangRefReference));
- mirror::ArtField::SetClass(GetClassRoot(kJavaLangReflectArtField));
mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
mirror::CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
@@ -913,18 +930,22 @@ void ClassLinker::InitFromImage() {
void ClassLinker::VisitClassRoots(RootVisitor* visitor, VisitRootFlags flags) {
WriterMutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
+ BufferedRootVisitor<kDefaultBufferedRootCount> buffered_visitor(
+ visitor, RootInfo(kRootStickyClass));
if ((flags & kVisitRootFlagAllRoots) != 0) {
- BufferedRootVisitor<kDefaultBufferedRootCount> buffered_visitor(
- visitor, RootInfo(kRootStickyClass));
for (GcRoot<mirror::Class>& root : class_table_) {
buffered_visitor.VisitRoot(root);
+ root.Read()->VisitFieldRoots(buffered_visitor);
}
+ // PreZygote classes can't move so we won't need to update fields' declaring classes.
for (GcRoot<mirror::Class>& root : pre_zygote_class_table_) {
buffered_visitor.VisitRoot(root);
+ root.Read()->VisitFieldRoots(buffered_visitor);
}
} else if ((flags & kVisitRootFlagNewRoots) != 0) {
for (auto& root : new_class_roots_) {
mirror::Class* old_ref = root.Read<kWithoutReadBarrier>();
+ old_ref->VisitFieldRoots(buffered_visitor);
root.VisitRoot(visitor, RootInfo(kRootStickyClass));
mirror::Class* new_ref = root.Read<kWithoutReadBarrier>();
if (UNLIKELY(new_ref != old_ref)) {
@@ -937,6 +958,7 @@ void ClassLinker::VisitClassRoots(RootVisitor* visitor, VisitRootFlags flags) {
}
}
}
+ buffered_visitor.Flush(); // Flush before clearing new_class_roots_.
if ((flags & kVisitRootFlagClearRootLog) != 0) {
new_class_roots_.clear();
}
@@ -1077,7 +1099,6 @@ ClassLinker::~ClassLinker() {
mirror::Class::ResetClass();
mirror::String::ResetClass();
mirror::Reference::ResetClass();
- mirror::ArtField::ResetClass();
mirror::ArtMethod::ResetClass();
mirror::Field::ResetClass();
mirror::Field::ResetArrayClass();
@@ -1095,7 +1116,7 @@ ClassLinker::~ClassLinker() {
}
mirror::DexCache* ClassLinker::AllocDexCache(Thread* self, const DexFile& dex_file) {
- gc::Heap* heap = Runtime::Current()->GetHeap();
+ gc::Heap* const heap = Runtime::Current()->GetHeap();
StackHandleScope<16> hs(self);
Handle<mirror::Class> dex_cache_class(hs.NewHandle(GetClassRoot(kJavaLangDexCache)));
Handle<mirror::DexCache> dex_cache(
@@ -1125,8 +1146,12 @@ mirror::DexCache* ClassLinker::AllocDexCache(Thread* self, const DexFile& dex_fi
if (methods.Get() == nullptr) {
return nullptr;
}
- Handle<mirror::ObjectArray<mirror::ArtField>>
- fields(hs.NewHandle(AllocArtFieldArray(self, dex_file.NumFieldIds())));
+ Handle<mirror::Array> fields;
+ if (image_pointer_size_ == 8) {
+ fields = hs.NewHandle<mirror::Array>(mirror::LongArray::Alloc(self, dex_file.NumFieldIds()));
+ } else {
+ fields = hs.NewHandle<mirror::Array>(mirror::IntArray::Alloc(self, dex_file.NumFieldIds()));
+ }
if (fields.Get() == nullptr) {
return nullptr;
}
@@ -1154,11 +1179,6 @@ mirror::Class* ClassLinker::AllocClass(Thread* self, uint32_t class_size) {
return AllocClass(self, GetClassRoot(kJavaLangClass), class_size);
}
-mirror::ArtField* ClassLinker::AllocArtField(Thread* self) {
- return down_cast<mirror::ArtField*>(
- GetClassRoot(kJavaLangReflectArtField)->AllocNonMovableObject(self));
-}
-
mirror::ArtMethod* ClassLinker::AllocArtMethod(Thread* self) {
return down_cast<mirror::ArtMethod*>(
GetClassRoot(kJavaLangReflectArtMethod)->AllocNonMovableObject(self));
@@ -1273,16 +1293,13 @@ mirror::Class* ClassLinker::FindClassInPathClassLoader(ScopedObjectAccessAlready
StackHandleScope<3> hs(self);
// The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
// We need to get the DexPathList and loop through it.
- Handle<mirror::ArtField> cookie_field =
- hs.NewHandle(soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie));
- Handle<mirror::ArtField> dex_file_field =
- hs.NewHandle(
- soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile));
+ ArtField* const cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie);
+ ArtField* const dex_file_field =
+ soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
mirror::Object* dex_path_list =
soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList)->
GetObject(class_loader.Get());
- if (dex_path_list != nullptr && dex_file_field.Get() != nullptr &&
- cookie_field.Get() != nullptr) {
+ if (dex_path_list != nullptr && dex_file_field != nullptr && cookie_field != nullptr) {
// DexPathList has an array dexElements of Elements[] which each contain a dex file.
mirror::Object* dex_elements_obj =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
@@ -1433,8 +1450,6 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, si
klass.Assign(GetClassRoot(kJavaLangRefReference));
} else if (strcmp(descriptor, "Ljava/lang/DexCache;") == 0) {
klass.Assign(GetClassRoot(kJavaLangDexCache));
- } else if (strcmp(descriptor, "Ljava/lang/reflect/ArtField;") == 0) {
- klass.Assign(GetClassRoot(kJavaLangReflectArtField));
} else if (strcmp(descriptor, "Ljava/lang/reflect/ArtMethod;") == 0) {
klass.Assign(GetClassRoot(kJavaLangReflectArtMethod));
}
@@ -1452,16 +1467,10 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, si
return nullptr;
}
klass->SetDexCache(FindDexCache(dex_file));
- LoadClass(self, dex_file, dex_class_def, klass, class_loader.Get());
+
+ SetupClass(dex_file, dex_class_def, klass, class_loader.Get());
+
ObjectLock<mirror::Class> lock(self, klass);
- if (self->IsExceptionPending()) {
- // An exception occured during load, set status to erroneous while holding klass' lock in case
- // notification is necessary.
- if (!klass->IsErroneous()) {
- mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
- }
- return nullptr;
- }
klass->SetClinitThreadId(self->GetTid());
// Add the newly loaded class to the loaded classes table.
@@ -1472,6 +1481,20 @@ mirror::Class* ClassLinker::DefineClass(Thread* self, const char* descriptor, si
return EnsureResolved(self, descriptor, existing);
}
+ // Load the fields and other things after we are inserted in the table. This is so that we don't
+ // end up allocating unfree-able linear alloc resources and then lose the race condition. The
+ // other reason is that the field roots are only visited from the class table. So we need to be
+ // inserted before we allocate / fill in these fields.
+ LoadClass(self, dex_file, dex_class_def, klass);
+ if (self->IsExceptionPending()) {
+ // An exception occured during load, set status to erroneous while holding klass' lock in case
+ // notification is necessary.
+ if (!klass->IsErroneous()) {
+ mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self);
+ }
+ return nullptr;
+ }
+
// Finish loading (if necessary) by finding parents
CHECK(!klass->IsLoaded());
if (!LoadSuperAndInterfaces(klass, dex_file)) {
@@ -1845,12 +1868,8 @@ void ClassLinker::LinkCode(Handle<mirror::ArtMethod> method,
}
}
-
-
-void ClassLinker::LoadClass(Thread* self, const DexFile& dex_file,
- const DexFile::ClassDef& dex_class_def,
- Handle<mirror::Class> klass,
- mirror::ClassLoader* class_loader) {
+void ClassLinker::SetupClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
+ Handle<mirror::Class> klass, mirror::ClassLoader* class_loader) {
CHECK(klass.Get() != nullptr);
CHECK(klass->GetDexCache() != nullptr);
CHECK_EQ(mirror::Class::kStatusNotReady, klass->GetStatus());
@@ -1868,13 +1887,15 @@ void ClassLinker::LoadClass(Thread* self, const DexFile& dex_file,
klass->SetDexClassDefIndex(dex_file.GetIndexForClassDef(dex_class_def));
klass->SetDexTypeIndex(dex_class_def.class_idx_);
CHECK(klass->GetDexCacheStrings() != nullptr);
+}
+void ClassLinker::LoadClass(Thread* self, const DexFile& dex_file,
+ const DexFile::ClassDef& dex_class_def,
+ Handle<mirror::Class> klass) {
const uint8_t* class_data = dex_file.GetClassData(dex_class_def);
if (class_data == nullptr) {
return; // no fields or methods - for example a marker interface
}
-
-
bool has_oat_class = false;
if (Runtime::Current()->IsStarted() && !Runtime::Current()->IsAotCompiler()) {
OatFile::OatClass oat_class = FindOatClass(dex_file, klass->GetDexClassDefIndex(),
@@ -1888,51 +1909,41 @@ void ClassLinker::LoadClass(Thread* self, const DexFile& dex_file,
}
}
+ArtField* ClassLinker::AllocArtFieldArray(Thread* self, size_t length) {
+ auto* const la = Runtime::Current()->GetLinearAlloc();
+ auto* ptr = reinterpret_cast<ArtField*>(la->AllocArray<ArtField>(self, length));
+ CHECK(ptr!= nullptr);
+ std::uninitialized_fill_n(ptr, length, ArtField());
+ return ptr;
+}
+
void ClassLinker::LoadClassMembers(Thread* self, const DexFile& dex_file,
const uint8_t* class_data,
Handle<mirror::Class> klass,
const OatFile::OatClass* oat_class) {
- // Load fields.
+ // Load static fields.
ClassDataItemIterator it(dex_file, class_data);
- if (it.NumStaticFields() != 0) {
- mirror::ObjectArray<mirror::ArtField>* statics = AllocArtFieldArray(self, it.NumStaticFields());
- if (UNLIKELY(statics == nullptr)) {
- CHECK(self->IsExceptionPending()); // OOME.
- return;
- }
- klass->SetSFields(statics);
- }
- if (it.NumInstanceFields() != 0) {
- mirror::ObjectArray<mirror::ArtField>* fields =
- AllocArtFieldArray(self, it.NumInstanceFields());
- if (UNLIKELY(fields == nullptr)) {
- CHECK(self->IsExceptionPending()); // OOME.
- return;
- }
- klass->SetIFields(fields);
- }
+ const size_t num_sfields = it.NumStaticFields();
+ ArtField* sfields = num_sfields != 0 ? AllocArtFieldArray(self, num_sfields) : nullptr;
for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
+ CHECK_LT(i, num_sfields);
self->AllowThreadSuspension();
- StackHandleScope<1> hs(self);
- Handle<mirror::ArtField> sfield(hs.NewHandle(AllocArtField(self)));
- if (UNLIKELY(sfield.Get() == nullptr)) {
- CHECK(self->IsExceptionPending()); // OOME.
- return;
- }
- klass->SetStaticField(i, sfield.Get());
- LoadField(dex_file, it, klass, sfield);
- }
+ LoadField(it, klass, &sfields[i]);
+ }
+ klass->SetSFields(sfields);
+ klass->SetNumStaticFields(num_sfields);
+ DCHECK_EQ(klass->NumStaticFields(), num_sfields);
+ // Load instance fields.
+ const size_t num_ifields = it.NumInstanceFields();
+ ArtField* ifields = num_ifields != 0 ? AllocArtFieldArray(self, num_ifields) : nullptr;
for (size_t i = 0; it.HasNextInstanceField(); i++, it.Next()) {
+ CHECK_LT(i, num_ifields);
self->AllowThreadSuspension();
- StackHandleScope<1> hs(self);
- Handle<mirror::ArtField> ifield(hs.NewHandle(AllocArtField(self)));
- if (UNLIKELY(ifield.Get() == nullptr)) {
- CHECK(self->IsExceptionPending()); // OOME.
- return;
- }
- klass->SetInstanceField(i, ifield.Get());
- LoadField(dex_file, it, klass, ifield);
+ LoadField(it, klass, &ifields[i]);
}
+ klass->SetIFields(ifields);
+ klass->SetNumInstanceFields(num_ifields);
+ DCHECK_EQ(klass->NumInstanceFields(), num_ifields);
// Load methods.
if (it.NumDirectMethods() != 0) {
@@ -1995,10 +2006,9 @@ void ClassLinker::LoadClassMembers(Thread* self, const DexFile& dex_file,
DCHECK(!it.HasNext());
}
-void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIterator& it,
- Handle<mirror::Class> klass,
- Handle<mirror::ArtField> dst) {
- uint32_t field_idx = it.GetMemberIndex();
+void ClassLinker::LoadField(const ClassDataItemIterator& it, Handle<mirror::Class> klass,
+ ArtField* dst) {
+ const uint32_t field_idx = it.GetMemberIndex();
dst->SetDexFieldIndex(field_idx);
dst->SetDeclaringClass(klass.Get());
dst->SetAccessFlags(it.GetFieldAccessFlags());
@@ -2282,13 +2292,12 @@ mirror::Class* ClassLinker::CreateArrayClass(Thread* self, const char* descripto
} else if (strcmp(descriptor,
GetClassRootDescriptor(kJavaLangReflectArtMethodArrayClass)) == 0) {
new_class.Assign(GetClassRoot(kJavaLangReflectArtMethodArrayClass));
- } else if (strcmp(descriptor,
- GetClassRootDescriptor(kJavaLangReflectArtFieldArrayClass)) == 0) {
- new_class.Assign(GetClassRoot(kJavaLangReflectArtFieldArrayClass));
} else if (strcmp(descriptor, "[C") == 0) {
new_class.Assign(GetClassRoot(kCharArrayClass));
} else if (strcmp(descriptor, "[I") == 0) {
new_class.Assign(GetClassRoot(kIntArrayClass));
+ } else if (strcmp(descriptor, "[J") == 0) {
+ new_class.Assign(GetClassRoot(kLongArrayClass));
}
}
if (new_class.Get() == nullptr) {
@@ -2919,32 +2928,20 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable&
mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self);
// Instance fields are inherited, but we add a couple of static fields...
- {
- mirror::ObjectArray<mirror::ArtField>* sfields = AllocArtFieldArray(self, 2);
- if (UNLIKELY(sfields == nullptr)) {
- CHECK(self->IsExceptionPending()); // OOME.
- return nullptr;
- }
- klass->SetSFields(sfields);
- }
+ const size_t num_fields = 2;
+ ArtField* sfields = AllocArtFieldArray(self, num_fields);
+ klass->SetSFields(sfields);
+ klass->SetNumStaticFields(num_fields);
+
// 1. Create a static field 'interfaces' that holds the _declared_ interfaces implemented by
// our proxy, so Class.getInterfaces doesn't return the flattened set.
- Handle<mirror::ArtField> interfaces_sfield(hs.NewHandle(AllocArtField(self)));
- if (UNLIKELY(interfaces_sfield.Get() == nullptr)) {
- CHECK(self->IsExceptionPending()); // OOME.
- return nullptr;
- }
- klass->SetStaticField(0, interfaces_sfield.Get());
+ ArtField* interfaces_sfield = &sfields[0];
interfaces_sfield->SetDexFieldIndex(0);
interfaces_sfield->SetDeclaringClass(klass.Get());
interfaces_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
+
// 2. Create a static field 'throws' that holds exceptions thrown by our methods.
- Handle<mirror::ArtField> throws_sfield(hs.NewHandle(AllocArtField(self)));
- if (UNLIKELY(throws_sfield.Get() == nullptr)) {
- CHECK(self->IsExceptionPending()); // OOME.
- return nullptr;
- }
- klass->SetStaticField(1, throws_sfield.Get());
+ ArtField* throws_sfield = &sfields[1];
throws_sfield->SetDexFieldIndex(1);
throws_sfield->SetDeclaringClass(klass.Get());
throws_sfield->SetAccessFlags(kAccStatic | kAccPublic | kAccFinal);
@@ -3332,11 +3329,11 @@ bool ClassLinker::InitializeClass(Thread* self, Handle<mirror::Class> klass,
// Eagerly fill in static fields so that the we don't have to do as many expensive
// Class::FindStaticField in ResolveField.
for (size_t i = 0; i < num_static_fields; ++i) {
- mirror::ArtField* field = klass->GetStaticField(i);
+ ArtField* field = klass->GetStaticField(i);
const uint32_t field_idx = field->GetDexFieldIndex();
- mirror::ArtField* resolved_field = dex_cache->GetResolvedField(field_idx);
+ ArtField* resolved_field = dex_cache->GetResolvedField(field_idx, image_pointer_size_);
if (resolved_field == nullptr) {
- dex_cache->SetResolvedField(field_idx, field);
+ dex_cache->SetResolvedField(field_idx, field, image_pointer_size_);
} else {
DCHECK_EQ(field, resolved_field);
}
@@ -3350,9 +3347,8 @@ bool ClassLinker::InitializeClass(Thread* self, Handle<mirror::Class> klass,
DCHECK(field_it.HasNextStaticField());
CHECK(can_init_statics);
for ( ; value_it.HasNext(); value_it.Next(), field_it.Next()) {
- StackHandleScope<1> hs2(self);
- Handle<mirror::ArtField> field(hs2.NewHandle(
- ResolveField(dex_file, field_it.GetMemberIndex(), dex_cache, class_loader, true)));
+ ArtField* field = ResolveField(
+ dex_file, field_it.GetMemberIndex(), dex_cache, class_loader, true);
if (Runtime::Current()->IsActiveTransaction()) {
value_it.ReadValueToField<true>(field);
} else {
@@ -3586,21 +3582,17 @@ bool ClassLinker::EnsureInitialized(Thread* self, Handle<mirror::Class> c, bool
}
void ClassLinker::FixupTemporaryDeclaringClass(mirror::Class* temp_class, mirror::Class* new_class) {
- mirror::ObjectArray<mirror::ArtField>* fields = new_class->GetIFields();
- if (fields != nullptr) {
- for (int index = 0; index < fields->GetLength(); index ++) {
- if (fields->Get(index)->GetDeclaringClass() == temp_class) {
- fields->Get(index)->SetDeclaringClass(new_class);
- }
+ ArtField* fields = new_class->GetIFields();
+ for (size_t i = 0, count = new_class->NumInstanceFields(); i < count; i++) {
+ if (fields[i].GetDeclaringClass() == temp_class) {
+ fields[i].SetDeclaringClass(new_class);
}
}
fields = new_class->GetSFields();
- if (fields != nullptr) {
- for (int index = 0; index < fields->GetLength(); index ++) {
- if (fields->Get(index)->GetDeclaringClass() == temp_class) {
- fields->Get(index)->SetDeclaringClass(new_class);
- }
+ for (size_t i = 0, count = new_class->NumStaticFields(); i < count; i++) {
+ if (fields[i].GetDeclaringClass() == temp_class) {
+ fields[i].SetDeclaringClass(new_class);
}
}
@@ -4567,7 +4559,7 @@ struct LinkFieldsComparator {
explicit LinkFieldsComparator() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
}
// No thread safety analysis as will be called from STL. Checked lock held in constructor.
- bool operator()(mirror::ArtField* field1, mirror::ArtField* field2)
+ bool operator()(ArtField* field1, ArtField* field2)
NO_THREAD_SAFETY_ANALYSIS {
// First come reference fields, then 64-bit, then 32-bit, and then 16-bit, then finally 8-bit.
Primitive::Type type1 = field1->GetTypeAsPrimitiveType();
@@ -4600,11 +4592,8 @@ struct LinkFieldsComparator {
bool ClassLinker::LinkFields(Thread* self, Handle<mirror::Class> klass, bool is_static,
size_t* class_size) {
self->AllowThreadSuspension();
- size_t num_fields =
- is_static ? klass->NumStaticFields() : klass->NumInstanceFields();
-
- mirror::ObjectArray<mirror::ArtField>* fields =
- is_static ? klass->GetSFields() : klass->GetIFields();
+ const size_t num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields();
+ ArtField* const fields = is_static ? klass->GetSFields() : klass->GetIFields();
// Initialize field_offset
MemberOffset field_offset(0);
@@ -4623,13 +4612,11 @@ bool ClassLinker::LinkFields(Thread* self, Handle<mirror::Class> klass, bool is_
// we want a relatively stable order so that adding new fields
// minimizes disruption of C++ version such as Class and Method.
- std::deque<mirror::ArtField*> grouped_and_sorted_fields;
+ std::deque<ArtField*> grouped_and_sorted_fields;
const char* old_no_suspend_cause = self->StartAssertNoThreadSuspension(
"Naked ArtField references in deque");
for (size_t i = 0; i < num_fields; i++) {
- mirror::ArtField* f = fields->Get(i);
- CHECK(f != nullptr) << PrettyClass(klass.Get());
- grouped_and_sorted_fields.push_back(f);
+ grouped_and_sorted_fields.push_back(&fields[i]);
}
std::sort(grouped_and_sorted_fields.begin(), grouped_and_sorted_fields.end(),
LinkFieldsComparator());
@@ -4640,7 +4627,7 @@ bool ClassLinker::LinkFields(Thread* self, Handle<mirror::Class> klass, bool is_
FieldGaps gaps;
for (; current_field < num_fields; current_field++) {
- mirror::ArtField* field = grouped_and_sorted_fields.front();
+ ArtField* field = grouped_and_sorted_fields.front();
Primitive::Type type = field->GetTypeAsPrimitiveType();
bool isPrimitive = type != Primitive::kPrimNot;
if (isPrimitive) {
@@ -4674,7 +4661,7 @@ bool ClassLinker::LinkFields(Thread* self, Handle<mirror::Class> klass, bool is_
// We know there are no non-reference fields in the Reference classes, and we know
// that 'referent' is alphabetically last, so this is easy...
CHECK_EQ(num_reference_fields, num_fields) << PrettyClass(klass.Get());
- CHECK_STREQ(fields->Get(num_fields - 1)->GetName(), "referent") << PrettyClass(klass.Get());
+ CHECK_STREQ(fields[num_fields - 1].GetName(), "referent") << PrettyClass(klass.Get());
--num_reference_fields;
}
@@ -4713,16 +4700,12 @@ bool ClassLinker::LinkFields(Thread* self, Handle<mirror::Class> klass, bool is_
sizeof(mirror::HeapReference<mirror::Object>));
MemberOffset current_ref_offset = start_ref_offset;
for (size_t i = 0; i < num_fields; i++) {
- mirror::ArtField* field = fields->Get(i);
- if ((false)) { // enable to debug field layout
- LOG(INFO) << "LinkFields: " << (is_static ? "static" : "instance")
- << " class=" << PrettyClass(klass.Get())
- << " field=" << PrettyField(field)
- << " offset="
- << field->GetField32(mirror::ArtField::OffsetOffset());
- }
+ ArtField* field = &fields[i];
+ VLOG(class_linker) << "LinkFields: " << (is_static ? "static" : "instance")
+ << " class=" << PrettyClass(klass.Get()) << " field=" << PrettyField(field) << " offset="
+ << field->GetOffset();
if (i != 0) {
- mirror::ArtField* prev_field = fields->Get(i - 1u);
+ ArtField* const prev_field = &fields[i - 1];
// NOTE: The field names can be the same. This is not possible in the Java language
// but it's valid Java/dex bytecode and for example proguard can generate such bytecode.
CHECK_LE(strcmp(prev_field->GetName(), field->GetName()), 0);
@@ -4994,12 +4977,11 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file, uint32_t
}
}
-mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t field_idx,
- Handle<mirror::DexCache> dex_cache,
- Handle<mirror::ClassLoader> class_loader,
- bool is_static) {
+ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t field_idx,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader, bool is_static) {
DCHECK(dex_cache.Get() != nullptr);
- mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx);
+ ArtField* resolved = dex_cache->GetResolvedField(field_idx, image_pointer_size_);
if (resolved != nullptr) {
return resolved;
}
@@ -5032,16 +5014,15 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi
return nullptr;
}
}
- dex_cache->SetResolvedField(field_idx, resolved);
+ dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
return resolved;
}
-mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file,
- uint32_t field_idx,
- Handle<mirror::DexCache> dex_cache,
- Handle<mirror::ClassLoader> class_loader) {
+ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> class_loader) {
DCHECK(dex_cache.Get() != nullptr);
- mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx);
+ ArtField* resolved = dex_cache->GetResolvedField(field_idx, image_pointer_size_);
if (resolved != nullptr) {
return resolved;
}
@@ -5060,7 +5041,7 @@ mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file,
dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
resolved = mirror::Class::FindField(self, klass, name, type);
if (resolved != nullptr) {
- dex_cache->SetResolvedField(field_idx, resolved);
+ dex_cache->SetResolvedField(field_idx, resolved, image_pointer_size_);
} else {
ThrowNoSuchFieldError("", klass.Get(), type, name);
}
@@ -5190,12 +5171,10 @@ const char* ClassLinker::GetClassRootDescriptor(ClassRoot class_root) {
"Ljava/lang/String;",
"Ljava/lang/DexCache;",
"Ljava/lang/ref/Reference;",
- "Ljava/lang/reflect/ArtField;",
"Ljava/lang/reflect/ArtMethod;",
"Ljava/lang/reflect/Field;",
"Ljava/lang/reflect/Proxy;",
"[Ljava/lang/String;",
- "[Ljava/lang/reflect/ArtField;",
"[Ljava/lang/reflect/ArtMethod;",
"[Ljava/lang/reflect/Field;",
"Ljava/lang/ClassLoader;",
@@ -5310,12 +5289,12 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFi
}
// For now, create a libcore-level DexFile for each ART DexFile. This "explodes" multidex.
- StackHandleScope<11> hs(self);
+ StackHandleScope<10> hs(self);
- Handle<mirror::ArtField> h_dex_elements_field =
- hs.NewHandle(soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements));
+ ArtField* dex_elements_field =
+ soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements);
- mirror::Class* dex_elements_class = h_dex_elements_field->GetType<true>();
+ mirror::Class* dex_elements_class = dex_elements_field->GetType<true>();
DCHECK(dex_elements_class != nullptr);
DCHECK(dex_elements_class->IsArrayClass());
Handle<mirror::ObjectArray<mirror::Object>> h_dex_elements(hs.NewHandle(
@@ -5323,14 +5302,12 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFi
Handle<mirror::Class> h_dex_element_class =
hs.NewHandle(dex_elements_class->GetComponentType());
- Handle<mirror::ArtField> h_element_file_field =
- hs.NewHandle(
- soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile));
- DCHECK_EQ(h_dex_element_class.Get(), h_element_file_field->GetDeclaringClass());
+ ArtField* element_file_field =
+ soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
+ DCHECK_EQ(h_dex_element_class.Get(), element_file_field->GetDeclaringClass());
- Handle<mirror::ArtField> h_cookie_field =
- hs.NewHandle(soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie));
- DCHECK_EQ(h_cookie_field->GetDeclaringClass(), h_element_file_field->GetType<false>());
+ ArtField* cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie);
+ DCHECK_EQ(cookie_field->GetDeclaringClass(), element_file_field->GetType<false>());
// Fill the elements array.
int32_t index = 0;
@@ -5342,13 +5319,13 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFi
h_long_array->Set(0, reinterpret_cast<intptr_t>(dex_file));
Handle<mirror::Object> h_dex_file = hs2.NewHandle(
- h_cookie_field->GetDeclaringClass()->AllocObject(self));
+ cookie_field->GetDeclaringClass()->AllocObject(self));
DCHECK(h_dex_file.Get() != nullptr);
- h_cookie_field->SetObject<false>(h_dex_file.Get(), h_long_array.Get());
+ cookie_field->SetObject<false>(h_dex_file.Get(), h_long_array.Get());
Handle<mirror::Object> h_element = hs2.NewHandle(h_dex_element_class->AllocObject(self));
DCHECK(h_element.Get() != nullptr);
- h_element_file_field->SetObject<false>(h_element.Get(), h_dex_file.Get());
+ element_file_field->SetObject<false>(h_element.Get(), h_dex_file.Get());
h_dex_elements->Set(index, h_element.Get());
index++;
@@ -5357,10 +5334,10 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFi
// Create DexPathList.
Handle<mirror::Object> h_dex_path_list = hs.NewHandle(
- h_dex_elements_field->GetDeclaringClass()->AllocObject(self));
+ dex_elements_field->GetDeclaringClass()->AllocObject(self));
DCHECK(h_dex_path_list.Get() != nullptr);
// Set elements.
- h_dex_elements_field->SetObject<false>(h_dex_path_list.Get(), h_dex_elements.Get());
+ dex_elements_field->SetObject<false>(h_dex_path_list.Get(), h_dex_elements.Get());
// Create PathClassLoader.
Handle<mirror::Class> h_path_class_class = hs.NewHandle(
@@ -5369,20 +5346,20 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, std::vector<const DexFi
h_path_class_class->AllocObject(self));
DCHECK(h_path_class_loader.Get() != nullptr);
// Set DexPathList.
- Handle<mirror::ArtField> h_path_list_field = hs.NewHandle(
- soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList));
- DCHECK(h_path_list_field.Get() != nullptr);
- h_path_list_field->SetObject<false>(h_path_class_loader.Get(), h_dex_path_list.Get());
+ ArtField* path_list_field =
+ soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList);
+ DCHECK(path_list_field != nullptr);
+ path_list_field->SetObject<false>(h_path_class_loader.Get(), h_dex_path_list.Get());
// Make a pretend boot-classpath.
// TODO: Should we scan the image?
- Handle<mirror::ArtField> h_parent_field = hs.NewHandle(
+ ArtField* const parent_field =
mirror::Class::FindField(self, hs.NewHandle(h_path_class_loader->GetClass()), "parent",
- "Ljava/lang/ClassLoader;"));
- DCHECK(h_parent_field.Get() != nullptr);
+ "Ljava/lang/ClassLoader;");
+ DCHECK(parent_field!= nullptr);
mirror::Object* boot_cl =
soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self);
- h_parent_field->SetObject<false>(h_path_class_loader.Get(), boot_cl);
+ parent_field->SetObject<false>(h_path_class_loader.Get(), boot_cl);
// Make it a global ref and return.
ScopedLocalRef<jobject> local_ref(
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 577fec2419..2427462427 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -70,12 +70,10 @@ class ClassLinker {
kJavaLangString,
kJavaLangDexCache,
kJavaLangRefReference,
- kJavaLangReflectArtField,
kJavaLangReflectArtMethod,
kJavaLangReflectField,
kJavaLangReflectProxy,
kJavaLangStringArrayClass,
- kJavaLangReflectArtFieldArrayClass,
kJavaLangReflectArtMethodArrayClass,
kJavaLangReflectFieldArrayClass,
kJavaLangClassLoader,
@@ -201,7 +199,7 @@ class ClassLinker {
mirror::Class* ResolveType(uint16_t type_idx, mirror::ArtMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::Class* ResolveType(uint16_t type_idx, mirror::ArtField* referrer)
+ mirror::Class* ResolveType(uint16_t type_idx, ArtField* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a type with the given ID from the DexFile, storing the
@@ -232,10 +230,11 @@ class ClassLinker {
InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtField* GetResolvedField(uint32_t field_idx, mirror::Class* field_declaring_class)
+ ArtField* GetResolvedField(uint32_t field_idx, mirror::Class* field_declaring_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtField* ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer,
- bool is_static)
+ ArtField* GetResolvedField(uint32_t field_idx, mirror::DexCache* dex_cache)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* ResolveField(uint32_t field_idx, mirror::ArtMethod* referrer, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a field with a given ID from the DexFile, storing the
@@ -243,7 +242,7 @@ class ClassLinker {
// in ResolveType. What is unique is the is_static argument which is
// used to determine if we are resolving a static or non-static
// field.
- mirror::ArtField* ResolveField(const DexFile& dex_file,
+ ArtField* ResolveField(const DexFile& dex_file,
uint32_t field_idx,
Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader,
@@ -254,7 +253,7 @@ class ClassLinker {
// result in DexCache. The ClassLinker and ClassLoader are used as
// in ResolveType. No is_static argument is provided so that Java
// field resolution semantics are followed.
- mirror::ArtField* ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx,
+ ArtField* ResolveFieldJLS(const DexFile& dex_file, uint32_t field_idx,
Handle<mirror::DexCache> dex_cache,
Handle<mirror::ClassLoader> class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -354,7 +353,7 @@ class ClassLinker {
mirror::IfTable* AllocIfTable(Thread* self, size_t ifcount)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ObjectArray<mirror::ArtField>* AllocArtFieldArray(Thread* self, size_t length)
+ ArtField* AllocArtFieldArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ObjectArray<mirror::StackTraceElement>* AllocStackTraceElementArray(Thread* self,
@@ -485,7 +484,6 @@ class ClassLinker {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::DexCache* AllocDexCache(Thread* self, const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtField* AllocArtField(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::Class* CreatePrimitiveClass(Thread* self, Primitive::Type type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -507,15 +505,21 @@ class ClassLinker {
uint32_t SizeOfClassWithoutEmbeddedTables(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def);
+ // Setup the classloader, class def index, type idx so that we can insert this class in the class
+ // table.
+ void SetupClass(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
+ Handle<mirror::Class> klass, mirror::ClassLoader* class_loader)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
void LoadClass(Thread* self, const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
- Handle<mirror::Class> klass, mirror::ClassLoader* class_loader)
+ Handle<mirror::Class> klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void LoadClassMembers(Thread* self, const DexFile& dex_file, const uint8_t* class_data,
Handle<mirror::Class> klass, const OatFile::OatClass* oat_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it,
- Handle<mirror::Class> klass, Handle<mirror::ArtField> dst)
+ void LoadField(const ClassDataItemIterator& it, Handle<mirror::Class> klass,
+ ArtField* dst)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ArtMethod* LoadMethod(Thread* self, const DexFile& dex_file,
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 3f6c5a0ac2..a31a7852c7 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -19,14 +19,13 @@
#include <memory>
#include <string>
+#include "art_field-inl.h"
#include "class_linker-inl.h"
#include "common_runtime_test.h"
#include "dex_file.h"
#include "entrypoints/entrypoint_utils-inl.h"
#include "gc/heap.h"
#include "mirror/accessible_object.h"
-#include "mirror/art_field-inl.h"
-#include "mirror/art_method.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/dex_cache.h"
@@ -173,10 +172,9 @@ class ClassLinkerTest : public CommonRuntimeTest {
method->GetDeclaringClass()->GetDexCache()->GetResolvedTypes()));
}
- void AssertField(mirror::Class* klass, mirror::ArtField* field)
+ void AssertField(mirror::Class* klass, ArtField* field)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
EXPECT_TRUE(field != nullptr);
- EXPECT_TRUE(field->GetClass() != nullptr);
EXPECT_EQ(klass, field->GetDeclaringClass());
EXPECT_TRUE(field->GetName() != nullptr);
EXPECT_TRUE(field->GetType<true>() != nullptr);
@@ -262,30 +260,27 @@ class ClassLinkerTest : public CommonRuntimeTest {
}
for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
- mirror::ArtField* field = klass->GetInstanceField(i);
+ ArtField* field = klass->GetInstanceField(i);
AssertField(klass.Get(), field);
EXPECT_FALSE(field->IsStatic());
}
for (size_t i = 0; i < klass->NumStaticFields(); i++) {
- mirror::ArtField* field = klass->GetStaticField(i);
+ ArtField* field = klass->GetStaticField(i);
AssertField(klass.Get(), field);
EXPECT_TRUE(field->IsStatic());
}
// Confirm that all instances field offsets are packed together at the start.
EXPECT_GE(klass->NumInstanceFields(), klass->NumReferenceInstanceFields());
- StackHandleScope<1> hs(Thread::Current());
- MutableHandle<mirror::ArtField> fhandle = hs.NewHandle<mirror::ArtField>(nullptr);
MemberOffset start_ref_offset = klass->GetFirstReferenceInstanceFieldOffset();
MemberOffset end_ref_offset(start_ref_offset.Uint32Value() +
klass->NumReferenceInstanceFields() *
sizeof(mirror::HeapReference<mirror::Object>));
MemberOffset current_ref_offset = start_ref_offset;
for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
- mirror::ArtField* field = klass->GetInstanceField(i);
- fhandle.Assign(field);
- mirror::Class* field_type = fhandle->GetType<true>();
+ ArtField* field = klass->GetInstanceField(i);
+ mirror::Class* field_type = field->GetType<true>();
ASSERT_TRUE(field_type != nullptr);
if (!field->IsPrimitiveType()) {
ASSERT_TRUE(!field_type->IsPrimitive());
@@ -293,7 +288,7 @@ class ClassLinkerTest : public CommonRuntimeTest {
if (current_ref_offset.Uint32Value() == end_ref_offset.Uint32Value()) {
// While Reference.referent is not primitive, the ClassLinker
// treats it as such so that the garbage collector won't scan it.
- EXPECT_EQ(PrettyField(fhandle.Get()),
+ EXPECT_EQ(PrettyField(field),
"java.lang.Object java.lang.ref.Reference.referent");
} else {
current_ref_offset = MemberOffset(current_ref_offset.Uint32Value() +
@@ -425,7 +420,7 @@ struct CheckOffsets {
}
for (size_t i = 0; i < offsets.size(); i++) {
- mirror::ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
+ ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
StringPiece field_name(field->GetName());
if (field_name != offsets[i].java_name) {
error = true;
@@ -434,7 +429,7 @@ struct CheckOffsets {
if (error) {
for (size_t i = 0; i < offsets.size(); i++) {
CheckOffset& offset = offsets[i];
- mirror::ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
+ ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
StringPiece field_name(field->GetName());
if (field_name != offsets[i].java_name) {
LOG(ERROR) << "JAVA FIELD ORDER MISMATCH NEXT LINE:";
@@ -448,7 +443,7 @@ struct CheckOffsets {
for (size_t i = 0; i < offsets.size(); i++) {
CheckOffset& offset = offsets[i];
- mirror::ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
+ ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
if (field->GetOffset().Uint32Value() != offset.cpp_offset) {
error = true;
}
@@ -456,7 +451,7 @@ struct CheckOffsets {
if (error) {
for (size_t i = 0; i < offsets.size(); i++) {
CheckOffset& offset = offsets[i];
- mirror::ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
+ ArtField* field = is_static ? klass->GetStaticField(i) : klass->GetInstanceField(i);
if (field->GetOffset().Uint32Value() != offset.cpp_offset) {
LOG(ERROR) << "OFFSET MISMATCH NEXT LINE:";
}
@@ -486,15 +481,6 @@ struct ObjectOffsets : public CheckOffsets<mirror::Object> {
};
};
-struct ArtFieldOffsets : public CheckOffsets<mirror::ArtField> {
- ArtFieldOffsets() : CheckOffsets<mirror::ArtField>(false, "Ljava/lang/reflect/ArtField;") {
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtField, access_flags_), "accessFlags"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtField, declaring_class_), "declaringClass"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtField, field_dex_idx_), "fieldDexIndex"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtField, offset_), "offset"));
- };
-};
-
struct ArtMethodOffsets : public CheckOffsets<mirror::ArtMethod> {
ArtMethodOffsets() : CheckOffsets<mirror::ArtMethod>(false, "Ljava/lang/reflect/ArtMethod;") {
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::ArtMethod, access_flags_), "accessFlags"));
@@ -522,8 +508,10 @@ struct ClassOffsets : public CheckOffsets<mirror::Class> {
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, ifields_), "iFields"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, iftable_), "ifTable"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, name_), "name"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_instance_fields_), "numInstanceFields"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_instance_fields_), "numReferenceInstanceFields"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_reference_static_fields_), "numReferenceStaticFields"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, num_static_fields_), "numStaticFields"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, object_size_), "objectSize"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, primitive_type_), "primitiveType"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(mirror::Class, reference_instance_offsets_), "referenceInstanceOffsets"));
@@ -629,7 +617,6 @@ struct FieldOffsets : public CheckOffsets<mirror::Field> {
TEST_F(ClassLinkerTest, ValidateFieldOrderOfJavaCppUnionClasses) {
ScopedObjectAccess soa(Thread::Current());
EXPECT_TRUE(ObjectOffsets().Check());
- EXPECT_TRUE(ArtFieldOffsets().Check());
EXPECT_TRUE(ArtMethodOffsets().Check());
EXPECT_TRUE(ClassOffsets().Check());
EXPECT_TRUE(StringOffsets().Check());
@@ -844,21 +831,21 @@ TEST_F(ClassLinkerTest, ValidateBoxedTypes) {
NullHandle<mirror::ClassLoader> class_loader;
mirror::Class* c;
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Boolean;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Byte;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Character;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Double;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Float;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Integer;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Long;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/Short;", class_loader);
- EXPECT_STREQ("value", c->GetIFields()->Get(0)->GetName());
+ EXPECT_STREQ("value", c->GetIFields()[0].GetName());
}
TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) {
@@ -892,49 +879,47 @@ TEST_F(ClassLinkerTest, StaticFields) {
EXPECT_EQ(9U, statics->NumStaticFields());
- mirror::ArtField* s0 = mirror::Class::FindStaticField(soa.Self(), statics, "s0", "Z");
- std::string temp;
- EXPECT_STREQ(s0->GetClass()->GetDescriptor(&temp), "Ljava/lang/reflect/ArtField;");
+ ArtField* s0 = mirror::Class::FindStaticField(soa.Self(), statics, "s0", "Z");
EXPECT_EQ(s0->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
EXPECT_EQ(true, s0->GetBoolean(statics.Get()));
s0->SetBoolean<false>(statics.Get(), false);
- mirror::ArtField* s1 = mirror::Class::FindStaticField(soa.Self(), statics, "s1", "B");
+ ArtField* s1 = mirror::Class::FindStaticField(soa.Self(), statics, "s1", "B");
EXPECT_EQ(s1->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
EXPECT_EQ(5, s1->GetByte(statics.Get()));
s1->SetByte<false>(statics.Get(), 6);
- mirror::ArtField* s2 = mirror::Class::FindStaticField(soa.Self(), statics, "s2", "C");
+ ArtField* s2 = mirror::Class::FindStaticField(soa.Self(), statics, "s2", "C");
EXPECT_EQ(s2->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
EXPECT_EQ('a', s2->GetChar(statics.Get()));
s2->SetChar<false>(statics.Get(), 'b');
- mirror::ArtField* s3 = mirror::Class::FindStaticField(soa.Self(), statics, "s3", "S");
+ ArtField* s3 = mirror::Class::FindStaticField(soa.Self(), statics, "s3", "S");
EXPECT_EQ(s3->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
EXPECT_EQ(-536, s3->GetShort(statics.Get()));
s3->SetShort<false>(statics.Get(), -535);
- mirror::ArtField* s4 = mirror::Class::FindStaticField(soa.Self(), statics, "s4", "I");
+ ArtField* s4 = mirror::Class::FindStaticField(soa.Self(), statics, "s4", "I");
EXPECT_EQ(s4->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(2000000000, s4->GetInt(statics.Get()));
s4->SetInt<false>(statics.Get(), 2000000001);
- mirror::ArtField* s5 = mirror::Class::FindStaticField(soa.Self(), statics, "s5", "J");
+ ArtField* s5 = mirror::Class::FindStaticField(soa.Self(), statics, "s5", "J");
EXPECT_EQ(s5->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
EXPECT_EQ(0x1234567890abcdefLL, s5->GetLong(statics.Get()));
s5->SetLong<false>(statics.Get(), INT64_C(0x34567890abcdef12));
- mirror::ArtField* s6 = mirror::Class::FindStaticField(soa.Self(), statics, "s6", "F");
+ ArtField* s6 = mirror::Class::FindStaticField(soa.Self(), statics, "s6", "F");
EXPECT_EQ(s6->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
EXPECT_DOUBLE_EQ(0.5, s6->GetFloat(statics.Get()));
s6->SetFloat<false>(statics.Get(), 0.75);
- mirror::ArtField* s7 = mirror::Class::FindStaticField(soa.Self(), statics, "s7", "D");
+ ArtField* s7 = mirror::Class::FindStaticField(soa.Self(), statics, "s7", "D");
EXPECT_EQ(s7->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
EXPECT_DOUBLE_EQ(16777217.0, s7->GetDouble(statics.Get()));
s7->SetDouble<false>(statics.Get(), 16777219);
- mirror::ArtField* s8 = mirror::Class::FindStaticField(soa.Self(), statics, "s8",
+ ArtField* s8 = mirror::Class::FindStaticField(soa.Self(), statics, "s8",
"Ljava/lang/String;");
EXPECT_EQ(s8->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
EXPECT_TRUE(s8->GetObject(statics.Get())->AsString()->Equals("android"));
@@ -1006,13 +991,13 @@ TEST_F(ClassLinkerTest, Interfaces) {
EXPECT_EQ(Aj1, A->FindVirtualMethodForVirtualOrInterface(Jj1));
EXPECT_EQ(Aj2, A->FindVirtualMethodForVirtualOrInterface(Jj2));
- mirror::ArtField* Afoo = mirror::Class::FindStaticField(soa.Self(), A, "foo",
+ ArtField* Afoo = mirror::Class::FindStaticField(soa.Self(), A, "foo",
"Ljava/lang/String;");
- mirror::ArtField* Bfoo = mirror::Class::FindStaticField(soa.Self(), B, "foo",
+ ArtField* Bfoo = mirror::Class::FindStaticField(soa.Self(), B, "foo",
"Ljava/lang/String;");
- mirror::ArtField* Jfoo = mirror::Class::FindStaticField(soa.Self(), J, "foo",
+ ArtField* Jfoo = mirror::Class::FindStaticField(soa.Self(), J, "foo",
"Ljava/lang/String;");
- mirror::ArtField* Kfoo = mirror::Class::FindStaticField(soa.Self(), K, "foo",
+ ArtField* Kfoo = mirror::Class::FindStaticField(soa.Self(), K, "foo",
"Ljava/lang/String;");
ASSERT_TRUE(Afoo != nullptr);
EXPECT_EQ(Afoo, Bfoo);
@@ -1110,9 +1095,6 @@ TEST_F(ClassLinkerTest, ValidatePredefinedClassSizes) {
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/DexCache;", class_loader);
EXPECT_EQ(c->GetClassSize(), mirror::DexCache::ClassSize());
- c = class_linker_->FindClass(soa.Self(), "Ljava/lang/reflect/ArtField;", class_loader);
- EXPECT_EQ(c->GetClassSize(), mirror::ArtField::ClassSize());
-
c = class_linker_->FindClass(soa.Self(), "Ljava/lang/reflect/ArtMethod;", class_loader);
EXPECT_EQ(c->GetClassSize(), mirror::ArtMethod::ClassSize());
}
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index d400010e4b..60b7fa218f 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -398,7 +398,7 @@ std::vector<const DexFile*> CommonRuntimeTest::GetDexFiles(jobject jclass_loader
ScopedObjectAccess soa(Thread::Current());
- StackHandleScope<4> hs(Thread::Current());
+ StackHandleScope<2> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader = hs.NewHandle(
soa.Decode<mirror::ClassLoader*>(jclass_loader));
@@ -409,16 +409,13 @@ std::vector<const DexFile*> CommonRuntimeTest::GetDexFiles(jobject jclass_loader
// The class loader is a PathClassLoader which inherits from BaseDexClassLoader.
// We need to get the DexPathList and loop through it.
- Handle<mirror::ArtField> cookie_field =
- hs.NewHandle(soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie));
- Handle<mirror::ArtField> dex_file_field =
- hs.NewHandle(
- soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile));
+ ArtField* cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie);
+ ArtField* dex_file_field =
+ soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile);
mirror::Object* dex_path_list =
soa.DecodeField(WellKnownClasses::dalvik_system_PathClassLoader_pathList)->
GetObject(class_loader.Get());
- if (dex_path_list != nullptr && dex_file_field.Get() != nullptr &&
- cookie_field.Get() != nullptr) {
+ if (dex_path_list != nullptr && dex_file_field!= nullptr && cookie_field != nullptr) {
// DexPathList has an array dexElements of Elements[] which each contain a dex file.
mirror::Object* dex_elements_obj =
soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList_dexElements)->
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index 36de221549..407746fe95 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -18,6 +18,7 @@
#include <sstream>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "class_linker-inl.h"
#include "dex_file-inl.h"
@@ -160,7 +161,7 @@ void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::ArtMethod* a
ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
}
-void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::ArtField* accessed) {
+void ThrowIllegalAccessErrorField(mirror::Class* referrer, ArtField* accessed) {
std::ostringstream msg;
msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '"
<< PrettyDescriptor(referrer) << "'";
@@ -168,7 +169,7 @@ void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::ArtField* acc
}
void ThrowIllegalAccessErrorFinalField(mirror::ArtMethod* referrer,
- mirror::ArtField* accessed) {
+ ArtField* accessed) {
std::ostringstream msg;
msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '"
<< PrettyMethod(referrer) << "'";
@@ -226,7 +227,7 @@ void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(mirror::ArtMetho
msg.str().c_str());
}
-void ThrowIncompatibleClassChangeErrorField(mirror::ArtField* resolved_field, bool is_static,
+void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field, bool is_static,
mirror::ArtMethod* referrer) {
std::ostringstream msg;
msg << "Expected '" << PrettyField(resolved_field) << "' to be a "
@@ -314,7 +315,7 @@ void ThrowNoSuchMethodError(uint32_t method_idx) {
// NullPointerException
-void ThrowNullPointerExceptionForFieldAccess(mirror::ArtField* field, bool is_read) {
+void ThrowNullPointerExceptionForFieldAccess(ArtField* field, bool is_read) {
std::ostringstream msg;
msg << "Attempt to " << (is_read ? "read from" : "write to")
<< " field '" << PrettyField(field, true) << "' on a null object reference";
@@ -394,7 +395,7 @@ void ThrowNullPointerExceptionFromDexPC() {
case Instruction::IGET_BYTE:
case Instruction::IGET_CHAR:
case Instruction::IGET_SHORT: {
- mirror::ArtField* field =
+ ArtField* field =
Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false);
ThrowNullPointerExceptionForFieldAccess(field, true /* read */);
break;
@@ -408,7 +409,7 @@ void ThrowNullPointerExceptionFromDexPC() {
case Instruction::IGET_OBJECT_QUICK: {
// Since we replaced the field index, we ask the verifier to tell us which
// field is accessed at this location.
- mirror::ArtField* field =
+ ArtField* field =
verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc);
if (field != NULL) {
// NPE with precise message.
@@ -426,7 +427,7 @@ void ThrowNullPointerExceptionFromDexPC() {
case Instruction::IPUT_BYTE:
case Instruction::IPUT_CHAR:
case Instruction::IPUT_SHORT: {
- mirror::ArtField* field =
+ ArtField* field =
Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false);
ThrowNullPointerExceptionForFieldAccess(field, false /* write */);
break;
@@ -440,7 +441,7 @@ void ThrowNullPointerExceptionFromDexPC() {
case Instruction::IPUT_OBJECT_QUICK: {
// Since we replaced the field index, we ask the verifier to tell us which
// field is accessed at this location.
- mirror::ArtField* field =
+ ArtField* field =
verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc);
if (field != NULL) {
// NPE with precise message.
diff --git a/runtime/common_throws.h b/runtime/common_throws.h
index 9e749e3df6..df95cf9a9e 100644
--- a/runtime/common_throws.h
+++ b/runtime/common_throws.h
@@ -22,11 +22,11 @@
namespace art {
namespace mirror {
- class ArtField;
class ArtMethod;
class Class;
class Object;
} // namespace mirror
+class ArtField;
class Signature;
class StringPiece;
@@ -81,10 +81,10 @@ void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirr
void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::ArtMethod* accessed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) COLD_ATTR;
-void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::ArtField* accessed)
+void ThrowIllegalAccessErrorField(mirror::Class* referrer, ArtField* accessed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) COLD_ATTR;
-void ThrowIllegalAccessErrorFinalField(mirror::ArtMethod* referrer, mirror::ArtField* accessed)
+void ThrowIllegalAccessErrorFinalField(mirror::ArtMethod* referrer, ArtField* accessed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) COLD_ATTR;
void ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...)
@@ -112,7 +112,7 @@ void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(mirror::ArtMetho
mirror::ArtMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) COLD_ATTR;
-void ThrowIncompatibleClassChangeErrorField(mirror::ArtField* resolved_field, bool is_static,
+void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field, bool is_static,
mirror::ArtMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) COLD_ATTR;
@@ -160,7 +160,7 @@ void ThrowNoSuchMethodError(uint32_t method_idx)
// NullPointerException
-void ThrowNullPointerExceptionForFieldAccess(mirror::ArtField* field,
+void ThrowNullPointerExceptionForFieldAccess(ArtField* field,
bool is_read)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) COLD_ATTR;
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index a909a1afbe..12fe863ecd 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -21,6 +21,7 @@
#include <set>
#include "arch/context.h"
+#include "art_field-inl.h"
#include "class_linker.h"
#include "class_linker-inl.h"
#include "dex_file-inl.h"
@@ -30,7 +31,6 @@
#include "gc/space/space-inl.h"
#include "handle_scope.h"
#include "jdwp/object_registry.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class.h"
#include "mirror/class-inl.h"
@@ -266,14 +266,14 @@ class DebugInstrumentationListener FINAL : public instrumentation::Instrumentati
}
void FieldRead(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method,
- uint32_t dex_pc, mirror::ArtField* field)
+ uint32_t dex_pc, ArtField* field)
OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
UNUSED(thread);
Dbg::PostFieldAccessEvent(method, dex_pc, this_object, field);
}
void FieldWritten(Thread* thread ATTRIBUTE_UNUSED, mirror::Object* this_object,
- mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field,
+ mirror::ArtMethod* method, uint32_t dex_pc, ArtField* field,
const JValue& field_value)
OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Dbg::PostFieldModificationEvent(method, dex_pc, this_object, field, &field_value);
@@ -1336,8 +1336,7 @@ JDWP::JdwpError Dbg::CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t
return JDWP::ERR_NONE;
}
-JDWP::FieldId Dbg::ToFieldId(const mirror::ArtField* f) {
- CHECK(!kMovingFields);
+JDWP::FieldId Dbg::ToFieldId(const ArtField* f) {
return static_cast<JDWP::FieldId>(reinterpret_cast<uintptr_t>(f));
}
@@ -1347,10 +1346,9 @@ static JDWP::MethodId ToMethodId(const mirror::ArtMethod* m)
return static_cast<JDWP::MethodId>(reinterpret_cast<uintptr_t>(m));
}
-static mirror::ArtField* FromFieldId(JDWP::FieldId fid)
+static ArtField* FromFieldId(JDWP::FieldId fid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(!kMovingFields);
- return reinterpret_cast<mirror::ArtField*>(static_cast<uintptr_t>(fid));
+ return reinterpret_cast<ArtField*>(static_cast<uintptr_t>(fid));
}
static mirror::ArtMethod* FromMethodId(JDWP::MethodId mid)
@@ -1387,8 +1385,8 @@ bool Dbg::MatchType(mirror::Class* event_class, JDWP::RefTypeId class_id) {
}
bool Dbg::MatchField(JDWP::RefTypeId expected_type_id, JDWP::FieldId expected_field_id,
- mirror::ArtField* event_field) {
- mirror::ArtField* expected_field = FromFieldId(expected_field_id);
+ ArtField* event_field) {
+ ArtField* expected_field = FromFieldId(expected_field_id);
if (expected_field != event_field) {
return false;
}
@@ -1423,7 +1421,7 @@ std::string Dbg::GetMethodName(JDWP::MethodId method_id) {
}
std::string Dbg::GetFieldName(JDWP::FieldId field_id) {
- mirror::ArtField* f = FromFieldId(field_id);
+ ArtField* f = FromFieldId(field_id);
if (f == nullptr) {
return "NULL";
}
@@ -1510,7 +1508,7 @@ JDWP::JdwpError Dbg::OutputDeclaredFields(JDWP::RefTypeId class_id, bool with_ge
expandBufAdd4BE(pReply, instance_field_count + static_field_count);
for (size_t i = 0; i < instance_field_count + static_field_count; ++i) {
- mirror::ArtField* f = (i < instance_field_count) ? c->GetInstanceField(i) : c->GetStaticField(i - instance_field_count);
+ ArtField* f = (i < instance_field_count) ? c->GetInstanceField(i) : c->GetStaticField(i - instance_field_count);
expandBufAddFieldId(pReply, ToFieldId(f));
expandBufAddUtf8String(pReply, f->GetName());
expandBufAddUtf8String(pReply, f->GetTypeDescriptor());
@@ -1680,7 +1678,7 @@ void Dbg::OutputMethodReturnValue(JDWP::MethodId method_id, const JValue* return
void Dbg::OutputFieldValue(JDWP::FieldId field_id, const JValue* field_value,
JDWP::ExpandBuf* pReply) {
- mirror::ArtField* f = FromFieldId(field_id);
+ ArtField* f = FromFieldId(field_id);
JDWP::JdwpTag tag = BasicTagFromDescriptor(f->GetTypeDescriptor());
OutputJValue(tag, field_value, pReply);
}
@@ -1723,7 +1721,7 @@ static JDWP::JdwpError GetFieldValueImpl(JDWP::RefTypeId ref_type_id, JDWP::Obje
if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
- mirror::ArtField* f = FromFieldId(field_id);
+ ArtField* f = FromFieldId(field_id);
mirror::Class* receiver_class = c;
if (receiver_class == nullptr && o != nullptr) {
@@ -1785,7 +1783,7 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId
if ((!is_static && o == nullptr) || error != JDWP::ERR_NONE) {
return JDWP::ERR_INVALID_OBJECT;
}
- mirror::ArtField* f = FromFieldId(field_id);
+ ArtField* f = FromFieldId(field_id);
// The RI only enforces the static/non-static mismatch in one direction.
// TODO: should we change the tests and check both?
@@ -1822,11 +1820,10 @@ static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId
if (v != nullptr) {
mirror::Class* field_type;
{
- StackHandleScope<3> hs(Thread::Current());
+ StackHandleScope<2> hs(Thread::Current());
HandleWrapper<mirror::Object> h_v(hs.NewHandleWrapper(&v));
- HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(&f));
HandleWrapper<mirror::Object> h_o(hs.NewHandleWrapper(&o));
- field_type = h_f->GetType<true>();
+ field_type = f->GetType<true>();
}
if (!field_type->IsAssignableFrom(v->GetClass())) {
return JDWP::ERR_INVALID_OBJECT;
@@ -1904,7 +1901,7 @@ JDWP::JdwpError Dbg::GetThreadName(JDWP::ObjectId thread_id, std::string* name)
// We still need to report the zombie threads' names, so we can't just call Thread::GetThreadName.
mirror::Object* thread_object = gRegistry->Get<mirror::Object*>(thread_id, &error);
CHECK(thread_object != nullptr) << error;
- mirror::ArtField* java_lang_Thread_name_field =
+ ArtField* java_lang_Thread_name_field =
soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
mirror::String* s =
reinterpret_cast<mirror::String*>(java_lang_Thread_name_field->GetObject(thread_object));
@@ -1935,7 +1932,7 @@ JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* p
} else if (error == JDWP::ERR_NONE) {
mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread);
CHECK(c != nullptr);
- mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_group);
+ ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_group);
CHECK(f != nullptr);
mirror::Object* group = f->GetObject(thread_object);
CHECK(group != nullptr);
@@ -1976,7 +1973,7 @@ JDWP::JdwpError Dbg::GetThreadGroupName(JDWP::ObjectId thread_group_id, JDWP::Ex
return error;
}
ScopedAssertNoThreadSuspension ants(soa.Self(), "Debugger: GetThreadGroupName");
- mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
+ ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
CHECK(f != nullptr);
mirror::String* s = reinterpret_cast<mirror::String*>(f->GetObject(thread_group));
@@ -1995,7 +1992,7 @@ JDWP::JdwpError Dbg::GetThreadGroupParent(JDWP::ObjectId thread_group_id, JDWP::
mirror::Object* parent;
{
ScopedAssertNoThreadSuspension ants(soa.Self(), "Debugger: GetThreadGroupParent");
- mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_parent);
+ ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_parent);
CHECK(f != nullptr);
parent = f->GetObject(thread_group);
}
@@ -2010,7 +2007,7 @@ static void GetChildThreadGroups(ScopedObjectAccessUnchecked& soa, mirror::Objec
CHECK(thread_group != nullptr);
// Get the ArrayList<ThreadGroup> "groups" out of this thread group...
- mirror::ArtField* groups_field = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_groups);
+ ArtField* groups_field = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_groups);
mirror::Object* groups_array_list = groups_field->GetObject(thread_group);
{
// The "groups" field is declared as a java.util.List: check it really is
@@ -2022,8 +2019,8 @@ static void GetChildThreadGroups(ScopedObjectAccessUnchecked& soa, mirror::Objec
}
// Get the array and size out of the ArrayList<ThreadGroup>...
- mirror::ArtField* array_field = soa.DecodeField(WellKnownClasses::java_util_ArrayList_array);
- mirror::ArtField* size_field = soa.DecodeField(WellKnownClasses::java_util_ArrayList_size);
+ ArtField* array_field = soa.DecodeField(WellKnownClasses::java_util_ArrayList_array);
+ ArtField* size_field = soa.DecodeField(WellKnownClasses::java_util_ArrayList_size);
mirror::ObjectArray<mirror::Object>* groups_array =
array_field->GetObject(groups_array_list)->AsObjectArray<mirror::Object>();
const int32_t size = size_field->GetInt(groups_array_list);
@@ -2069,7 +2066,7 @@ JDWP::JdwpError Dbg::GetThreadGroupChildren(JDWP::ObjectId thread_group_id,
JDWP::ObjectId Dbg::GetSystemThreadGroupId() {
ScopedObjectAccessUnchecked soa(Thread::Current());
- mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup);
+ ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup);
mirror::Object* group = f->GetObject(f->GetDeclaringClass());
return gRegistry->Add(group);
}
@@ -2166,7 +2163,7 @@ static bool IsInDesiredThreadGroup(ScopedObjectAccessUnchecked& soa,
if (desired_thread_group == nullptr) {
return true;
}
- mirror::ArtField* thread_group_field = soa.DecodeField(WellKnownClasses::java_lang_Thread_group);
+ ArtField* thread_group_field = soa.DecodeField(WellKnownClasses::java_lang_Thread_group);
DCHECK(thread_group_field != nullptr);
mirror::Object* group = thread_group_field->GetObject(peer);
return (group == desired_thread_group);
@@ -2771,7 +2768,7 @@ void Dbg::PostLocationEvent(mirror::ArtMethod* m, int dex_pc, mirror::Object* th
}
void Dbg::PostFieldAccessEvent(mirror::ArtMethod* m, int dex_pc,
- mirror::Object* this_object, mirror::ArtField* f) {
+ mirror::Object* this_object, ArtField* f) {
if (!IsDebuggerActive()) {
return;
}
@@ -2784,7 +2781,7 @@ void Dbg::PostFieldAccessEvent(mirror::ArtMethod* m, int dex_pc,
}
void Dbg::PostFieldModificationEvent(mirror::ArtMethod* m, int dex_pc,
- mirror::Object* this_object, mirror::ArtField* f,
+ mirror::Object* this_object, ArtField* f,
const JValue* field_value) {
if (!IsDebuggerActive()) {
return;
diff --git a/runtime/debugger.h b/runtime/debugger.h
index dd7f9c56fa..c287121f84 100644
--- a/runtime/debugger.h
+++ b/runtime/debugger.h
@@ -37,13 +37,13 @@
namespace art {
namespace mirror {
-class ArtField;
class ArtMethod;
class Class;
class Object;
class Throwable;
} // namespace mirror
class AllocRecord;
+class ArtField;
class ObjectRegistry;
class ScopedObjectAccessUnchecked;
class StackVisitor;
@@ -340,7 +340,7 @@ class Dbg {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static bool MatchField(JDWP::RefTypeId expected_type_id, JDWP::FieldId expected_field_id,
- mirror::ArtField* event_field)
+ ArtField* event_field)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static bool MatchInstance(JDWP::ObjectId expected_instance_id, mirror::Object* event_instance)
@@ -525,10 +525,10 @@ class Dbg {
kMethodExit = 0x08,
};
static void PostFieldAccessEvent(mirror::ArtMethod* m, int dex_pc, mirror::Object* this_object,
- mirror::ArtField* f)
+ ArtField* f)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void PostFieldModificationEvent(mirror::ArtMethod* m, int dex_pc,
- mirror::Object* this_object, mirror::ArtField* f,
+ mirror::Object* this_object, ArtField* f,
const JValue* field_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void PostException(mirror::Throwable* exception)
@@ -706,7 +706,7 @@ class Dbg {
static JDWP::JdwpTypeTag GetTypeTag(mirror::Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static JDWP::FieldId ToFieldId(const mirror::ArtField* f)
+ static JDWP::FieldId ToFieldId(const ArtField* f)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void SetJdwpLocation(JDWP::JdwpLocation* location, mirror::ArtMethod* m, uint32_t dex_pc)
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 8685d8e73c..03a47a3f04 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -27,6 +27,7 @@
#include <memory>
#include <sstream>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/stringprintf.h"
#include "class_linker.h"
@@ -34,7 +35,6 @@
#include "dex_file_verifier.h"
#include "globals.h"
#include "leb128.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/string.h"
#include "os.h"
@@ -1210,7 +1210,7 @@ void EncodedStaticFieldValueIterator::Next() {
}
template<bool kTransactionActive>
-void EncodedStaticFieldValueIterator::ReadValueToField(Handle<mirror::ArtField> field) const {
+void EncodedStaticFieldValueIterator::ReadValueToField(ArtField* field) const {
switch (type_) {
case kBoolean: field->SetBoolean<kTransactionActive>(field->GetDeclaringClass(), jval_.z); break;
case kByte: field->SetByte<kTransactionActive>(field->GetDeclaringClass(), jval_.b); break;
@@ -1222,13 +1222,11 @@ void EncodedStaticFieldValueIterator::ReadValueToField(Handle<mirror::ArtField>
case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break;
case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), NULL); break;
case kString: {
- CHECK(!kMovingFields);
mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, *dex_cache_);
field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
break;
}
case kType: {
- CHECK(!kMovingFields);
mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, *dex_cache_,
*class_loader_);
field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
@@ -1237,8 +1235,8 @@ void EncodedStaticFieldValueIterator::ReadValueToField(Handle<mirror::ArtField>
default: UNIMPLEMENTED(FATAL) << ": type " << type_;
}
}
-template void EncodedStaticFieldValueIterator::ReadValueToField<true>(Handle<mirror::ArtField> field) const;
-template void EncodedStaticFieldValueIterator::ReadValueToField<false>(Handle<mirror::ArtField> field) const;
+template void EncodedStaticFieldValueIterator::ReadValueToField<true>(ArtField* field) const;
+template void EncodedStaticFieldValueIterator::ReadValueToField<false>(ArtField* field) const;
CatchHandlerIterator::CatchHandlerIterator(const DexFile::CodeItem& code_item, uint32_t address) {
handler_.address_ = -1;
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 8e2d6c2a55..5bdd9b6c94 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -37,11 +37,11 @@ namespace art {
// TODO: remove dependencies on mirror classes, primarily by moving
// EncodedStaticFieldValueIterator to its own file.
namespace mirror {
- class ArtField;
class ArtMethod;
class ClassLoader;
class DexCache;
} // namespace mirror
+class ArtField;
class ClassLinker;
class MemMap;
class OatDexFile;
@@ -1298,7 +1298,7 @@ class EncodedStaticFieldValueIterator {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<bool kTransactionActive>
- void ReadValueToField(Handle<mirror::ArtField> field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void ReadValueToField(ArtField* field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool HasNext() const { return pos_ < array_size_; }
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 8a13d3498b..cbfba12968 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -252,7 +252,7 @@ inline mirror::Array* AllocArrayFromCodeResolved(mirror::Class* klass,
}
template<FindFieldType type, bool access_check>
-inline mirror::ArtField* FindFieldFromCode(uint32_t field_idx, mirror::ArtMethod* referrer,
+inline ArtField* FindFieldFromCode(uint32_t field_idx, mirror::ArtMethod* referrer,
Thread* self, size_t expected_size) {
bool is_primitive;
bool is_set;
@@ -269,7 +269,7 @@ inline mirror::ArtField* FindFieldFromCode(uint32_t field_idx, mirror::ArtMethod
default: is_primitive = true; is_set = true; is_static = true; break;
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- mirror::ArtField* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
+ ArtField* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
if (UNLIKELY(resolved_field == nullptr)) {
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return nullptr; // Failure.
@@ -324,7 +324,7 @@ inline mirror::ArtField* FindFieldFromCode(uint32_t field_idx, mirror::ArtMethod
// Explicit template declarations of FindFieldFromCode for all field access types.
#define EXPLICIT_FIND_FIELD_FROM_CODE_TEMPLATE_DECL(_type, _access_check) \
template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE \
-mirror::ArtField* FindFieldFromCode<_type, _access_check>(uint32_t field_idx, \
+ArtField* FindFieldFromCode<_type, _access_check>(uint32_t field_idx, \
mirror::ArtMethod* referrer, \
Thread* self, size_t expected_size) \
@@ -469,11 +469,11 @@ EXPLICIT_FIND_METHOD_FROM_CODE_TYPED_TEMPLATE_DECL(kInterface);
#undef EXPLICIT_FIND_METHOD_FROM_CODE_TEMPLATE_DECL
// Fast path field resolution that can't initialize classes or throw exceptions.
-inline mirror::ArtField* FindFieldFast(uint32_t field_idx,
+inline ArtField* FindFieldFast(uint32_t field_idx,
mirror::ArtMethod* referrer,
FindFieldType type, size_t expected_size) {
- mirror::ArtField* resolved_field =
- referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
+ ArtField* resolved_field =
+ referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx, sizeof(void*));
if (UNLIKELY(resolved_field == nullptr)) {
return nullptr;
}
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index 70e2851acd..1d8df68994 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -16,11 +16,11 @@
#include "entrypoints/entrypoint_utils.h"
+#include "art_field-inl.h"
#include "base/mutex.h"
#include "class_linker-inl.h"
#include "dex_file-inl.h"
#include "gc/accounting/card_table-inl.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index 77eec46161..8d419f8a7b 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -30,14 +30,14 @@
namespace art {
namespace mirror {
- class Class;
class Array;
- class ArtField;
class ArtMethod;
+ class Class;
class Object;
class String;
} // namespace mirror
+class ArtField;
class ScopedObjectAccessAlreadyRunnable;
class Thread;
@@ -132,7 +132,7 @@ enum FindFieldType {
};
template<FindFieldType type, bool access_check>
-inline mirror::ArtField* FindFieldFromCode(uint32_t field_idx, mirror::ArtMethod* referrer,
+inline ArtField* FindFieldFromCode(uint32_t field_idx, mirror::ArtMethod* referrer,
Thread* self, size_t expected_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -143,7 +143,7 @@ inline mirror::ArtMethod* FindMethodFromCode(uint32_t method_idx,
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Fast path field resolution that can't initialize classes or throw exceptions.
-inline mirror::ArtField* FindFieldFast(uint32_t field_idx,
+inline ArtField* FindFieldFast(uint32_t field_idx,
mirror::ArtMethod* referrer,
FindFieldType type, size_t expected_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/entrypoints/quick/quick_field_entrypoints.cc b/runtime/entrypoints/quick/quick_field_entrypoints.cc
index 22bf939f6b..b5a7c09531 100644
--- a/runtime/entrypoints/quick/quick_field_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_field_entrypoints.cc
@@ -14,10 +14,10 @@
* limitations under the License.
*/
+#include "art_field-inl.h"
#include "callee_save_frame.h"
#include "dex_file-inl.h"
#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
@@ -29,8 +29,7 @@ extern "C" int8_t artGetByteStaticFromCode(uint32_t field_idx, mirror::ArtMethod
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
- sizeof(int8_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
if (LIKELY(field != nullptr)) {
return field->GetByte(field->GetDeclaringClass());
}
@@ -45,8 +44,7 @@ extern "C" uint8_t artGetBooleanStaticFromCode(uint32_t field_idx, mirror::ArtMe
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
- sizeof(int8_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int8_t));
if (LIKELY(field != nullptr)) {
return field->GetBoolean(field->GetDeclaringClass());
}
@@ -61,8 +59,7 @@ extern "C" int16_t artGetShortStaticFromCode(uint32_t field_idx, mirror::ArtMeth
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
- sizeof(int16_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
if (LIKELY(field != nullptr)) {
return field->GetShort(field->GetDeclaringClass());
}
@@ -78,8 +75,7 @@ extern "C" uint16_t artGetCharStaticFromCode(uint32_t field_idx,
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
- sizeof(int16_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int16_t));
if (LIKELY(field != nullptr)) {
return field->GetChar(field->GetDeclaringClass());
}
@@ -95,8 +91,7 @@ extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
- sizeof(int32_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
if (LIKELY(field != nullptr)) {
return field->Get32(field->GetDeclaringClass());
}
@@ -112,8 +107,7 @@ extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead,
- sizeof(int64_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
if (LIKELY(field != nullptr)) {
return field->Get64(field->GetDeclaringClass());
}
@@ -129,8 +123,8 @@ extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
- sizeof(mirror::HeapReference<mirror::Object>));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr)) {
return field->GetObj(field->GetDeclaringClass());
}
@@ -146,8 +140,7 @@ extern "C" int8_t artGetByteInstanceFromCode(uint32_t field_idx, mirror::Object*
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
- sizeof(int8_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
return field->GetByte(obj);
}
@@ -167,8 +160,7 @@ extern "C" uint8_t artGetBooleanInstanceFromCode(uint32_t field_idx, mirror::Obj
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
- sizeof(int8_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int8_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
return field->GetBoolean(obj);
}
@@ -187,8 +179,7 @@ extern "C" int16_t artGetShortInstanceFromCode(uint32_t field_idx, mirror::Objec
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
- sizeof(int16_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
return field->GetShort(obj);
}
@@ -208,8 +199,7 @@ extern "C" uint16_t artGetCharInstanceFromCode(uint32_t field_idx, mirror::Objec
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
- sizeof(int16_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int16_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
return field->GetChar(obj);
}
@@ -229,8 +219,7 @@ extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object*
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
- sizeof(int32_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
return field->Get32(obj);
}
@@ -250,8 +239,7 @@ extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object*
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead,
- sizeof(int64_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
return field->Get64(obj);
}
@@ -272,13 +260,13 @@ extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror:
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
- sizeof(mirror::HeapReference<mirror::Object>));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr && obj != nullptr)) {
return field->GetObj(obj);
}
- field = FindFieldFromCode<InstanceObjectRead, true>(field_idx, referrer, self,
- sizeof(mirror::HeapReference<mirror::Object>));
+ field = FindFieldFromCode<InstanceObjectRead, true>(
+ field_idx, referrer, self, sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr)) {
if (UNLIKELY(obj == nullptr)) {
ThrowNullPointerExceptionForFieldAccess(field, true);
@@ -293,8 +281,7 @@ extern "C" int artSet8StaticFromCode(uint32_t field_idx, uint32_t new_value,
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
- sizeof(int8_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int8_t));
if (LIKELY(field != nullptr)) {
Primitive::Type type = field->GetTypeAsPrimitiveType();
// Compiled code can't use transactional mode.
@@ -325,8 +312,7 @@ extern "C" int artSet16StaticFromCode(uint32_t field_idx, uint16_t new_value,
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
- sizeof(int16_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int16_t));
if (LIKELY(field != nullptr)) {
Primitive::Type type = field->GetTypeAsPrimitiveType();
// Compiled code can't use transactional mode.
@@ -357,8 +343,7 @@ extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
- sizeof(int32_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
if (LIKELY(field != nullptr)) {
// Compiled code can't use transactional mode.
field->Set32<false>(field->GetDeclaringClass(), new_value);
@@ -377,8 +362,7 @@ extern "C" int artSet64StaticFromCode(uint32_t field_idx, mirror::ArtMethod* ref
uint64_t new_value, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite,
- sizeof(int64_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
if (LIKELY(field != nullptr)) {
// Compiled code can't use transactional mode.
field->Set64<false>(field->GetDeclaringClass(), new_value);
@@ -397,8 +381,8 @@ extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_v
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
- sizeof(mirror::HeapReference<mirror::Object>));
+ ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr)) {
if (LIKELY(!field->IsPrimitiveType())) {
// Compiled code can't use transactional mode.
@@ -420,8 +404,7 @@ extern "C" int artSet8InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
- sizeof(int8_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int8_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
Primitive::Type type = field->GetTypeAsPrimitiveType();
// Compiled code can't use transactional mode.
@@ -460,8 +443,7 @@ extern "C" int artSet16InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
- sizeof(int16_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int16_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
Primitive::Type type = field->GetTypeAsPrimitiveType();
// Compiled code can't use transactional mode.
@@ -501,8 +483,7 @@ extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
- sizeof(int32_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
// Compiled code can't use transactional mode.
field->Set32<false>(obj, new_value);
@@ -530,8 +511,7 @@ extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
- sizeof(int64_t));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t));
if (LIKELY(field != nullptr && obj != nullptr)) {
// Compiled code can't use transactional mode.
field->Set64<false>(obj, new_value);
@@ -556,8 +536,8 @@ extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj
mirror::ArtMethod* referrer, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ScopedQuickEntrypointChecks sqec(self);
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
- sizeof(mirror::HeapReference<mirror::Object>));
+ ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
+ sizeof(mirror::HeapReference<mirror::Object>));
if (LIKELY(field != nullptr && obj != nullptr)) {
// Compiled code can't use transactional mode.
field->SetObj<false>(obj, new_value);
diff --git a/runtime/gc/accounting/mod_union_table.cc b/runtime/gc/accounting/mod_union_table.cc
index a3fac58e8a..cd3f910d95 100644
--- a/runtime/gc/accounting/mod_union_table.cc
+++ b/runtime/gc/accounting/mod_union_table.cc
@@ -28,7 +28,6 @@
#include "gc/heap.h"
#include "gc/space/space.h"
#include "gc/space/image_space.h"
-#include "mirror/art_field-inl.h"
#include "mirror/object-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object_array-inl.h"
diff --git a/runtime/gc/accounting/remembered_set.cc b/runtime/gc/accounting/remembered_set.cc
index b16a146ea9..eeb385e957 100644
--- a/runtime/gc/accounting/remembered_set.cc
+++ b/runtime/gc/accounting/remembered_set.cc
@@ -26,7 +26,6 @@
#include "gc/collector/semi_space.h"
#include "gc/heap.h"
#include "gc/space/space.h"
-#include "mirror/art_field-inl.h"
#include "mirror/object-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object_array-inl.h"
diff --git a/runtime/gc/accounting/space_bitmap.cc b/runtime/gc/accounting/space_bitmap.cc
index ad8d9884ec..2da83250d3 100644
--- a/runtime/gc/accounting/space_bitmap.cc
+++ b/runtime/gc/accounting/space_bitmap.cc
@@ -16,12 +16,12 @@
#include "space_bitmap-inl.h"
+#include "art_field-inl.h"
#include "base/stringprintf.h"
#include "dex_file-inl.h"
#include "mem_map.h"
#include "mirror/object-inl.h"
#include "mirror/class.h"
-#include "mirror/art_field.h"
#include "mirror/object_array.h"
namespace art {
@@ -190,15 +190,13 @@ void SpaceBitmap<kAlignment>::WalkInstanceFields(SpaceBitmap<kAlignment>* visite
WalkInstanceFields(visited, callback, obj, super, arg);
}
// Walk instance fields
- mirror::ObjectArray<mirror::ArtField>* fields = klass->GetIFields();
- if (fields != NULL) {
- for (int32_t i = 0; i < fields->GetLength(); i++) {
- mirror::ArtField* field = fields->Get(i);
- if (!field->IsPrimitiveType()) {
- mirror::Object* value = field->GetObj(obj);
- if (value != NULL) {
- WalkFieldsInOrder(visited, callback, value, arg);
- }
+ auto* fields = klass->GetIFields();
+ for (size_t i = 0, count = klass->NumInstanceFields(); i < count; ++i) {
+ ArtField* field = &fields[i];
+ if (!field->IsPrimitiveType()) {
+ mirror::Object* value = field->GetObj(obj);
+ if (value != nullptr) {
+ WalkFieldsInOrder(visited, callback, value, arg);
}
}
}
@@ -219,15 +217,13 @@ void SpaceBitmap<kAlignment>::WalkFieldsInOrder(SpaceBitmap<kAlignment>* visited
WalkInstanceFields(visited, callback, obj, klass, arg);
// Walk static fields of a Class
if (obj->IsClass()) {
- mirror::ObjectArray<mirror::ArtField>* fields = klass->GetSFields();
- if (fields != NULL) {
- for (int32_t i = 0; i < fields->GetLength(); i++) {
- mirror::ArtField* field = fields->Get(i);
- if (!field->IsPrimitiveType()) {
- mirror::Object* value = field->GetObj(NULL);
- if (value != NULL) {
- WalkFieldsInOrder(visited, callback, value, arg);
- }
+ auto* sfields = klass->GetSFields();
+ for (size_t i = 0, count = klass->NumStaticFields(); i < count; ++i) {
+ ArtField* field = &sfields[i];
+ if (!field->IsPrimitiveType()) {
+ mirror::Object* value = field->GetObj(nullptr);
+ if (value != nullptr) {
+ WalkFieldsInOrder(visited, callback, value, arg);
}
}
}
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 6a68880880..eabb1c2974 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -16,12 +16,12 @@
#include "concurrent_copying.h"
+#include "art_field-inl.h"
#include "gc/accounting/heap_bitmap-inl.h"
#include "gc/accounting/space_bitmap-inl.h"
#include "gc/space/image_space.h"
#include "gc/space/space.h"
#include "intern_table.h"
-#include "mirror/art_field-inl.h"
#include "mirror/object-inl.h"
#include "scoped_thread_state_change.h"
#include "thread-inl.h"
diff --git a/runtime/gc/collector/mark_compact.cc b/runtime/gc/collector/mark_compact.cc
index 8902df8de6..3c247cd4b4 100644
--- a/runtime/gc/collector/mark_compact.cc
+++ b/runtime/gc/collector/mark_compact.cc
@@ -35,8 +35,6 @@
#include "jni_internal.h"
#include "mark_sweep-inl.h"
#include "monitor.h"
-#include "mirror/art_field.h"
-#include "mirror/art_field-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mirror/dex_cache.h"
diff --git a/runtime/gc/collector/mark_sweep-inl.h b/runtime/gc/collector/mark_sweep-inl.h
index 104ed36014..4e3845e5d6 100644
--- a/runtime/gc/collector/mark_sweep-inl.h
+++ b/runtime/gc/collector/mark_sweep-inl.h
@@ -17,10 +17,9 @@
#ifndef ART_RUNTIME_GC_COLLECTOR_MARK_SWEEP_INL_H_
#define ART_RUNTIME_GC_COLLECTOR_MARK_SWEEP_INL_H_
-#include "gc/collector/mark_sweep.h"
+#include "mark_sweep.h"
#include "gc/heap.h"
-#include "mirror/art_field.h"
#include "mirror/class-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/reference.h"
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc
index 79d10347fb..ed2e2954f4 100644
--- a/runtime/gc/collector/mark_sweep.cc
+++ b/runtime/gc/collector/mark_sweep.cc
@@ -39,7 +39,6 @@
#include "gc/space/large_object_space.h"
#include "gc/space/space-inl.h"
#include "mark_sweep-inl.h"
-#include "mirror/art_field-inl.h"
#include "mirror/object-inl.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index b9153c1b29..83da5a8fbd 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -23,6 +23,7 @@
#include <memory>
#include <vector>
+#include "art_field-inl.h"
#include "base/allocator.h"
#include "base/dumpable.h"
#include "base/histogram-inl.h"
@@ -58,7 +59,6 @@
#include "heap-inl.h"
#include "image.h"
#include "intern_table.h"
-#include "mirror/art_field-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object.h"
#include "mirror/object-inl.h"
@@ -233,7 +233,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max
CHECK_GT(oat_file_end_addr, image_space->End());
requested_alloc_space_begin = AlignUp(oat_file_end_addr, kPageSize);
} else {
- LOG(WARNING) << "Could not create image space with image file '" << image_file_name << "'. "
+ LOG(ERROR) << "Could not create image space with image file '" << image_file_name << "'. "
<< "Attempting to fall back to imageless running. Error was: " << error_msg;
}
}
@@ -482,7 +482,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max
non_moving_space_->GetMemMap());
if (!no_gap) {
MemMap::DumpMaps(LOG(ERROR));
- LOG(FATAL) << "There's a gap between the image space and the main space";
+ LOG(FATAL) << "There's a gap between the image space and the non-moving space";
}
}
if (running_on_valgrind_) {
@@ -2708,12 +2708,12 @@ class VerifyReferenceCardVisitor {
// Print which field of the object is dead.
if (!obj->IsObjectArray()) {
mirror::Class* klass = is_static ? obj->AsClass() : obj->GetClass();
- CHECK(klass != NULL);
- mirror::ObjectArray<mirror::ArtField>* fields = is_static ? klass->GetSFields()
- : klass->GetIFields();
- CHECK(fields != NULL);
- for (int32_t i = 0; i < fields->GetLength(); ++i) {
- mirror::ArtField* cur = fields->Get(i);
+ CHECK(klass != nullptr);
+ auto* fields = is_static ? klass->GetSFields() : klass->GetIFields();
+ auto num_fields = is_static ? klass->NumStaticFields() : klass->NumInstanceFields();
+ CHECK_EQ(fields == nullptr, num_fields == 0u);
+ for (size_t i = 0; i < num_fields; ++i) {
+ ArtField* cur = &fields[i];
if (cur->GetOffset().Int32Value() == offset.Int32Value()) {
LOG(ERROR) << (is_static ? "Static " : "") << "field in the live stack is "
<< PrettyField(cur);
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 1fb3252ea9..e28e8d7771 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -43,8 +43,9 @@ namespace space {
Atomic<uint32_t> ImageSpace::bitmap_index_(0);
ImageSpace::ImageSpace(const std::string& image_filename, const char* image_location,
- MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap)
- : MemMapSpace(image_filename, mem_map, mem_map->Begin(), mem_map->End(), mem_map->End(),
+ MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap,
+ uint8_t* end)
+ : MemMapSpace(image_filename, mem_map, mem_map->Begin(), end, end,
kGcRetentionPolicyNeverCollect),
image_location_(image_location) {
DCHECK(live_bitmap != nullptr);
@@ -642,10 +643,10 @@ ImageSpace* ImageSpace::Create(const char* image_location,
void ImageSpace::VerifyImageAllocations() {
uint8_t* current = Begin() + RoundUp(sizeof(ImageHeader), kObjectAlignment);
while (current < End()) {
- DCHECK_ALIGNED(current, kObjectAlignment);
- mirror::Object* obj = reinterpret_cast<mirror::Object*>(current);
- CHECK(live_bitmap_->Test(obj));
+ CHECK_ALIGNED(current, kObjectAlignment);
+ auto* obj = reinterpret_cast<mirror::Object*>(current);
CHECK(obj->GetClass() != nullptr) << "Image object at address " << obj << " has null class";
+ CHECK(live_bitmap_->Test(obj)) << PrettyTypeOf(obj);
if (kUseBakerOrBrooksReadBarrier) {
obj->AssertReadBarrierPointer();
}
@@ -675,7 +676,6 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat
*error_msg = StringPrintf("Invalid image header in '%s'", image_filename);
return nullptr;
}
-
// Check that the file is large enough.
uint64_t image_file_size = static_cast<uint64_t>(file->GetLength());
if (image_header.GetImageSize() > image_file_size) {
@@ -683,23 +683,18 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat
image_file_size, image_header.GetImageSize());
return nullptr;
}
- if (image_header.GetBitmapOffset() + image_header.GetImageBitmapSize() != image_file_size) {
- *error_msg = StringPrintf("Image file too small for image bitmap: %" PRIu64 " vs. %zu.",
- image_file_size,
- image_header.GetBitmapOffset() + image_header.GetImageBitmapSize());
+ auto end_of_bitmap = image_header.GetImageBitmapOffset() + image_header.GetImageBitmapSize();
+ if (end_of_bitmap != image_file_size) {
+ *error_msg = StringPrintf(
+ "Image file size does not equal end of bitmap: size=%" PRIu64 " vs. %zu.", image_file_size,
+ end_of_bitmap);
return nullptr;
}
// Note: The image header is part of the image due to mmap page alignment required of offset.
- std::unique_ptr<MemMap> map(MemMap::MapFileAtAddress(image_header.GetImageBegin(),
- image_header.GetImageSize(),
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE,
- file->Fd(),
- 0,
- false,
- image_filename,
- error_msg));
+ std::unique_ptr<MemMap> map(MemMap::MapFileAtAddress(
+ image_header.GetImageBegin(), image_header.GetImageSize() + image_header.GetArtFieldsSize(),
+ PROT_READ | PROT_WRITE, MAP_PRIVATE, file->Fd(), 0, false, image_filename, error_msg));
if (map.get() == NULL) {
DCHECK(!error_msg->empty());
return nullptr;
@@ -710,7 +705,7 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat
std::unique_ptr<MemMap> image_map(
MemMap::MapFileAtAddress(nullptr, image_header.GetImageBitmapSize(),
PROT_READ, MAP_PRIVATE,
- file->Fd(), image_header.GetBitmapOffset(),
+ file->Fd(), image_header.GetImageBitmapOffset(),
false,
image_filename,
error_msg));
@@ -730,8 +725,9 @@ ImageSpace* ImageSpace::Init(const char* image_filename, const char* image_locat
return nullptr;
}
+ uint8_t* const image_end = map->Begin() + image_header.GetImageSize();
std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename, image_location,
- map.release(), bitmap.release()));
+ map.release(), bitmap.release(), image_end));
// VerifyImageAllocations() will be called later in Runtime::Init()
// as some class roots like ArtMethod::java_lang_reflect_ArtMethod_
diff --git a/runtime/gc/space/image_space.h b/runtime/gc/space/image_space.h
index d7f8057dc0..9ae2af4711 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -145,7 +145,7 @@ class ImageSpace : public MemMapSpace {
std::unique_ptr<accounting::ContinuousSpaceBitmap> live_bitmap_;
ImageSpace(const std::string& name, const char* image_location,
- MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap);
+ MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap, uint8_t* end);
// The OatFile associated with the image during early startup to
// reserve space contiguous to the image. It is later released to
diff --git a/runtime/globals.h b/runtime/globals.h
index ac8751c852..4d7fd2e09c 100644
--- a/runtime/globals.h
+++ b/runtime/globals.h
@@ -71,8 +71,6 @@ static constexpr bool kMarkCompactSupport = false && kMovingCollector;
static constexpr bool kMoveFieldArrays = !kMarkCompactSupport;
// True if we allow moving classes.
static constexpr bool kMovingClasses = !kMarkCompactSupport;
-// True if we allow moving fields.
-static constexpr bool kMovingFields = false;
// True if we allow moving methods.
static constexpr bool kMovingMethods = false;
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index cdb3e2af79..23af25d468 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -37,6 +37,7 @@
#include <set>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
@@ -51,7 +52,6 @@
#include "globals.h"
#include "jdwp/jdwp.h"
#include "jdwp/jdwp_priv.h"
-#include "mirror/art_field-inl.h"
#include "mirror/class.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
@@ -999,7 +999,7 @@ void Hprof::DumpHeapClass(mirror::Class* klass) {
__ AddClassStaticsId(klass);
for (size_t i = 0; i < sFieldCount; ++i) {
- mirror::ArtField* f = klass->GetStaticField(i);
+ ArtField* f = klass->GetStaticField(i);
size_t size;
HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size);
@@ -1038,7 +1038,7 @@ void Hprof::DumpHeapClass(mirror::Class* klass) {
int iFieldCount = klass->IsObjectClass() ? 0 : klass->NumInstanceFields();
__ AddU2((uint16_t)iFieldCount);
for (int i = 0; i < iFieldCount; ++i) {
- mirror::ArtField* f = klass->GetInstanceField(i);
+ ArtField* f = klass->GetInstanceField(i);
__ AddStringId(LookupStringId(f->GetName()));
HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), nullptr);
__ AddU1(t);
@@ -1102,7 +1102,7 @@ void Hprof::DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) {
while (!klass->IsObjectClass()) {
int ifieldCount = klass->NumInstanceFields();
for (int i = 0; i < ifieldCount; ++i) {
- mirror::ArtField* f = klass->GetInstanceField(i);
+ ArtField* f = klass->GetInstanceField(i);
size_t size;
auto t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size);
switch (t) {
diff --git a/runtime/image.cc b/runtime/image.cc
index 3cb25807c6..2d8c1c4b6e 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -24,10 +24,12 @@
namespace art {
const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const uint8_t ImageHeader::kImageVersion[] = { '0', '1', '4', '\0' };
+const uint8_t ImageHeader::kImageVersion[] = { '0', '1', '5', '\0' };
ImageHeader::ImageHeader(uint32_t image_begin,
uint32_t image_size,
+ uint32_t art_fields_offset,
+ uint32_t art_fields_size,
uint32_t image_bitmap_offset,
uint32_t image_bitmap_size,
uint32_t image_roots,
@@ -39,6 +41,8 @@ ImageHeader::ImageHeader(uint32_t image_begin,
bool compile_pic)
: image_begin_(image_begin),
image_size_(image_size),
+ art_fields_offset_(art_fields_offset),
+ art_fields_size_(art_fields_size),
image_bitmap_offset_(image_bitmap_offset),
image_bitmap_size_(image_bitmap_size),
oat_checksum_(oat_checksum),
diff --git a/runtime/image.h b/runtime/image.h
index 3c527b8547..613414aa25 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -32,6 +32,8 @@ class PACKED(4) ImageHeader {
ImageHeader(uint32_t image_begin,
uint32_t image_size_,
+ uint32_t art_fields_offset,
+ uint32_t art_fields_size,
uint32_t image_bitmap_offset,
uint32_t image_bitmap_size,
uint32_t image_roots,
@@ -53,6 +55,14 @@ class PACKED(4) ImageHeader {
return static_cast<uint32_t>(image_size_);
}
+ size_t GetArtFieldsOffset() const {
+ return art_fields_offset_;
+ }
+
+ size_t GetArtFieldsSize() const {
+ return art_fields_size_;
+ }
+
size_t GetImageBitmapOffset() const {
return image_bitmap_offset_;
}
@@ -89,10 +99,6 @@ class PACKED(4) ImageHeader {
return patch_delta_;
}
- size_t GetBitmapOffset() const {
- return RoundUp(image_size_, kPageSize);
- }
-
static std::string GetOatLocationFromImageLocation(const std::string& image) {
std::string oat_filename = image;
if (oat_filename.length() <= 3) {
@@ -140,6 +146,12 @@ class PACKED(4) ImageHeader {
// Image size, not page aligned.
uint32_t image_size_;
+ // ArtField array offset.
+ uint32_t art_fields_offset_;
+
+ // ArtField size in bytes.
+ uint32_t art_fields_size_;
+
// Image bitmap offset in the file.
uint32_t image_bitmap_offset_;
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 680b563df7..f8c0e8328d 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -929,7 +929,7 @@ void Instrumentation::BackwardBranchImpl(Thread* thread, mirror::ArtMethod* meth
void Instrumentation::FieldReadEventImpl(Thread* thread, mirror::Object* this_object,
mirror::ArtMethod* method, uint32_t dex_pc,
- mirror::ArtField* field) const {
+ ArtField* field) const {
if (HasFieldReadListeners()) {
std::shared_ptr<std::list<InstrumentationListener*>> original(field_read_listeners_);
for (InstrumentationListener* listener : *original.get()) {
@@ -940,7 +940,7 @@ void Instrumentation::FieldReadEventImpl(Thread* thread, mirror::Object* this_ob
void Instrumentation::FieldWriteEventImpl(Thread* thread, mirror::Object* this_object,
mirror::ArtMethod* method, uint32_t dex_pc,
- mirror::ArtField* field, const JValue& field_value) const {
+ ArtField* field, const JValue& field_value) const {
if (HasFieldWriteListeners()) {
std::shared_ptr<std::list<InstrumentationListener*>> original(field_write_listeners_);
for (InstrumentationListener* listener : *original.get()) {
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 77314c60c0..41821a6b67 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -30,12 +30,12 @@
namespace art {
namespace mirror {
- class ArtField;
class ArtMethod;
class Class;
class Object;
class Throwable;
} // namespace mirror
+class ArtField;
union JValue;
class Thread;
@@ -82,11 +82,11 @@ struct InstrumentationListener {
// Call-back for when we read from a field.
virtual void FieldRead(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method,
- uint32_t dex_pc, mirror::ArtField* field) = 0;
+ uint32_t dex_pc, ArtField* field) = 0;
// Call-back for when we write into a field.
virtual void FieldWritten(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method,
- uint32_t dex_pc, mirror::ArtField* field, const JValue& field_value) = 0;
+ uint32_t dex_pc, ArtField* field, const JValue& field_value) = 0;
// Call-back when an exception is caught.
virtual void ExceptionCaught(Thread* thread, mirror::Throwable* exception_object)
@@ -301,7 +301,7 @@ class Instrumentation {
// Inform listeners that we read a field (only supported by the interpreter).
void FieldReadEvent(Thread* thread, mirror::Object* this_object,
mirror::ArtMethod* method, uint32_t dex_pc,
- mirror::ArtField* field) const
+ ArtField* field) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (UNLIKELY(HasFieldReadListeners())) {
FieldReadEventImpl(thread, this_object, method, dex_pc, field);
@@ -311,7 +311,7 @@ class Instrumentation {
// Inform listeners that we write a field (only supported by the interpreter).
void FieldWriteEvent(Thread* thread, mirror::Object* this_object,
mirror::ArtMethod* method, uint32_t dex_pc,
- mirror::ArtField* field, const JValue& field_value) const
+ ArtField* field, const JValue& field_value) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (UNLIKELY(HasFieldWriteListeners())) {
FieldWriteEventImpl(thread, this_object, method, dex_pc, field, field_value);
@@ -377,11 +377,11 @@ class Instrumentation {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FieldReadEventImpl(Thread* thread, mirror::Object* this_object,
mirror::ArtMethod* method, uint32_t dex_pc,
- mirror::ArtField* field) const
+ ArtField* field) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FieldWriteEventImpl(Thread* thread, mirror::Object* this_object,
mirror::ArtMethod* method, uint32_t dex_pc,
- mirror::ArtField* field, const JValue& field_value) const
+ ArtField* field, const JValue& field_value) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Read barrier-aware utility functions for accessing deoptimized_methods_
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 375d6445a1..3ae611bcbf 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -281,11 +281,10 @@ bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction
// object in the destructor.
Class* field_class;
{
- StackHandleScope<3> hs(self);
- HandleWrapper<mirror::ArtField> h_f(hs.NewHandleWrapper(&f));
+ StackHandleScope<2> hs(self);
HandleWrapper<mirror::Object> h_reg(hs.NewHandleWrapper(&reg));
HandleWrapper<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
- field_class = h_f->GetType<true>();
+ field_class = f->GetType<true>();
}
if (!reg->VerifierInstanceOf(field_class)) {
// This should never happen.
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 2f8bf554e1..0e0d56a3ad 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -24,6 +24,7 @@
#include <iostream>
#include <sstream>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/macros.h"
#include "class_linker-inl.h"
@@ -32,7 +33,6 @@
#include "dex_instruction-inl.h"
#include "entrypoints/entrypoint_utils-inl.h"
#include "handle_scope-inl.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object-inl.h"
@@ -41,7 +41,6 @@
#include "thread.h"
#include "well_known_classes.h"
-using ::art::mirror::ArtField;
using ::art::mirror::ArtMethod;
using ::art::mirror::Array;
using ::art::mirror::BooleanArray;
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 9af81025d0..dd8c57b664 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -208,20 +208,22 @@ static void UnstartedClassGetDeclaredField(
// going the reflective Dex way.
mirror::Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
mirror::String* name2 = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
- mirror::ArtField* found = nullptr;
- mirror::ObjectArray<mirror::ArtField>* fields = klass->GetIFields();
- for (int32_t i = 0; i < fields->GetLength() && found == nullptr; ++i) {
- mirror::ArtField* f = fields->Get(i);
+ ArtField* found = nullptr;
+ ArtField* fields = klass->GetIFields();
+ for (int32_t i = 0, count = klass->NumInstanceFields(); i < count; ++i) {
+ ArtField* f = &fields[i];
if (name2->Equals(f->GetName())) {
found = f;
+ break;
}
}
if (found == nullptr) {
fields = klass->GetSFields();
- for (int32_t i = 0; i < fields->GetLength() && found == nullptr; ++i) {
- mirror::ArtField* f = fields->Get(i);
+ for (int32_t i = 0, count = klass->NumStaticFields(); i < count; ++i) {
+ ArtField* f = &fields[i];
if (name2->Equals(f->GetName())) {
found = f;
+ break;
}
}
}
diff --git a/runtime/jdwp/jdwp.h b/runtime/jdwp/jdwp.h
index 31c9a0bb4e..a503b17e87 100644
--- a/runtime/jdwp/jdwp.h
+++ b/runtime/jdwp/jdwp.h
@@ -33,11 +33,11 @@ struct iovec;
namespace art {
+class ArtField;
union JValue;
class Thread;
namespace mirror {
- class ArtField;
class ArtMethod;
class Class;
class Object;
@@ -207,7 +207,7 @@ struct JdwpState {
* "fieldValue" is non-null for field modification events only.
* "is_modification" is true for field modification, false for field access.
*/
- void PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field, mirror::Object* thisPtr,
+ void PostFieldEvent(const EventLocation* pLoc, ArtField* field, mirror::Object* thisPtr,
const JValue* fieldValue, bool is_modification)
LOCKS_EXCLUDED(event_list_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc
index c9a4483188..ccf8bffba3 100644
--- a/runtime/jdwp/jdwp_event.cc
+++ b/runtime/jdwp/jdwp_event.cc
@@ -21,6 +21,7 @@
#include <string.h>
#include <unistd.h>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/stringprintf.h"
#include "debugger.h"
@@ -28,7 +29,6 @@
#include "jdwp/jdwp_expand_buf.h"
#include "jdwp/jdwp_priv.h"
#include "jdwp/object_registry.h"
-#include "mirror/art_field-inl.h"
#include "scoped_thread_state_change.h"
#include "thread-inl.h"
@@ -119,7 +119,7 @@ struct ModBasket {
mirror::Class* locationClass; /* ClassOnly */
mirror::Class* exceptionClass; /* ExceptionOnly */
bool caught; /* ExceptionOnly */
- mirror::ArtField* field; /* FieldOnly */
+ ArtField* field; /* FieldOnly */
mirror::Object* thisPtr; /* InstanceOnly */
/* nothing for StepOnly -- handled differently */
};
@@ -914,7 +914,7 @@ void JdwpState::PostLocationEvent(const EventLocation* pLoc, mirror::Object* thi
SendRequestAndPossiblySuspend(pReq, suspend_policy, thread_id);
}
-void JdwpState::PostFieldEvent(const EventLocation* pLoc, mirror::ArtField* field,
+void JdwpState::PostFieldEvent(const EventLocation* pLoc, ArtField* field,
mirror::Object* this_object, const JValue* fieldValue,
bool is_modification) {
DCHECK(pLoc != nullptr);
diff --git a/runtime/jit/jit_instrumentation.h b/runtime/jit/jit_instrumentation.h
index 425d2d3d2d..9d5d74f3f9 100644
--- a/runtime/jit/jit_instrumentation.h
+++ b/runtime/jit/jit_instrumentation.h
@@ -31,12 +31,12 @@
namespace art {
namespace mirror {
- class ArtField;
class ArtMethod;
class Class;
class Object;
class Throwable;
} // namespace mirror
+class ArtField;
union JValue;
class Thread;
@@ -77,10 +77,10 @@ class JitInstrumentationListener : public instrumentation::InstrumentationListen
mirror::ArtMethod* /*method*/, uint32_t /*dex_pc*/) OVERRIDE { }
virtual void FieldRead(Thread* /*thread*/, mirror::Object* /*this_object*/,
mirror::ArtMethod* /*method*/, uint32_t /*dex_pc*/,
- mirror::ArtField* /*field*/) OVERRIDE { }
+ ArtField* /*field*/) OVERRIDE { }
virtual void FieldWritten(Thread* /*thread*/, mirror::Object* /*this_object*/,
mirror::ArtMethod* /*method*/, uint32_t /*dex_pc*/,
- mirror::ArtField* /*field*/, const JValue& /*field_value*/)
+ ArtField* /*field*/, const JValue& /*field_value*/)
OVERRIDE { }
virtual void ExceptionCaught(Thread* /*thread*/,
mirror::Throwable* /*exception_object*/) OVERRIDE { }
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 9ec64d4b07..8a5461baee 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
+#include "art_field-inl.h"
#include "atomic.h"
#include "base/allocator.h"
#include "base/logging.h"
@@ -37,7 +38,6 @@
#include "interpreter/interpreter.h"
#include "jni_env_ext.h"
#include "java_vm_ext.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
@@ -184,7 +184,7 @@ static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, con
if (c.Get() == nullptr) {
return nullptr;
}
- mirror::ArtField* field = nullptr;
+ ArtField* field = nullptr;
mirror::Class* field_type;
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
if (sig[1] != '\0') {
@@ -379,7 +379,7 @@ class JNI {
static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
- mirror::ArtField* f = soa.DecodeField(fid);
+ ArtField* f = soa.DecodeField(fid);
return soa.AddLocalReference<jobject>(mirror::Field::CreateFromArtField(soa.Self(), f, true));
}
@@ -1203,14 +1203,14 @@ class JNI {
CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
mirror::Object* o = soa.Decode<mirror::Object*>(obj);
- mirror::ArtField* f = soa.DecodeField(fid);
+ ArtField* f = soa.DecodeField(fid);
return soa.AddLocalReference<jobject>(f->GetObject(o));
}
static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
- mirror::ArtField* f = soa.DecodeField(fid);
+ ArtField* f = soa.DecodeField(fid);
return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
}
@@ -1220,7 +1220,7 @@ class JNI {
ScopedObjectAccess soa(env);
mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
- mirror::ArtField* f = soa.DecodeField(fid);
+ ArtField* f = soa.DecodeField(fid);
f->SetObject<false>(o, v);
}
@@ -1228,7 +1228,7 @@ class JNI {
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
ScopedObjectAccess soa(env);
mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
- mirror::ArtField* f = soa.DecodeField(fid);
+ ArtField* f = soa.DecodeField(fid);
f->SetObject<false>(f->GetDeclaringClass(), v);
}
@@ -1237,13 +1237,13 @@ class JNI {
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
ScopedObjectAccess soa(env); \
mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
- mirror::ArtField* f = soa.DecodeField(fid); \
+ ArtField* f = soa.DecodeField(fid); \
return f->Get ##fn (o)
#define GET_STATIC_PRIMITIVE_FIELD(fn) \
CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
ScopedObjectAccess soa(env); \
- mirror::ArtField* f = soa.DecodeField(fid); \
+ ArtField* f = soa.DecodeField(fid); \
return f->Get ##fn (f->GetDeclaringClass())
#define SET_PRIMITIVE_FIELD(fn, instance, value) \
@@ -1251,13 +1251,13 @@ class JNI {
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
ScopedObjectAccess soa(env); \
mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
- mirror::ArtField* f = soa.DecodeField(fid); \
+ ArtField* f = soa.DecodeField(fid); \
f->Set ##fn <false>(o, value)
#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
ScopedObjectAccess soa(env); \
- mirror::ArtField* f = soa.DecodeField(fid); \
+ ArtField* f = soa.DecodeField(fid); \
f->Set ##fn <false>(f->GetDeclaringClass(), value)
static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
diff --git a/runtime/linear_alloc.cc b/runtime/linear_alloc.cc
new file mode 100644
index 0000000000..fe6bee6d02
--- /dev/null
+++ b/runtime/linear_alloc.cc
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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 "linear_alloc.h"
+
+#include "thread-inl.h"
+
+namespace art {
+
+LinearAlloc::LinearAlloc(ArenaPool* pool) : lock_("linear alloc"), allocator_(pool) {
+}
+
+void* LinearAlloc::Alloc(Thread* self, size_t size) {
+ MutexLock mu(self, lock_);
+ return allocator_.Alloc(size);
+}
+
+size_t LinearAlloc::GetUsedMemory() const {
+ MutexLock mu(Thread::Current(), lock_);
+ return allocator_.BytesUsed();
+}
+
+} // namespace art
diff --git a/runtime/linear_alloc.h b/runtime/linear_alloc.h
new file mode 100644
index 0000000000..6d8eda6499
--- /dev/null
+++ b/runtime/linear_alloc.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 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_LINEAR_ALLOC_H_
+#define ART_RUNTIME_LINEAR_ALLOC_H_
+
+#include "base/arena_allocator.h"
+
+namespace art {
+
+class ArenaPool;
+
+// TODO: Support freeing if we add poor man's class unloading.
+class LinearAlloc {
+ public:
+ explicit LinearAlloc(ArenaPool* pool);
+
+ void* Alloc(Thread* self, size_t size);
+
+ // Allocate and construct an array of structs of type T.
+ template<class T>
+ T* AllocArray(Thread* self, size_t elements) {
+ return reinterpret_cast<T*>(Alloc(self, elements * sizeof(T)));
+ }
+
+ // Return the number of bytes used in the allocator.
+ size_t GetUsedMemory() const;
+
+ private:
+ mutable Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
+ ArenaAllocator allocator_ GUARDED_BY(lock_);
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_LINEAR_ALLOC_H_
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 588615f9d4..edd2888168 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -622,7 +622,7 @@ void MemMap::DumpMaps(std::ostream& os) {
}
void MemMap::DumpMapsLocked(std::ostream& os) {
- os << maps_;
+ os << *maps_;
}
bool MemMap::HasMemMap(MemMap* map) {
diff --git a/runtime/mirror/array-inl.h b/runtime/mirror/array-inl.h
index 6452f31ebc..8b3418d6be 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -203,7 +203,7 @@ inline void PrimitiveArray<T>::VisitRoots(RootVisitor* visitor) {
template<typename T>
inline PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
Array* raw_array = Array::Alloc<true>(self, GetArrayClass(), length,
- ComponentSizeShiftWidth<sizeof(T)>(),
+ ComponentSizeShiftWidth(sizeof(T)),
Runtime::Current()->GetHeap()->GetCurrentAllocator());
return down_cast<PrimitiveArray<T>*>(raw_array);
}
diff --git a/runtime/mirror/array.h b/runtime/mirror/array.h
index 115fcf2408..832ad68dcd 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -54,7 +54,7 @@ class MANAGED Array : public Object {
}
void SetLength(int32_t length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK_GE(length, 0);
+ DCHECK_GE(length, 0);
// We use non transactional version since we can't undo this write. We also disable checking
// since it would fail during a transaction.
SetField32<false, false, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Array, length_), length);
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index edbbb4af30..92aea1f3cc 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -53,7 +53,7 @@ GcRoot<Class> ArtMethod::java_lang_reflect_ArtMethod_;
ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
jobject jlr_method) {
- mirror::ArtField* f =
+ ArtField* f =
soa.DecodeField(WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
mirror::ArtMethod* method = f->GetObject(soa.Decode<mirror::Object*>(jlr_method))->AsArtMethod();
DCHECK(method != nullptr);
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index c368dc6d04..5b72e5a033 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -397,9 +397,9 @@ inline void Class::SetIfTable(IfTable* new_iftable) {
SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable);
}
-inline ObjectArray<ArtField>* Class::GetIFields() {
+inline ArtField* Class::GetIFields() {
DCHECK(IsLoaded() || IsErroneous());
- return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
+ return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
}
inline MemberOffset Class::GetFirstReferenceInstanceFieldOffset() {
@@ -432,55 +432,46 @@ inline MemberOffset Class::GetFirstReferenceStaticFieldOffsetDuringLinking() {
return MemberOffset(base);
}
-inline void Class::SetIFields(ObjectArray<ArtField>* new_ifields)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_)));
- SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
+inline void Class::SetIFields(ArtField* new_ifields) {
+ DCHECK(GetIFieldsUnchecked() == nullptr);
+ return SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
}
-inline ObjectArray<ArtField>* Class::GetSFields() {
- DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
- return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+inline void Class::SetIFieldsUnchecked(ArtField* new_ifields) {
+ SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
}
-inline void Class::SetSFields(ObjectArray<ArtField>* new_sfields)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK((IsRetired() && new_sfields == nullptr) ||
- (NULL == GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_))));
- SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
+inline ArtField* Class::GetSFieldsUnchecked() {
+ return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
}
-inline uint32_t Class::NumStaticFields() {
- return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
+inline ArtField* Class::GetIFieldsUnchecked() {
+ return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
}
-
-inline ArtField* Class::GetStaticField(uint32_t i) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetSFields()->GetWithoutChecks(i);
+inline ArtField* Class::GetSFields() {
+ DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
+ return GetSFieldsUnchecked();
}
-inline void Class::SetStaticField(uint32_t i, ArtField* f) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectArray<ArtField>* sfields= GetFieldObject<ObjectArray<ArtField>>(
- OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
- sfields->Set<false>(i, f);
+inline void Class::SetSFields(ArtField* new_sfields) {
+ DCHECK((IsRetired() && new_sfields == nullptr) ||
+ GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
+ SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
}
-inline uint32_t Class::NumInstanceFields() {
- return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
+inline void Class::SetSFieldsUnchecked(ArtField* new_sfields) {
+ SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
}
-inline ArtField* Class::GetInstanceField(uint32_t i) { // TODO: uint16_t
- DCHECK_NE(NumInstanceFields(), 0U);
- return GetIFields()->GetWithoutChecks(i);
+inline ArtField* Class::GetStaticField(uint32_t i) {
+ DCHECK_LT(i, NumStaticFields());
+ return &GetSFields()[i];
}
-inline void Class::SetInstanceField(uint32_t i, ArtField* f) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectArray<ArtField>* ifields= GetFieldObject<ObjectArray<ArtField>>(
- OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
- ifields->Set<false>(i, f);
+inline ArtField* Class::GetInstanceField(uint32_t i) {
+ DCHECK_LT(i, NumInstanceFields());
+ return &GetIFields()[i];
}
template<VerifyObjectFlags kVerifyFlags>
@@ -513,14 +504,12 @@ inline uint32_t Class::GetAccessFlags() {
DCHECK(IsIdxLoaded<kVerifyFlags>() || IsRetired<kVerifyFlags>() ||
IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>() ||
this == String::GetJavaLangString() ||
- this == ArtField::GetJavaLangReflectArtField() ||
this == ArtMethod::GetJavaLangReflectArtMethod())
<< "IsIdxLoaded=" << IsIdxLoaded<kVerifyFlags>()
<< " IsRetired=" << IsRetired<kVerifyFlags>()
<< " IsErroneous=" <<
IsErroneous<static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis)>()
<< " IsString=" << (this == String::GetJavaLangString())
- << " IsArtField=" << (this == ArtField::GetJavaLangReflectArtField())
<< " IsArtMethod=" << (this == ArtMethod::GetJavaLangReflectArtMethod())
<< " descriptor=" << PrettyDescriptor(this);
return GetField32<kVerifyFlags>(AccessFlagsOffset());
@@ -691,11 +680,6 @@ inline void Class::VisitEmbeddedImtAndVTable(const Visitor& visitor) {
}
template<ReadBarrierOption kReadBarrierOption>
-inline bool Class::IsArtFieldClass() const {
- return this == ArtField::GetJavaLangReflectArtField<kReadBarrierOption>();
-}
-
-template<ReadBarrierOption kReadBarrierOption>
inline bool Class::IsArtMethodClass() const {
return this == ArtMethod::GetJavaLangReflectArtMethod<kReadBarrierOption>();
}
@@ -741,35 +725,35 @@ inline void Class::AssertInitializedOrInitializingInThread(Thread* self) {
inline ObjectArray<Class>* Class::GetInterfaces() {
CHECK(IsProxyClass());
// First static field.
- DCHECK(GetSFields()->Get(0)->IsArtField());
- DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "interfaces");
- MemberOffset field_offset = GetSFields()->Get(0)->GetOffset();
+ auto* field = GetStaticField(0);
+ DCHECK_STREQ(field->GetName(), "interfaces");
+ MemberOffset field_offset = field->GetOffset();
return GetFieldObject<ObjectArray<Class>>(field_offset);
}
inline ObjectArray<ObjectArray<Class>>* Class::GetThrows() {
CHECK(IsProxyClass());
// Second static field.
- DCHECK(GetSFields()->Get(1)->IsArtField());
- DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "throws");
- MemberOffset field_offset = GetSFields()->Get(1)->GetOffset();
+ auto* field = GetStaticField(1);
+ DCHECK_STREQ(field->GetName(), "throws");
+ MemberOffset field_offset = field->GetOffset();
return GetFieldObject<ObjectArray<ObjectArray<Class>>>(field_offset);
}
inline MemberOffset Class::GetDisableIntrinsicFlagOffset() {
CHECK(IsReferenceClass());
// First static field
- DCHECK(GetSFields()->Get(0)->IsArtField());
- DCHECK_STREQ(GetSFields()->Get(0)->GetName(), "disableIntrinsic");
- return GetSFields()->Get(0)->GetOffset();
+ auto* field = GetStaticField(0);
+ DCHECK_STREQ(field->GetName(), "disableIntrinsic");
+ return field->GetOffset();
}
inline MemberOffset Class::GetSlowPathFlagOffset() {
CHECK(IsReferenceClass());
// Second static field
- DCHECK(GetSFields()->Get(1)->IsArtField());
- DCHECK_STREQ(GetSFields()->Get(1)->GetName(), "slowPathEnabled");
- return GetSFields()->Get(1)->GetOffset();
+ auto* field = GetStaticField(1);
+ DCHECK_STREQ(field->GetName(), "slowPathEnabled");
+ return field->GetOffset();
}
inline bool Class::GetSlowPathEnabled() {
@@ -827,6 +811,24 @@ inline ObjectArray<String>* Class::GetDexCacheStrings() {
return GetFieldObject<ObjectArray<String>>(DexCacheStringsOffset());
}
+template<class Visitor>
+void mirror::Class::VisitFieldRoots(Visitor& visitor) {
+ ArtField* const sfields = GetSFieldsUnchecked();
+ for (size_t i = 0, count = NumStaticFields(); i < count; ++i) {
+ if (kIsDebugBuild && GetStatus() != kStatusRetired) {
+ CHECK_EQ(sfields[i].GetDeclaringClass(), this);
+ }
+ visitor.VisitRoot(sfields[i].DeclaringClassRoot().AddressWithoutBarrier());
+ }
+ ArtField* const ifields = GetIFieldsUnchecked();
+ for (size_t i = 0, count = NumInstanceFields(); i < count; ++i) {
+ if (kIsDebugBuild && GetStatus() != kStatusRetired) {
+ CHECK_EQ(ifields[i].GetDeclaringClass(), this);
+ }
+ visitor.VisitRoot(ifields[i].DeclaringClassRoot().AddressWithoutBarrier());
+ }
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index b82a58f4c2..92493bc567 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -35,6 +35,7 @@
namespace art {
+class ArtField;
struct ClassOffsets;
template<class T> class Handle;
template<class T> class Handle;
@@ -44,7 +45,6 @@ template<size_t kNumReferences> class PACKED(4) StackHandleScope;
namespace mirror {
-class ArtField;
class ArtMethod;
class ClassLoader;
class DexCache;
@@ -420,9 +420,6 @@ class MANAGED Class FINAL : public Object {
bool IsThrowableClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- bool IsArtFieldClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
bool IsArtMethodClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
@@ -823,17 +820,22 @@ class MANAGED Class FINAL : public Object {
ALWAYS_INLINE void SetIfTable(IfTable* new_iftable) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get instance fields of the class (See also GetSFields).
- ObjectArray<ArtField>* GetIFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* GetIFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetIFields(ObjectArray<ArtField>* new_ifields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetIFields(ArtField* new_ifields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint32_t NumInstanceFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Unchecked edition has no verification flags.
+ void SetIFieldsUnchecked(ArtField* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtField* GetInstanceField(uint32_t i) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint32_t NumInstanceFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_instance_fields_));
+ }
- void SetInstanceField(uint32_t i, ArtField* f) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetNumInstanceFields(uint32_t num) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_instance_fields_), num);
+ }
+
+ ArtField* GetInstanceField(uint32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns the number of instance fields containing reference types.
uint32_t NumReferenceInstanceFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -884,17 +886,23 @@ class MANAGED Class FINAL : public Object {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Gets the static fields of the class.
- ObjectArray<ArtField>* GetSFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* GetSFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetSFields(ObjectArray<ArtField>* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetSFields(ArtField* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint32_t NumStaticFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Unchecked edition has no verification flags.
+ void SetSFieldsUnchecked(ArtField* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- // TODO: uint16_t
- ArtField* GetStaticField(uint32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint32_t NumStaticFields() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_static_fields_));
+ }
+
+ void SetNumStaticFields(uint32_t num) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, num_static_fields_), num);
+ }
// TODO: uint16_t
- void SetStaticField(uint32_t i, ArtField* f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* GetStaticField(uint32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Find a static or instance field using the JLS resolution order
static ArtField* FindField(Thread* self, Handle<Class> klass, const StringPiece& name,
@@ -974,6 +982,10 @@ class MANAGED Class FINAL : public Object {
static void VisitRoots(RootVisitor* visitor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ template<class Visitor>
+ // Visit field roots.
+ void VisitFieldRoots(Visitor& visitor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// When class is verified, set the kAccPreverified flag on each method.
void SetPreverifiedFlagOnAllMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -1079,6 +1091,10 @@ class MANAGED Class FINAL : public Object {
void CheckObjectAlloc() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Unchecked editions is for root visiting.
+ ArtField* GetSFieldsUnchecked() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* GetIFieldsUnchecked() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// defining class loader, or NULL for the "bootstrap" system loader
HeapReference<ClassLoader> class_loader_;
@@ -1096,18 +1112,6 @@ class MANAGED Class FINAL : public Object {
// static, private, and <init> methods
HeapReference<ObjectArray<ArtMethod>> direct_methods_;
- // instance fields
- //
- // These describe the layout of the contents of an Object.
- // Note that only the fields directly declared by this class are
- // listed in ifields; fields declared by a superclass are listed in
- // the superclass's Class.ifields.
- //
- // All instance fields that refer to objects are guaranteed to be at
- // the beginning of the field list. num_reference_instance_fields_
- // specifies the number of reference fields.
- HeapReference<ObjectArray<ArtField>> ifields_;
-
// The interface table (iftable_) contains pairs of a interface class and an array of the
// interface methods. There is one pair per interface supported by this class. That means one
// pair for each interface we support directly, indirectly via superclass, or indirectly via a
@@ -1124,9 +1128,6 @@ class MANAGED Class FINAL : public Object {
// Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName
HeapReference<String> name_;
- // Static fields
- HeapReference<ObjectArray<ArtField>> sfields_;
-
// The superclass, or NULL if this is java.lang.Object, an interface or primitive type.
HeapReference<Class> super_class_;
@@ -1143,8 +1144,22 @@ class MANAGED Class FINAL : public Object {
HeapReference<ObjectArray<ArtMethod>> vtable_;
// Access flags; low 16 bits are defined by VM spec.
+ // Note: Shuffled back.
uint32_t access_flags_;
+ // instance fields
+ //
+ // These describe the layout of the contents of an Object.
+ // Note that only the fields directly declared by this class are
+ // listed in ifields; fields declared by a superclass are listed in
+ // the superclass's Class.ifields.
+ //
+ // ArtField arrays are allocated as an array of fields, and not an array of fields pointers.
+ uint64_t ifields_;
+
+ // Static fields
+ uint64_t sfields_;
+
// Total size of the Class instance; used when allocating storage on gc heap.
// See also object_size_.
uint32_t class_size_;
@@ -1160,12 +1175,18 @@ class MANAGED Class FINAL : public Object {
// TODO: really 16bits
int32_t dex_type_idx_;
+ // Number of static fields.
+ uint32_t num_instance_fields_;
+
// Number of instance fields that are object refs.
uint32_t num_reference_instance_fields_;
// Number of static fields that are object refs,
uint32_t num_reference_static_fields_;
+ // Number of static fields.
+ uint32_t num_static_fields_;
+
// Total object size; used when allocating storage on gc heap.
// (For interfaces and abstract classes this will be zero.)
// See also class_size_.
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index 6758e22a20..1cb437e8ea 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -19,6 +19,7 @@
#include "dex_cache.h"
+#include "art_field-inl.h"
#include "base/logging.h"
#include "mirror/class.h"
#include "runtime.h"
@@ -35,12 +36,11 @@ inline ArtMethod* DexCache::GetResolvedMethod(uint32_t method_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ArtMethod* method = GetResolvedMethods()->Get(method_idx);
// Hide resolution trampoline methods from the caller
- if (method != NULL && method->IsRuntimeMethod()) {
- DCHECK(method == Runtime::Current()->GetResolutionMethod());
- return NULL;
- } else {
- return method;
+ if (method != nullptr && method->IsRuntimeMethod()) {
+ DCHECK_EQ(method, Runtime::Current()->GetResolutionMethod());
+ return nullptr;
}
+ return method;
}
inline void DexCache::SetResolvedType(uint32_t type_idx, Class* resolved) {
@@ -49,6 +49,34 @@ inline void DexCache::SetResolvedType(uint32_t type_idx, Class* resolved) {
GetResolvedTypes()->Set(type_idx, resolved);
}
+inline ArtField* DexCache::GetResolvedField(uint32_t idx, size_t ptr_size) {
+ ArtField* field = nullptr;
+ if (ptr_size == 8) {
+ field = reinterpret_cast<ArtField*>(
+ static_cast<uintptr_t>(GetResolvedFields()->AsLongArray()->GetWithoutChecks(idx)));
+ } else {
+ DCHECK_EQ(ptr_size, 4u);
+ field = reinterpret_cast<ArtField*>(
+ static_cast<uintptr_t>(GetResolvedFields()->AsIntArray()->GetWithoutChecks(idx)));
+ }
+ if (field == nullptr || field->GetDeclaringClass()->IsErroneous()) {
+ return nullptr;
+ }
+ return field;
+}
+
+inline void DexCache::SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size) {
+ if (ptr_size == 8) {
+ GetResolvedFields()->AsLongArray()->Set(
+ idx, static_cast<uint64_t>(reinterpret_cast<uintptr_t>(field)));
+ } else {
+ DCHECK_EQ(ptr_size, 4u);
+ CHECK_LE(reinterpret_cast<uintptr_t>(field), 0xFFFFFFFF);
+ GetResolvedFields()->AsIntArray()->Set(
+ idx, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(field)));
+ }
+}
+
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/dex_cache.cc b/runtime/mirror/dex_cache.cc
index d6c11e8b0c..ade8bd27ec 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -36,7 +36,7 @@ void DexCache::Init(const DexFile* dex_file,
ObjectArray<String>* strings,
ObjectArray<Class>* resolved_types,
ObjectArray<ArtMethod>* resolved_methods,
- ObjectArray<ArtField>* resolved_fields) {
+ Array* resolved_fields) {
CHECK(dex_file != nullptr);
CHECK(location != nullptr);
CHECK(strings != nullptr);
@@ -44,19 +44,18 @@ void DexCache::Init(const DexFile* dex_file,
CHECK(resolved_methods != nullptr);
CHECK(resolved_fields != nullptr);
- SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, dex_file_), dex_file);
+ SetDexFile(dex_file);
SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, location_), location);
SetFieldObject<false>(StringsOffset(), strings);
+ SetFieldObject<false>(ResolvedFieldsOffset(), resolved_fields);
SetFieldObject<false>(OFFSET_OF_OBJECT_MEMBER(DexCache, resolved_types_), resolved_types);
SetFieldObject<false>(ResolvedMethodsOffset(), resolved_methods);
- SetFieldObject<false>(ResolvedFieldsOffset(), resolved_fields);
Runtime* runtime = Runtime::Current();
if (runtime->HasResolutionMethod()) {
// Initialize the resolve methods array to contain trampolines for resolution.
ArtMethod* trampoline = runtime->GetResolutionMethod();
- size_t length = resolved_methods->GetLength();
- for (size_t i = 0; i < length; i++) {
+ for (size_t i = 0, length = resolved_methods->GetLength(); i < length; i++) {
resolved_methods->SetWithoutChecks<false>(i, trampoline);
}
}
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index c548c03e63..7e30b891de 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -50,7 +50,7 @@ class MANAGED DexCache FINAL : public Object {
ObjectArray<String>* strings,
ObjectArray<Class>* types,
ObjectArray<ArtMethod>* methods,
- ObjectArray<ArtField>* fields)
+ Array* fields)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void Fixup(ArtMethod* trampoline) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -116,23 +116,16 @@ class MANAGED DexCache FINAL : public Object {
GetResolvedMethods()->Set(method_idx, resolved);
}
- ArtField* GetResolvedField(uint32_t field_idx) ALWAYS_INLINE
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ArtField* field = GetResolvedFields()->Get(field_idx);
- if (UNLIKELY(field == nullptr || field->GetDeclaringClass()->IsErroneous())) {
- return nullptr;
- } else {
- return field;
- }
- }
+ // Pointer sized variant, used for patching.
+ ArtField* GetResolvedField(uint32_t idx, size_t ptr_size)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetResolvedField(uint32_t field_idx, ArtField* resolved) ALWAYS_INLINE
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- GetResolvedFields()->Set(field_idx, resolved);
- }
+ // Pointer sized variant, used for patching.
+ void SetResolvedField(uint32_t idx, ArtField* field, size_t ptr_size)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
ObjectArray<String>* GetStrings() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetFieldObject< ObjectArray<String>>(StringsOffset());
+ return GetFieldObject<ObjectArray<String>>(StringsOffset());
}
ObjectArray<Class>* GetResolvedTypes() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -145,9 +138,8 @@ class MANAGED DexCache FINAL : public Object {
return GetFieldObject< ObjectArray<ArtMethod>>(ResolvedMethodsOffset());
}
- ObjectArray<ArtField>* GetResolvedFields() ALWAYS_INLINE
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetFieldObject<ObjectArray<ArtField>>(ResolvedFieldsOffset());
+ Array* GetResolvedFields() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetFieldObject<Array>(ResolvedFieldsOffset());
}
const DexFile* GetDexFile() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -162,7 +154,8 @@ class MANAGED DexCache FINAL : public Object {
private:
HeapReference<Object> dex_;
HeapReference<String> location_;
- HeapReference<ObjectArray<ArtField>> resolved_fields_;
+ // Either an int array or long array (64 bit).
+ HeapReference<Object> resolved_fields_;
HeapReference<ObjectArray<ArtMethod>> resolved_methods_;
HeapReference<ObjectArray<Class>> resolved_types_;
HeapReference<ObjectArray<String>> strings_;
diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc
index 53e5534b11..1d6846b6c4 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -47,7 +47,7 @@ TEST_F(DexCacheTest, Open) {
EXPECT_LE(0, dex_cache->GetStrings()->GetLength());
EXPECT_LE(0, dex_cache->GetResolvedTypes()->GetLength());
EXPECT_LE(0, dex_cache->GetResolvedMethods()->GetLength());
- EXPECT_LE(0, dex_cache->GetResolvedFields()->GetLength());
+ EXPECT_LE(0u, dex_cache->NumResolvedFields());
EXPECT_EQ(java_lang_dex_file_->NumStringIds(),
static_cast<uint32_t>(dex_cache->GetStrings()->GetLength()));
@@ -55,8 +55,7 @@ TEST_F(DexCacheTest, Open) {
static_cast<uint32_t>(dex_cache->GetResolvedTypes()->GetLength()));
EXPECT_EQ(java_lang_dex_file_->NumMethodIds(),
static_cast<uint32_t>(dex_cache->GetResolvedMethods()->GetLength()));
- EXPECT_EQ(java_lang_dex_file_->NumFieldIds(),
- static_cast<uint32_t>(dex_cache->GetResolvedFields()->GetLength()));
+ EXPECT_EQ(java_lang_dex_file_->NumFieldIds(), dex_cache->NumResolvedFields());
}
} // namespace mirror
diff --git a/runtime/mirror/field-inl.h b/runtime/mirror/field-inl.h
index 24ebc481a7..7db181112a 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -27,9 +27,8 @@ namespace art {
namespace mirror {
template <bool kTransactionActive>
-inline mirror::Field* Field::CreateFromArtField(Thread* self, mirror::ArtField* field,
+inline mirror::Field* Field::CreateFromArtField(Thread* self, ArtField* field,
bool force_resolve) {
- CHECK(!kMovingFields);
// Try to resolve type before allocating since this is a thread suspension point.
mirror::Class* type = field->GetType<true>();
@@ -57,13 +56,13 @@ inline mirror::Field* Field::CreateFromArtField(Thread* self, mirror::ArtField*
return nullptr;
}
auto dex_field_index = field->GetDexFieldIndex();
- auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index);
+ auto* resolved_field = field->GetDexCache()->GetResolvedField(dex_field_index, sizeof(void*));
if (resolved_field != nullptr) {
DCHECK_EQ(resolved_field, field);
} else {
// We rely on the field being resolved so that we can back to the ArtField
// (i.e. FromReflectedMethod).
- field->GetDexCache()->SetResolvedField(dex_field_index, field);
+ field->GetDexCache()->SetResolvedField(dex_field_index, field, sizeof(void*));
}
ret->SetType<kTransactionActive>(type);
ret->SetDeclaringClass<kTransactionActive>(field->GetDeclaringClass());
diff --git a/runtime/mirror/field.cc b/runtime/mirror/field.cc
index 82cc26e9fe..70311bb889 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -55,7 +55,7 @@ void Field::VisitRoots(RootVisitor* visitor) {
ArtField* Field::GetArtField() {
mirror::DexCache* const dex_cache = GetDeclaringClass()->GetDexCache();
- mirror::ArtField* const art_field = dex_cache->GetResolvedField(GetDexFieldIndex());
+ ArtField* const art_field = dex_cache->GetResolvedField(GetDexFieldIndex(), sizeof(void*));
CHECK(art_field != nullptr);
return art_field;
}
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index cea06f5af8..9988f84a72 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -25,11 +25,11 @@
namespace art {
+class ArtField;
struct FieldOffsets;
namespace mirror {
-class ArtField;
class Class;
class String;
@@ -93,10 +93,10 @@ class MANAGED Field : public AccessibleObject {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Slow, try to use only for PrettyField and such.
- mirror::ArtField* GetArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* GetArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template <bool kTransactionActive = false>
- static mirror::Field* CreateFromArtField(Thread* self, mirror::ArtField* field,
+ static mirror::Field* CreateFromArtField(Thread* self, ArtField* field,
bool force_resolve)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index d6901634b7..af0e85603b 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -225,18 +225,6 @@ inline bool Object::IsArrayInstance() {
}
template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
-inline bool Object::IsArtField() {
- return GetClass<kVerifyFlags, kReadBarrierOption>()->
- template IsArtFieldClass<kReadBarrierOption>();
-}
-
-template<VerifyObjectFlags kVerifyFlags>
-inline ArtField* Object::AsArtField() {
- DCHECK(IsArtField<kVerifyFlags>());
- return down_cast<ArtField*>(this);
-}
-
-template<VerifyObjectFlags kVerifyFlags, ReadBarrierOption kReadBarrierOption>
inline bool Object::IsArtMethod() {
return GetClass<kVerifyFlags, kReadBarrierOption>()->
template IsArtMethodClass<kReadBarrierOption>();
@@ -318,8 +306,8 @@ inline ShortArray* Object::AsShortSizedArray() {
template<VerifyObjectFlags kVerifyFlags>
inline IntArray* Object::AsIntArray() {
constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
- DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
- DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
+ CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
+ CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveInt() ||
GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveFloat());
return down_cast<IntArray*>(this);
}
@@ -327,8 +315,8 @@ inline IntArray* Object::AsIntArray() {
template<VerifyObjectFlags kVerifyFlags>
inline LongArray* Object::AsLongArray() {
constexpr auto kNewFlags = static_cast<VerifyObjectFlags>(kVerifyFlags & ~kVerifyThis);
- DCHECK(GetClass<kVerifyFlags>()->IsArrayClass());
- DCHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
+ CHECK(GetClass<kVerifyFlags>()->IsArrayClass());
+ CHECK(GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveLong() ||
GetClass<kNewFlags>()->template GetComponentType<kNewFlags>()->IsPrimitiveDouble());
return down_cast<LongArray*>(this);
}
@@ -403,7 +391,6 @@ inline size_t Object::SizeOf() {
}
DCHECK_GE(result, sizeof(Object))
<< " class=" << PrettyTypeOf(GetClass<kNewFlags, kReadBarrierOption>());
- DCHECK(!(IsArtField<kNewFlags, kReadBarrierOption>()) || result == sizeof(ArtField));
return result;
}
diff --git a/runtime/mirror/object.cc b/runtime/mirror/object.cc
index 57ac46fec6..04d0cd874a 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -204,22 +204,19 @@ void Object::CheckFieldAssignmentImpl(MemberOffset field_offset, Object* new_val
return;
}
for (Class* cur = c; cur != NULL; cur = cur->GetSuperClass()) {
- ObjectArray<ArtField>* fields = cur->GetIFields();
- if (fields != NULL) {
- size_t num_ifields = fields->GetLength();
- for (size_t i = 0; i < num_ifields; ++i) {
- StackHandleScope<1> hs(Thread::Current());
- Handle<Object> h_object(hs.NewHandle(new_value));
- ArtField* field = fields->Get(i);
- if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
- CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
- // TODO: resolve the field type for moving GC.
- mirror::Class* field_type = field->GetType<!kMovingCollector>();
- if (field_type != nullptr) {
- CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
- }
- return;
+ ArtField* fields = cur->GetIFields();
+ for (size_t i = 0, count = cur->NumInstanceFields(); i < count; ++i) {
+ StackHandleScope<1> hs(Thread::Current());
+ Handle<Object> h_object(hs.NewHandle(new_value));
+ ArtField* field = &fields[i];
+ if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
+ CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
+ // TODO: resolve the field type for moving GC.
+ mirror::Class* field_type = field->GetType<!kMovingCollector>();
+ if (field_type != nullptr) {
+ CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
}
+ return;
}
}
}
@@ -228,20 +225,17 @@ void Object::CheckFieldAssignmentImpl(MemberOffset field_offset, Object* new_val
return;
}
if (IsClass()) {
- ObjectArray<ArtField>* fields = AsClass()->GetSFields();
- if (fields != NULL) {
- size_t num_sfields = fields->GetLength();
- for (size_t i = 0; i < num_sfields; ++i) {
- ArtField* field = fields->Get(i);
- if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
- CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
- // TODO: resolve the field type for moving GC.
- mirror::Class* field_type = field->GetType<!kMovingCollector>();
- if (field_type != nullptr) {
- CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
- }
- return;
+ ArtField* fields = AsClass()->GetSFields();
+ for (size_t i = 0, count = AsClass()->NumStaticFields(); i < count; ++i) {
+ ArtField* field = &fields[i];
+ if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
+ CHECK_NE(field->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
+ // TODO: resolve the field type for moving GC.
+ mirror::Class* field_type = field->GetType<!kMovingCollector>();
+ if (field_type != nullptr) {
+ CHECK(field_type->IsAssignableFrom(new_value->GetClass()));
}
+ return;
}
}
}
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index cfc8549751..bfd5d4d775 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -24,6 +24,7 @@
namespace art {
+class ArtField;
class ImageWriter;
class LockWord;
class Monitor;
@@ -33,7 +34,6 @@ class VoidFunctor;
namespace mirror {
-class ArtField;
class ArtMethod;
class Array;
class Class;
@@ -191,12 +191,6 @@ class MANAGED LOCKABLE Object {
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
ArtMethod* AsArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags,
- ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
- bool IsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- ArtField* AsArtField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
bool IsReferenceInstance() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
diff --git a/runtime/mirror/object_array-inl.h b/runtime/mirror/object_array-inl.h
index 80d51359a6..30bc1cd66e 100644
--- a/runtime/mirror/object_array-inl.h
+++ b/runtime/mirror/object_array-inl.h
@@ -22,7 +22,6 @@
#include "array-inl.h"
#include "base/stringprintf.h"
#include "gc/heap.h"
-#include "mirror/art_field.h"
#include "mirror/class.h"
#include "runtime.h"
#include "handle_scope-inl.h"
@@ -36,13 +35,13 @@ template<class T>
inline ObjectArray<T>* ObjectArray<T>::Alloc(Thread* self, Class* object_array_class,
int32_t length, gc::AllocatorType allocator_type) {
Array* array = Array::Alloc<true>(self, object_array_class, length,
- ComponentSizeShiftWidth<sizeof(HeapReference<Object>)>(),
+ ComponentSizeShiftWidth(sizeof(HeapReference<Object>)),
allocator_type);
if (UNLIKELY(array == nullptr)) {
return nullptr;
} else {
DCHECK_EQ(array->GetClass()->GetComponentSizeShift(),
- ComponentSizeShiftWidth<sizeof(HeapReference<Object>)>());
+ ComponentSizeShiftWidth(sizeof(HeapReference<Object>)));
return array->AsObjectArray<T>();
}
}
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 1ce298d848..747a00836a 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -722,14 +722,12 @@ TEST_F(ObjectTest, FindStaticField) {
"Ljava/util/Comparator;") == NULL);
// Right name and type.
- Handle<ArtField> f1(hs.NewHandle(
- c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;")));
- Handle<ArtField> f2(hs.NewHandle(
- mirror::Class::FindStaticField(soa.Self(), c, "CASE_INSENSITIVE_ORDER",
- "Ljava/util/Comparator;")));
- EXPECT_TRUE(f1.Get() != NULL);
- EXPECT_TRUE(f2.Get() != NULL);
- EXPECT_EQ(f1.Get(), f2.Get());
+ ArtField* f1 = c->FindDeclaredStaticField("CASE_INSENSITIVE_ORDER", "Ljava/util/Comparator;");
+ ArtField* f2 = mirror::Class::FindStaticField(soa.Self(), c, "CASE_INSENSITIVE_ORDER",
+ "Ljava/util/Comparator;");
+ EXPECT_TRUE(f1 != NULL);
+ EXPECT_TRUE(f2 != NULL);
+ EXPECT_EQ(f1, f2);
// TODO: test static fields via superclasses.
// TODO: test static fields via interfaces.
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 760038a1dc..1a6adf8fc9 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -313,8 +313,8 @@ static void PreloadDexCachesResolveType(Thread* self, mirror::DexCache* dex_cach
static void PreloadDexCachesResolveField(Handle<mirror::DexCache> dex_cache, uint32_t field_idx,
bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = dex_cache->GetResolvedField(field_idx);
- if (field != NULL) {
+ ArtField* field = dex_cache->GetResolvedField(field_idx, sizeof(void*));
+ if (field != nullptr) {
return;
}
const DexFile* dex_file = dex_cache->GetDexFile();
@@ -334,7 +334,7 @@ static void PreloadDexCachesResolveField(Handle<mirror::DexCache> dex_cache, uin
return;
}
// LOG(INFO) << "VMRuntime.preloadDexCaches resolved field " << PrettyField(field);
- dex_cache->SetResolvedField(field_idx, field);
+ dex_cache->SetResolvedField(field_idx, field, sizeof(void*));
}
// Based on ClassLinker::ResolveMethod.
@@ -437,7 +437,7 @@ static void PreloadDexCachesStatsFilled(DexCacheStats* filled)
}
}
for (size_t j = 0; j < dex_cache->NumResolvedFields(); j++) {
- mirror::ArtField* field = dex_cache->GetResolvedField(j);
+ ArtField* field = linker->GetResolvedField(j, dex_cache);
if (field != NULL) {
filled->num_fields++;
}
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index b657aec30d..5ad18f87ed 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -16,12 +16,12 @@
#include "java_lang_Class.h"
+#include "art_field-inl.h"
#include "class_linker.h"
#include "common_throws.h"
#include "dex_file-inl.h"
#include "jni_internal.h"
#include "nth_caller_visitor.h"
-#include "mirror/art_field-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mirror/field-inl.h"
@@ -119,33 +119,33 @@ static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) {
static mirror::ObjectArray<mirror::Field>* GetDeclaredFields(
Thread* self, mirror::Class* klass, bool public_only, bool force_resolve)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- StackHandleScope<3> hs(self);
- auto h_ifields = hs.NewHandle(klass->GetIFields());
- auto h_sfields = hs.NewHandle(klass->GetSFields());
- const int32_t num_ifields = h_ifields.Get() != nullptr ? h_ifields->GetLength() : 0;
- const int32_t num_sfields = h_sfields.Get() != nullptr ? h_sfields->GetLength() : 0;
- int32_t array_size = num_ifields + num_sfields;
+ StackHandleScope<1> hs(self);
+ auto* ifields = klass->GetIFields();
+ auto* sfields = klass->GetSFields();
+ const auto num_ifields = klass->NumInstanceFields();
+ const auto num_sfields = klass->NumStaticFields();
+ size_t array_size = num_ifields + num_sfields;
if (public_only) {
// Lets go subtract all the non public fields.
- for (int32_t i = 0; i < num_ifields; ++i) {
- if (!h_ifields->GetWithoutChecks(i)->IsPublic()) {
+ for (size_t i = 0; i < num_ifields; ++i) {
+ if (!ifields[i].IsPublic()) {
--array_size;
}
}
- for (int32_t i = 0; i < num_sfields; ++i) {
- if (!h_sfields->GetWithoutChecks(i)->IsPublic()) {
+ for (size_t i = 0; i < num_sfields; ++i) {
+ if (!sfields[i].IsPublic()) {
--array_size;
}
}
}
- int32_t array_idx = 0;
+ size_t array_idx = 0;
auto object_array = hs.NewHandle(mirror::ObjectArray<mirror::Field>::Alloc(
self, mirror::Field::ArrayClass(), array_size));
if (object_array.Get() == nullptr) {
return nullptr;
}
- for (int32_t i = 0; i < num_ifields; ++i) {
- auto* art_field = h_ifields->GetWithoutChecks(i);
+ for (size_t i = 0; i < num_ifields; ++i) {
+ auto* art_field = &ifields[i];
if (!public_only || art_field->IsPublic()) {
auto* field = mirror::Field::CreateFromArtField(self, art_field, force_resolve);
if (field == nullptr) {
@@ -158,8 +158,8 @@ static mirror::ObjectArray<mirror::Field>* GetDeclaredFields(
object_array->SetWithoutChecks<false>(array_idx++, field);
}
}
- for (int32_t i = 0; i < num_sfields; ++i) {
- auto* art_field = h_sfields->GetWithoutChecks(i);
+ for (size_t i = 0; i < num_sfields; ++i) {
+ auto* art_field = &sfields[i];
if (!public_only || art_field->IsPublic()) {
auto* field = mirror::Field::CreateFromArtField(self, art_field, force_resolve);
if (field == nullptr) {
@@ -197,17 +197,16 @@ static jobjectArray Class_getPublicDeclaredFields(JNIEnv* env, jobject javaThis)
// Performs a binary search through an array of fields, TODO: Is this fast enough if we don't use
// the dex cache for lookups? I think CompareModifiedUtf8ToUtf16AsCodePointValues should be fairly
// fast.
-ALWAYS_INLINE static inline mirror::ArtField* FindFieldByName(
- Thread* self ATTRIBUTE_UNUSED, mirror::String* name,
- mirror::ObjectArray<mirror::ArtField>* fields)
+ALWAYS_INLINE static inline ArtField* FindFieldByName(
+ Thread* self ATTRIBUTE_UNUSED, mirror::String* name, ArtField* fields, size_t num_fields)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- uint32_t low = 0;
- uint32_t high = fields->GetLength();
+ size_t low = 0;
+ size_t high = num_fields;
const uint16_t* const data = name->GetCharArray()->GetData() + name->GetOffset();
const size_t length = name->GetLength();
while (low < high) {
auto mid = (low + high) / 2;
- mirror::ArtField* const field = fields->GetWithoutChecks(mid);
+ ArtField* const field = &fields[mid];
int result = CompareModifiedUtf8ToUtf16AsCodePointValues(field->GetName(), data, length);
// Alternate approach, only a few % faster at the cost of more allocations.
// int result = field->GetStringName(self, true)->CompareTo(name);
@@ -220,8 +219,8 @@ ALWAYS_INLINE static inline mirror::ArtField* FindFieldByName(
}
}
if (kIsDebugBuild) {
- for (int32_t i = 0; i < fields->GetLength(); ++i) {
- CHECK_NE(fields->GetWithoutChecks(i)->GetName(), name->ToModifiedUtf8());
+ for (size_t i = 0; i < num_fields; ++i) {
+ CHECK_NE(fields[i].GetName(), name->ToModifiedUtf8());
}
}
return nullptr;
@@ -231,18 +230,14 @@ ALWAYS_INLINE static inline mirror::Field* GetDeclaredField(
Thread* self, mirror::Class* c, mirror::String* name)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
auto* instance_fields = c->GetIFields();
- if (instance_fields != nullptr) {
- auto* art_field = FindFieldByName(self, name, instance_fields);
- if (art_field != nullptr) {
- return mirror::Field::CreateFromArtField(self, art_field, true);
- }
+ auto* art_field = FindFieldByName(self, name, instance_fields, c->NumInstanceFields());
+ if (art_field != nullptr) {
+ return mirror::Field::CreateFromArtField(self, art_field, true);
}
auto* static_fields = c->GetSFields();
- if (static_fields != nullptr) {
- auto* art_field = FindFieldByName(self, name, static_fields);
- if (art_field != nullptr) {
- return mirror::Field::CreateFromArtField(self, art_field, true);
- }
+ art_field = FindFieldByName(self, name, static_fields, c->NumStaticFields());
+ if (art_field != nullptr) {
+ return mirror::Field::CreateFromArtField(self, art_field, true);
}
return nullptr;
}
diff --git a/runtime/native/java_lang_reflect_Array.cc b/runtime/native/java_lang_reflect_Array.cc
index 1ffcbdfd5e..681b261dcc 100644
--- a/runtime/native/java_lang_reflect_Array.cc
+++ b/runtime/native/java_lang_reflect_Array.cc
@@ -63,7 +63,7 @@ static jobject Array_createObjectArray(JNIEnv* env, jclass, jclass javaElementCl
DCHECK(array_class->IsObjectArrayClass());
mirror::Array* new_array = mirror::Array::Alloc<true>(
soa.Self(), array_class, length,
- ComponentSizeShiftWidth<sizeof(mirror::HeapReference<mirror::Object>)>(),
+ ComponentSizeShiftWidth(sizeof(mirror::HeapReference<mirror::Object>)),
runtime->GetHeap()->GetCurrentAllocator());
return soa.AddLocalReference<jobject>(new_array);
}
diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc
index 765f54893a..5e1a4c59f7 100644
--- a/runtime/native/java_lang_reflect_Constructor.cc
+++ b/runtime/native/java_lang_reflect_Constructor.cc
@@ -57,8 +57,6 @@ static jobject Constructor_newInstance(JNIEnv* env, jobject javaMethod, jobjectA
bool movable = true;
if (!kMovingMethods && c->IsArtMethodClass()) {
movable = false;
- } else if (!kMovingFields && c->IsArtFieldClass()) {
- movable = false;
} else if (!kMovingClasses && c->IsClassClass()) {
movable = false;
}
diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc
index d2362a210e..37c635377c 100644
--- a/runtime/oat_file_assistant_test.cc
+++ b/runtime/oat_file_assistant_test.cc
@@ -25,11 +25,11 @@
#include <backtrace/BacktraceMap.h>
#include <gtest/gtest.h>
+#include "art_field-inl.h"
#include "class_linker.h"
#include "common_runtime_test.h"
#include "compiler_callbacks.h"
#include "mem_map.h"
-#include "mirror/art_field-inl.h"
#include "os.h"
#include "scoped_thread_state_change.h"
#include "thread-inl.h"
@@ -959,25 +959,25 @@ TEST_F(OatFileAssistantTest, DexOptStatusValues) {
ASSERT_FALSE(dexfile.Get() == nullptr);
linker->EnsureInitialized(soa.Self(), dexfile, true, true);
- mirror::ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
+ ArtField* no_dexopt_needed = mirror::Class::FindStaticField(
soa.Self(), dexfile, "NO_DEXOPT_NEEDED", "I");
ASSERT_FALSE(no_dexopt_needed == nullptr);
EXPECT_EQ(no_dexopt_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(OatFileAssistant::kNoDexOptNeeded, no_dexopt_needed->GetInt(dexfile.Get()));
- mirror::ArtField* dex2oat_needed = mirror::Class::FindStaticField(
+ ArtField* dex2oat_needed = mirror::Class::FindStaticField(
soa.Self(), dexfile, "DEX2OAT_NEEDED", "I");
ASSERT_FALSE(dex2oat_needed == nullptr);
EXPECT_EQ(dex2oat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(OatFileAssistant::kDex2OatNeeded, dex2oat_needed->GetInt(dexfile.Get()));
- mirror::ArtField* patchoat_needed = mirror::Class::FindStaticField(
+ ArtField* patchoat_needed = mirror::Class::FindStaticField(
soa.Self(), dexfile, "PATCHOAT_NEEDED", "I");
ASSERT_FALSE(patchoat_needed == nullptr);
EXPECT_EQ(patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
EXPECT_EQ(OatFileAssistant::kPatchOatNeeded, patchoat_needed->GetInt(dexfile.Get()));
- mirror::ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
+ ArtField* self_patchoat_needed = mirror::Class::FindStaticField(
soa.Self(), dexfile, "SELF_PATCHOAT_NEEDED", "I");
ASSERT_FALSE(self_patchoat_needed == nullptr);
EXPECT_EQ(self_patchoat_needed->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
diff --git a/runtime/primitive.h b/runtime/primitive.h
index 32bfdaf089..38184871af 100644
--- a/runtime/primitive.h
+++ b/runtime/primitive.h
@@ -27,21 +27,11 @@ namespace art {
static constexpr size_t kObjectReferenceSize = 4;
-template<size_t kComponentSize>
-size_t ComponentSizeShiftWidth() {
- switch (kComponentSize) {
- case 1:
- return 0U;
- case 2:
- return 1U;
- case 4:
- return 2U;
- case 8:
- return 3U;
- default:
- LOG(FATAL) << "Unexpected component size : " << kComponentSize;
- return 0U;
- }
+constexpr size_t ComponentSizeShiftWidth(size_t component_size) {
+ return component_size == 1u ? 0u :
+ component_size == 2u ? 1u :
+ component_size == 4u ? 2u :
+ component_size == 8u ? 3u : 0u;
}
class Primitive {
@@ -95,7 +85,7 @@ class Primitive {
case kPrimFloat: return 2;
case kPrimLong:
case kPrimDouble: return 3;
- case kPrimNot: return ComponentSizeShiftWidth<kObjectReferenceSize>();
+ case kPrimNot: return ComponentSizeShiftWidth(kObjectReferenceSize);
default:
LOG(FATAL) << "Invalid type " << static_cast<int>(type);
return 0;
diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc
index cb97049c5b..a3156b4d09 100644
--- a/runtime/proxy_test.cc
+++ b/runtime/proxy_test.cc
@@ -17,8 +17,8 @@
#include <jni.h>
#include <vector>
+#include "art_field-inl.h"
#include "common_compiler_test.h"
-#include "mirror/art_field-inl.h"
#include "scoped_thread_state_change.h"
namespace art {
@@ -165,14 +165,12 @@ TEST_F(ProxyTest, ProxyFieldHelper) {
ASSERT_TRUE(proxyClass->IsProxyClass());
ASSERT_TRUE(proxyClass->IsInitialized());
- Handle<mirror::ObjectArray<mirror::ArtField>> instance_fields(
- hs.NewHandle(proxyClass->GetIFields()));
- EXPECT_TRUE(instance_fields.Get() == nullptr);
+ ArtField* instance_fields = proxyClass->GetIFields();
+ EXPECT_TRUE(instance_fields == nullptr);
- Handle<mirror::ObjectArray<mirror::ArtField>> static_fields(
- hs.NewHandle(proxyClass->GetSFields()));
- ASSERT_TRUE(static_fields.Get() != nullptr);
- ASSERT_EQ(2, static_fields->GetLength());
+ ArtField* static_fields = proxyClass->GetSFields();
+ ASSERT_TRUE(static_fields != nullptr);
+ ASSERT_EQ(2u, proxyClass->NumStaticFields());
Handle<mirror::Class> interfacesFieldClass(
hs.NewHandle(class_linker_->FindSystemClass(soa.Self(), "[Ljava/lang/Class;")));
@@ -182,21 +180,21 @@ TEST_F(ProxyTest, ProxyFieldHelper) {
ASSERT_TRUE(throwsFieldClass.Get() != nullptr);
// Test "Class[] interfaces" field.
- MutableHandle<mirror::ArtField> fhandle = hs.NewHandle(static_fields->Get(0));
- EXPECT_EQ("interfaces", std::string(fhandle->GetName()));
- EXPECT_EQ("[Ljava/lang/Class;", std::string(fhandle->GetTypeDescriptor()));
- EXPECT_EQ(interfacesFieldClass.Get(), fhandle->GetType<true>());
+ ArtField* field = &static_fields[0];
+ EXPECT_STREQ("interfaces", field->GetName());
+ EXPECT_STREQ("[Ljava/lang/Class;", field->GetTypeDescriptor());
+ EXPECT_EQ(interfacesFieldClass.Get(), field->GetType<true>());
std::string temp;
- EXPECT_EQ("L$Proxy1234;", std::string(fhandle->GetDeclaringClass()->GetDescriptor(&temp)));
- EXPECT_FALSE(fhandle->IsPrimitiveType());
+ EXPECT_STREQ("L$Proxy1234;", field->GetDeclaringClass()->GetDescriptor(&temp));
+ EXPECT_FALSE(field->IsPrimitiveType());
// Test "Class[][] throws" field.
- fhandle.Assign(static_fields->Get(1));
- EXPECT_EQ("throws", std::string(fhandle->GetName()));
- EXPECT_EQ("[[Ljava/lang/Class;", std::string(fhandle->GetTypeDescriptor()));
- EXPECT_EQ(throwsFieldClass.Get(), fhandle->GetType<true>());
- EXPECT_EQ("L$Proxy1234;", std::string(fhandle->GetDeclaringClass()->GetDescriptor(&temp)));
- EXPECT_FALSE(fhandle->IsPrimitiveType());
+ field = &static_fields[1];
+ EXPECT_STREQ("throws", field->GetName());
+ EXPECT_STREQ("[[Ljava/lang/Class;", field->GetTypeDescriptor());
+ EXPECT_EQ(throwsFieldClass.Get(), field->GetType<true>());
+ EXPECT_STREQ("L$Proxy1234;", field->GetDeclaringClass()->GetDescriptor(&temp));
+ EXPECT_FALSE(field->IsPrimitiveType());
}
} // namespace art
diff --git a/runtime/quick/inline_method_analyser.cc b/runtime/quick/inline_method_analyser.cc
index 44e28443dd..efaa0ac570 100644
--- a/runtime/quick/inline_method_analyser.cc
+++ b/runtime/quick/inline_method_analyser.cc
@@ -15,18 +15,14 @@
*/
#include "inline_method_analyser.h"
+
+#include "art_field-inl.h"
#include "dex_file-inl.h"
#include "dex_instruction.h"
#include "dex_instruction-inl.h"
-#include "mirror/art_field.h"
-#include "mirror/art_field-inl.h"
-#include "mirror/art_method.h"
#include "mirror/art_method-inl.h"
-#include "mirror/class.h"
#include "mirror/class-inl.h"
-#include "mirror/dex_cache.h"
#include "mirror/dex_cache-inl.h"
-#include "verifier/method_verifier.h"
#include "verifier/method_verifier-inl.h"
/*
@@ -331,7 +327,7 @@ bool InlineMethodAnalyser::ComputeSpecialAccessorInfo(uint32_t field_idx, bool i
mirror::DexCache* dex_cache = verifier->GetDexCache();
uint32_t method_idx = verifier->GetMethodReference().dex_method_index;
mirror::ArtMethod* method = dex_cache->GetResolvedMethod(method_idx);
- mirror::ArtField* field = dex_cache->GetResolvedField(field_idx);
+ ArtField* field = Runtime::Current()->GetClassLinker()->GetResolvedField(field_idx, dex_cache);
if (method == nullptr || field == nullptr || field->IsStatic()) {
return false;
}
diff --git a/runtime/read_barrier.h b/runtime/read_barrier.h
index 471b37ceb1..52d83a24f6 100644
--- a/runtime/read_barrier.h
+++ b/runtime/read_barrier.h
@@ -30,7 +30,6 @@
namespace art {
namespace mirror {
- class ArtField;
class ArtMethod;
class Object;
template<typename MirrorType> class HeapReference;
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index 4e94de4139..3e1315c73e 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -16,16 +16,15 @@
#include "reflection-inl.h"
+#include "art_field-inl.h"
#include "class_linker.h"
#include "common_throws.h"
#include "dex_file-inl.h"
#include "entrypoints/entrypoint_utils.h"
#include "jni_internal.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/object_array-inl.h"
-#include "mirror/object_array.h"
#include "nth_caller_visitor.h"
#include "scoped_thread_state_change.h"
#include "stack.h"
@@ -238,13 +237,13 @@ class ArgArray {
#define DO_FIRST_ARG(match_descriptor, get_fn, append) { \
if (LIKELY(arg != nullptr && arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
- mirror::ArtField* primitive_field = arg->GetClass()->GetIFields()->Get(0); \
+ ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
append(primitive_field-> get_fn(arg));
#define DO_ARG(match_descriptor, get_fn, append) \
} else if (LIKELY(arg != nullptr && \
arg->GetClass<>()->DescriptorEquals(match_descriptor))) { \
- mirror::ArtField* primitive_field = arg->GetClass()->GetIFields()->Get(0); \
+ ArtField* primitive_field = arg->GetClass()->GetInstanceField(0); \
append(primitive_field-> get_fn(arg));
#define DO_FAIL(expected) \
@@ -692,7 +691,7 @@ mirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) {
return result.GetL();
}
-static std::string UnboxingFailureKind(mirror::ArtField* f)
+static std::string UnboxingFailureKind(ArtField* f)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (f != nullptr) {
return "field " + PrettyField(f, false);
@@ -701,7 +700,7 @@ static std::string UnboxingFailureKind(mirror::ArtField* f)
}
static bool UnboxPrimitive(mirror::Object* o,
- mirror::Class* dst_class, mirror::ArtField* f,
+ mirror::Class* dst_class, ArtField* f,
JValue* unboxed_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
bool unbox_for_result = (f == nullptr);
@@ -742,8 +741,8 @@ static bool UnboxPrimitive(mirror::Object* o,
JValue boxed_value;
mirror::Class* klass = o->GetClass();
mirror::Class* src_class = nullptr;
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- mirror::ArtField* primitive_field = o->GetClass()->GetIFields()->Get(0);
+ ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
+ ArtField* primitive_field = &klass->GetIFields()[0];
if (klass->DescriptorEquals("Ljava/lang/Boolean;")) {
src_class = class_linker->FindPrimitiveClass('Z');
boxed_value.SetZ(primitive_field->GetBoolean(o));
@@ -782,7 +781,7 @@ static bool UnboxPrimitive(mirror::Object* o,
boxed_value, unboxed_value);
}
-bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, mirror::ArtField* f,
+bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, ArtField* f,
JValue* unboxed_value) {
DCHECK(f != nullptr);
return UnboxPrimitive(o, dst_class, f, unboxed_value);
diff --git a/runtime/reflection.h b/runtime/reflection.h
index ff970e5507..c2d406a2db 100644
--- a/runtime/reflection.h
+++ b/runtime/reflection.h
@@ -23,18 +23,18 @@
namespace art {
namespace mirror {
- class ArtField;
class ArtMethod;
class Class;
class Object;
} // namespace mirror
+class ArtField;
union JValue;
class ScopedObjectAccessAlreadyRunnable;
class ShadowFrame;
mirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, mirror::ArtField* f,
+bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, ArtField* f,
JValue* unboxed_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool UnboxPrimitiveForResult(mirror::Object* o, mirror::Class* dst_class, JValue* unboxed_value)
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 1cd0a96a28..66d38ce770 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -48,6 +48,7 @@
#include "arch/x86/registers_x86.h"
#include "arch/x86_64/quick_method_frame_info_x86_64.h"
#include "arch/x86_64/registers_x86_64.h"
+#include "art_field-inl.h"
#include "asm_support.h"
#include "atomic.h"
#include "base/arena_allocator.h"
@@ -70,8 +71,8 @@
#include "interpreter/interpreter.h"
#include "jit/jit.h"
#include "jni_internal.h"
+#include "linear_alloc.h"
#include "mirror/array.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
@@ -257,7 +258,9 @@ Runtime::~Runtime() {
VLOG(jit) << "Deleting jit";
jit_.reset(nullptr);
}
+ linear_alloc_.reset();
arena_pool_.reset();
+ low_4gb_arena_pool_.reset();
// Shutdown the fault manager if it was initialized.
fault_manager.Shutdown();
@@ -441,7 +444,7 @@ static jobject CreateSystemClassLoader(Runtime* runtime) {
hs.NewHandle(soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread)));
CHECK(cl->EnsureInitialized(soa.Self(), thread_class, true, true));
- mirror::ArtField* contextClassLoader =
+ ArtField* contextClassLoader =
thread_class->FindDeclaredInstanceField("contextClassLoader", "Ljava/lang/ClassLoader;");
CHECK(contextClassLoader != NULL);
@@ -862,7 +865,14 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized)
// Use MemMap arena pool for jit, malloc otherwise. Malloc arenas are faster to allocate but
// can't be trimmed as easily.
const bool use_malloc = !use_jit;
- arena_pool_.reset(new ArenaPool(use_malloc));
+ arena_pool_.reset(new ArenaPool(use_malloc, false));
+ if (IsCompiler() && Is64BitInstructionSet(kRuntimeISA)) {
+ // 4gb, no malloc. Explanation in header.
+ low_4gb_arena_pool_.reset(new ArenaPool(false, true));
+ linear_alloc_.reset(new LinearAlloc(low_4gb_arena_pool_.get()));
+ } else {
+ linear_alloc_.reset(new LinearAlloc(arena_pool_.get()));
+ }
BlockSignals();
InitPlatformSignalHandlers();
@@ -1294,7 +1304,6 @@ mirror::Throwable* Runtime::GetPreAllocatedNoClassDefFoundError() {
void Runtime::VisitConstantRoots(RootVisitor* visitor) {
// Visit the classes held as static in mirror classes, these can be visited concurrently and only
// need to be visited once per GC since they never change.
- mirror::ArtField::VisitRoots(visitor);
mirror::ArtMethod::VisitRoots(visitor);
mirror::Class::VisitRoots(visitor);
mirror::Reference::VisitRoots(visitor);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index baa4d18da8..d95640dea6 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -42,6 +42,7 @@ namespace art {
class ArenaPool;
class CompilerCallbacks;
+class LinearAlloc;
namespace gc {
class Heap;
@@ -549,6 +550,9 @@ class Runtime {
const ArenaPool* GetArenaPool() const {
return arena_pool_.get();
}
+ LinearAlloc* GetLinearAlloc() {
+ return linear_alloc_.get();
+ }
jit::JitOptions* GetJITOptions() {
return jit_options_.get();
@@ -618,6 +622,13 @@ class Runtime {
gc::Heap* heap_;
std::unique_ptr<ArenaPool> arena_pool_;
+ // Special low 4gb pool for compiler linear alloc. We need ArtFields to be in low 4gb if we are
+ // compiling using a 32 bit image on a 64 bit compiler in case we resolve things in the image
+ // since the field arrays are int arrays in this case.
+ std::unique_ptr<ArenaPool> low_4gb_arena_pool_;
+
+ // Shared linear alloc for now.
+ std::unique_ptr<LinearAlloc> linear_alloc_;
// The number of spins that are done before thread suspension is used to forcibly inflate.
size_t max_spins_before_thin_lock_inflation_;
diff --git a/runtime/scoped_thread_state_change.h b/runtime/scoped_thread_state_change.h
index adf3480e2a..11b7df61f8 100644
--- a/runtime/scoped_thread_state_change.h
+++ b/runtime/scoped_thread_state_change.h
@@ -20,7 +20,7 @@
#include "base/casts.h"
#include "java_vm_ext.h"
#include "jni_env_ext-inl.h"
-#include "mirror/art_field.h"
+#include "art_field.h"
#include "read_barrier.h"
#include "thread-inl.h"
#include "verify_object.h"
@@ -148,20 +148,16 @@ class ScopedObjectAccessAlreadyRunnable {
return down_cast<T>(Self()->DecodeJObject(obj));
}
- mirror::ArtField* DecodeField(jfieldID fid) const
+ ArtField* DecodeField(jfieldID fid) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Locks::mutator_lock_->AssertSharedHeld(Self());
DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states.
- CHECK(!kMovingFields);
- mirror::ArtField* field = reinterpret_cast<mirror::ArtField*>(fid);
- return ReadBarrier::BarrierForRoot<mirror::ArtField, kWithReadBarrier>(&field);
+ return reinterpret_cast<ArtField*>(fid);
}
- jfieldID EncodeField(mirror::ArtField* field) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ jfieldID EncodeField(ArtField* field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Locks::mutator_lock_->AssertSharedHeld(Self());
DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states.
- CHECK(!kMovingFields);
return reinterpret_cast<jfieldID>(field);
}
diff --git a/runtime/thread.cc b/runtime/thread.cc
index af11f73d89..58b272bcb2 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -32,11 +32,11 @@
#include <sstream>
#include "arch/context.h"
+#include "art_field-inl.h"
#include "base/mutex.h"
#include "base/timing_logger.h"
#include "base/to_str.h"
#include "class_linker-inl.h"
-#include "class_linker.h"
#include "debugger.h"
#include "dex_file-inl.h"
#include "entrypoints/entrypoint_utils.h"
@@ -47,10 +47,8 @@
#include "gc/heap.h"
#include "gc/space/space.h"
#include "handle_scope-inl.h"
-#include "handle_scope.h"
#include "indirect_reference_table-inl.h"
#include "jni_internal.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class_loader.h"
#include "mirror/class-inl.h"
@@ -173,7 +171,7 @@ void* Thread::CreateCallback(void* arg) {
self->tlsPtr_.jpeer = nullptr;
self->SetThreadName(self->GetThreadName(soa)->ToModifiedUtf8().c_str());
- mirror::ArtField* priorityField = soa.DecodeField(WellKnownClasses::java_lang_Thread_priority);
+ ArtField* priorityField = soa.DecodeField(WellKnownClasses::java_lang_Thread_priority);
self->SetNativePriority(priorityField->GetInt(self->tlsPtr_.opeer));
Dbg::PostThreadStart(self);
@@ -190,7 +188,7 @@ void* Thread::CreateCallback(void* arg) {
Thread* Thread::FromManagedThread(const ScopedObjectAccessAlreadyRunnable& soa,
mirror::Object* thread_peer) {
- mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_nativePeer);
+ ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_nativePeer);
Thread* result = reinterpret_cast<Thread*>(static_cast<uintptr_t>(f->GetLong(thread_peer)));
// Sanity check that if we have a result it is either suspended or we hold the thread_list_lock_
// to stop it from going away.
@@ -589,7 +587,7 @@ void Thread::Dump(std::ostream& os) const {
}
mirror::String* Thread::GetThreadName(const ScopedObjectAccessAlreadyRunnable& soa) const {
- mirror::ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
+ ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
return (tlsPtr_.opeer != nullptr) ? reinterpret_cast<mirror::String*>(f->GetObject(tlsPtr_.opeer)) : nullptr;
}
@@ -794,7 +792,7 @@ void Thread::DumpState(std::ostream& os, const Thread* thread, pid_t tid) {
soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(thread->tlsPtr_.opeer);
if (thread_group != nullptr) {
- mirror::ArtField* group_name_field =
+ ArtField* group_name_field =
soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
mirror::String* group_name_string =
reinterpret_cast<mirror::String*>(group_name_field->GetObject(thread_group));
diff --git a/runtime/trace.cc b/runtime/trace.cc
index 5375dc0d3c..73268653f1 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -582,7 +582,7 @@ void Trace::DexPcMoved(Thread* thread, mirror::Object* this_object,
}
void Trace::FieldRead(Thread* thread, mirror::Object* this_object,
- mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field)
+ mirror::ArtMethod* method, uint32_t dex_pc, ArtField* field)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
UNUSED(thread, this_object, method, dex_pc, field);
// We're not recorded to listen to this kind of event, so complain.
@@ -590,7 +590,7 @@ void Trace::FieldRead(Thread* thread, mirror::Object* this_object,
}
void Trace::FieldWritten(Thread* thread, mirror::Object* this_object,
- mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field,
+ mirror::ArtMethod* method, uint32_t dex_pc, ArtField* field,
const JValue& field_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
UNUSED(thread, this_object, method, dex_pc, field, field_value);
diff --git a/runtime/trace.h b/runtime/trace.h
index 80f926f31c..d8bd428bf9 100644
--- a/runtime/trace.h
+++ b/runtime/trace.h
@@ -33,10 +33,10 @@
namespace art {
namespace mirror {
- class ArtField;
class ArtMethod;
} // namespace mirror
+class ArtField;
class Thread;
enum TracingMode {
@@ -99,10 +99,10 @@ class Trace FINAL : public instrumentation::InstrumentationListener {
mirror::ArtMethod* method, uint32_t new_dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
void FieldRead(Thread* thread, mirror::Object* this_object,
- mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field)
+ mirror::ArtMethod* method, uint32_t dex_pc, ArtField* field)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
void FieldWritten(Thread* thread, mirror::Object* this_object,
- mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field,
+ mirror::ArtMethod* method, uint32_t dex_pc, ArtField* field,
const JValue& field_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
void ExceptionCaught(Thread* thread, mirror::Throwable* exception_object)
diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc
index 24ecf6b096..9792eca757 100644
--- a/runtime/transaction_test.cc
+++ b/runtime/transaction_test.cc
@@ -16,9 +16,9 @@
#include "transaction.h"
+#include "art_field-inl.h"
#include "common_runtime_test.h"
#include "mirror/array-inl.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "scoped_thread_state_change.h"
@@ -181,47 +181,47 @@ TEST_F(TransactionTest, StaticFieldsTest) {
ASSERT_FALSE(soa.Self()->IsExceptionPending());
// Lookup fields.
- mirror::ArtField* booleanField = h_klass->FindDeclaredStaticField("booleanField", "Z");
+ ArtField* booleanField = h_klass->FindDeclaredStaticField("booleanField", "Z");
ASSERT_TRUE(booleanField != nullptr);
ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
ASSERT_EQ(booleanField->GetBoolean(h_klass.Get()), false);
- mirror::ArtField* byteField = h_klass->FindDeclaredStaticField("byteField", "B");
+ ArtField* byteField = h_klass->FindDeclaredStaticField("byteField", "B");
ASSERT_TRUE(byteField != nullptr);
ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
ASSERT_EQ(byteField->GetByte(h_klass.Get()), 0);
- mirror::ArtField* charField = h_klass->FindDeclaredStaticField("charField", "C");
+ ArtField* charField = h_klass->FindDeclaredStaticField("charField", "C");
ASSERT_TRUE(charField != nullptr);
ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
ASSERT_EQ(charField->GetChar(h_klass.Get()), 0u);
- mirror::ArtField* shortField = h_klass->FindDeclaredStaticField("shortField", "S");
+ ArtField* shortField = h_klass->FindDeclaredStaticField("shortField", "S");
ASSERT_TRUE(shortField != nullptr);
ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
ASSERT_EQ(shortField->GetShort(h_klass.Get()), 0);
- mirror::ArtField* intField = h_klass->FindDeclaredStaticField("intField", "I");
+ ArtField* intField = h_klass->FindDeclaredStaticField("intField", "I");
ASSERT_TRUE(intField != nullptr);
ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
ASSERT_EQ(intField->GetInt(h_klass.Get()), 0);
- mirror::ArtField* longField = h_klass->FindDeclaredStaticField("longField", "J");
+ ArtField* longField = h_klass->FindDeclaredStaticField("longField", "J");
ASSERT_TRUE(longField != nullptr);
ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
ASSERT_EQ(longField->GetLong(h_klass.Get()), static_cast<int64_t>(0));
- mirror::ArtField* floatField = h_klass->FindDeclaredStaticField("floatField", "F");
+ ArtField* floatField = h_klass->FindDeclaredStaticField("floatField", "F");
ASSERT_TRUE(floatField != nullptr);
ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
ASSERT_FLOAT_EQ(floatField->GetFloat(h_klass.Get()), static_cast<float>(0.0f));
- mirror::ArtField* doubleField = h_klass->FindDeclaredStaticField("doubleField", "D");
+ ArtField* doubleField = h_klass->FindDeclaredStaticField("doubleField", "D");
ASSERT_TRUE(doubleField != nullptr);
ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
ASSERT_DOUBLE_EQ(doubleField->GetDouble(h_klass.Get()), static_cast<double>(0.0));
- mirror::ArtField* objectField = h_klass->FindDeclaredStaticField("objectField",
+ ArtField* objectField = h_klass->FindDeclaredStaticField("objectField",
"Ljava/lang/Object;");
ASSERT_TRUE(objectField != nullptr);
ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
@@ -283,47 +283,47 @@ TEST_F(TransactionTest, InstanceFieldsTest) {
ASSERT_TRUE(h_instance.Get() != nullptr);
// Lookup fields.
- mirror::ArtField* booleanField = h_klass->FindDeclaredInstanceField("booleanField", "Z");
+ ArtField* booleanField = h_klass->FindDeclaredInstanceField("booleanField", "Z");
ASSERT_TRUE(booleanField != nullptr);
ASSERT_EQ(booleanField->GetTypeAsPrimitiveType(), Primitive::kPrimBoolean);
ASSERT_EQ(booleanField->GetBoolean(h_instance.Get()), false);
- mirror::ArtField* byteField = h_klass->FindDeclaredInstanceField("byteField", "B");
+ ArtField* byteField = h_klass->FindDeclaredInstanceField("byteField", "B");
ASSERT_TRUE(byteField != nullptr);
ASSERT_EQ(byteField->GetTypeAsPrimitiveType(), Primitive::kPrimByte);
ASSERT_EQ(byteField->GetByte(h_instance.Get()), 0);
- mirror::ArtField* charField = h_klass->FindDeclaredInstanceField("charField", "C");
+ ArtField* charField = h_klass->FindDeclaredInstanceField("charField", "C");
ASSERT_TRUE(charField != nullptr);
ASSERT_EQ(charField->GetTypeAsPrimitiveType(), Primitive::kPrimChar);
ASSERT_EQ(charField->GetChar(h_instance.Get()), 0u);
- mirror::ArtField* shortField = h_klass->FindDeclaredInstanceField("shortField", "S");
+ ArtField* shortField = h_klass->FindDeclaredInstanceField("shortField", "S");
ASSERT_TRUE(shortField != nullptr);
ASSERT_EQ(shortField->GetTypeAsPrimitiveType(), Primitive::kPrimShort);
ASSERT_EQ(shortField->GetShort(h_instance.Get()), 0);
- mirror::ArtField* intField = h_klass->FindDeclaredInstanceField("intField", "I");
+ ArtField* intField = h_klass->FindDeclaredInstanceField("intField", "I");
ASSERT_TRUE(intField != nullptr);
ASSERT_EQ(intField->GetTypeAsPrimitiveType(), Primitive::kPrimInt);
ASSERT_EQ(intField->GetInt(h_instance.Get()), 0);
- mirror::ArtField* longField = h_klass->FindDeclaredInstanceField("longField", "J");
+ ArtField* longField = h_klass->FindDeclaredInstanceField("longField", "J");
ASSERT_TRUE(longField != nullptr);
ASSERT_EQ(longField->GetTypeAsPrimitiveType(), Primitive::kPrimLong);
ASSERT_EQ(longField->GetLong(h_instance.Get()), static_cast<int64_t>(0));
- mirror::ArtField* floatField = h_klass->FindDeclaredInstanceField("floatField", "F");
+ ArtField* floatField = h_klass->FindDeclaredInstanceField("floatField", "F");
ASSERT_TRUE(floatField != nullptr);
ASSERT_EQ(floatField->GetTypeAsPrimitiveType(), Primitive::kPrimFloat);
ASSERT_FLOAT_EQ(floatField->GetFloat(h_instance.Get()), static_cast<float>(0.0f));
- mirror::ArtField* doubleField = h_klass->FindDeclaredInstanceField("doubleField", "D");
+ ArtField* doubleField = h_klass->FindDeclaredInstanceField("doubleField", "D");
ASSERT_TRUE(doubleField != nullptr);
ASSERT_EQ(doubleField->GetTypeAsPrimitiveType(), Primitive::kPrimDouble);
ASSERT_DOUBLE_EQ(doubleField->GetDouble(h_instance.Get()), static_cast<double>(0.0));
- mirror::ArtField* objectField = h_klass->FindDeclaredInstanceField("objectField",
+ ArtField* objectField = h_klass->FindDeclaredInstanceField("objectField",
"Ljava/lang/Object;");
ASSERT_TRUE(objectField != nullptr);
ASSERT_EQ(objectField->GetTypeAsPrimitiveType(), Primitive::kPrimNot);
@@ -381,63 +381,63 @@ TEST_F(TransactionTest, StaticArrayFieldsTest) {
ASSERT_FALSE(soa.Self()->IsExceptionPending());
// Lookup fields.
- mirror::ArtField* booleanArrayField = h_klass->FindDeclaredStaticField("booleanArrayField", "[Z");
+ ArtField* booleanArrayField = h_klass->FindDeclaredStaticField("booleanArrayField", "[Z");
ASSERT_TRUE(booleanArrayField != nullptr);
mirror::BooleanArray* booleanArray = booleanArrayField->GetObject(h_klass.Get())->AsBooleanArray();
ASSERT_TRUE(booleanArray != nullptr);
ASSERT_EQ(booleanArray->GetLength(), 1);
ASSERT_EQ(booleanArray->GetWithoutChecks(0), false);
- mirror::ArtField* byteArrayField = h_klass->FindDeclaredStaticField("byteArrayField", "[B");
+ ArtField* byteArrayField = h_klass->FindDeclaredStaticField("byteArrayField", "[B");
ASSERT_TRUE(byteArrayField != nullptr);
mirror::ByteArray* byteArray = byteArrayField->GetObject(h_klass.Get())->AsByteArray();
ASSERT_TRUE(byteArray != nullptr);
ASSERT_EQ(byteArray->GetLength(), 1);
ASSERT_EQ(byteArray->GetWithoutChecks(0), 0);
- mirror::ArtField* charArrayField = h_klass->FindDeclaredStaticField("charArrayField", "[C");
+ ArtField* charArrayField = h_klass->FindDeclaredStaticField("charArrayField", "[C");
ASSERT_TRUE(charArrayField != nullptr);
mirror::CharArray* charArray = charArrayField->GetObject(h_klass.Get())->AsCharArray();
ASSERT_TRUE(charArray != nullptr);
ASSERT_EQ(charArray->GetLength(), 1);
ASSERT_EQ(charArray->GetWithoutChecks(0), 0u);
- mirror::ArtField* shortArrayField = h_klass->FindDeclaredStaticField("shortArrayField", "[S");
+ ArtField* shortArrayField = h_klass->FindDeclaredStaticField("shortArrayField", "[S");
ASSERT_TRUE(shortArrayField != nullptr);
mirror::ShortArray* shortArray = shortArrayField->GetObject(h_klass.Get())->AsShortArray();
ASSERT_TRUE(shortArray != nullptr);
ASSERT_EQ(shortArray->GetLength(), 1);
ASSERT_EQ(shortArray->GetWithoutChecks(0), 0);
- mirror::ArtField* intArrayField = h_klass->FindDeclaredStaticField("intArrayField", "[I");
+ ArtField* intArrayField = h_klass->FindDeclaredStaticField("intArrayField", "[I");
ASSERT_TRUE(intArrayField != nullptr);
mirror::IntArray* intArray = intArrayField->GetObject(h_klass.Get())->AsIntArray();
ASSERT_TRUE(intArray != nullptr);
ASSERT_EQ(intArray->GetLength(), 1);
ASSERT_EQ(intArray->GetWithoutChecks(0), 0);
- mirror::ArtField* longArrayField = h_klass->FindDeclaredStaticField("longArrayField", "[J");
+ ArtField* longArrayField = h_klass->FindDeclaredStaticField("longArrayField", "[J");
ASSERT_TRUE(longArrayField != nullptr);
mirror::LongArray* longArray = longArrayField->GetObject(h_klass.Get())->AsLongArray();
ASSERT_TRUE(longArray != nullptr);
ASSERT_EQ(longArray->GetLength(), 1);
ASSERT_EQ(longArray->GetWithoutChecks(0), static_cast<int64_t>(0));
- mirror::ArtField* floatArrayField = h_klass->FindDeclaredStaticField("floatArrayField", "[F");
+ ArtField* floatArrayField = h_klass->FindDeclaredStaticField("floatArrayField", "[F");
ASSERT_TRUE(floatArrayField != nullptr);
mirror::FloatArray* floatArray = floatArrayField->GetObject(h_klass.Get())->AsFloatArray();
ASSERT_TRUE(floatArray != nullptr);
ASSERT_EQ(floatArray->GetLength(), 1);
ASSERT_FLOAT_EQ(floatArray->GetWithoutChecks(0), static_cast<float>(0.0f));
- mirror::ArtField* doubleArrayField = h_klass->FindDeclaredStaticField("doubleArrayField", "[D");
+ ArtField* doubleArrayField = h_klass->FindDeclaredStaticField("doubleArrayField", "[D");
ASSERT_TRUE(doubleArrayField != nullptr);
mirror::DoubleArray* doubleArray = doubleArrayField->GetObject(h_klass.Get())->AsDoubleArray();
ASSERT_TRUE(doubleArray != nullptr);
ASSERT_EQ(doubleArray->GetLength(), 1);
ASSERT_DOUBLE_EQ(doubleArray->GetWithoutChecks(0), static_cast<double>(0.0f));
- mirror::ArtField* objectArrayField = h_klass->FindDeclaredStaticField("objectArrayField",
+ ArtField* objectArrayField = h_klass->FindDeclaredStaticField("objectArrayField",
"[Ljava/lang/Object;");
ASSERT_TRUE(objectArrayField != nullptr);
mirror::ObjectArray<mirror::Object>* objectArray =
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 8a23ff7233..f13da8bc98 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -25,10 +25,10 @@
#include <unistd.h>
#include <memory>
+#include "art_field-inl.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "dex_file-inl.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
@@ -364,7 +364,7 @@ std::string PrettyDescriptor(const char* descriptor) {
return result;
}
-std::string PrettyField(mirror::ArtField* f, bool with_type) {
+std::string PrettyField(ArtField* f, bool with_type) {
if (f == NULL) {
return "null";
}
diff --git a/runtime/utils.h b/runtime/utils.h
index e6a6b1dfad..6dee5fed7e 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -33,10 +33,10 @@
namespace art {
+class ArtField;
class DexFile;
namespace mirror {
-class ArtField;
class ArtMethod;
class Class;
class Object;
@@ -343,7 +343,7 @@ std::string PrettyDescriptor(Primitive::Type type);
// Returns a human-readable signature for 'f'. Something like "a.b.C.f" or
// "int a.b.C.f" (depending on the value of 'with_type').
-std::string PrettyField(mirror::ArtField* f, bool with_type = true)
+std::string PrettyField(ArtField* f, bool with_type = true)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
std::string PrettyField(uint32_t field_idx, const DexFile& dex_file, bool with_type = true);
diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc
index 833427eb28..623a3eccfe 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -146,7 +146,7 @@ TEST_F(UtilsTest, PrettyField) {
mirror::Class* java_lang_String = class_linker_->FindSystemClass(soa.Self(),
"Ljava/lang/String;");
- mirror::ArtField* f;
+ ArtField* f;
f = java_lang_String->FindDeclaredInstanceField("count", "I");
EXPECT_EQ("int java.lang.String.count", PrettyField(f));
EXPECT_EQ("java.lang.String.count", PrettyField(f, false));
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 9fc2658b19..065df051f4 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -18,6 +18,7 @@
#include <iostream>
+#include "art_field-inl.h"
#include "base/logging.h"
#include "base/mutex-inl.h"
#include "class_linker.h"
@@ -30,7 +31,6 @@
#include "indenter.h"
#include "intern_table.h"
#include "leb128.h"
-#include "mirror/art_field-inl.h"
#include "mirror/art_method-inl.h"
#include "mirror/class.h"
#include "mirror/class-inl.h"
@@ -451,7 +451,7 @@ void MethodVerifier::FindLocksAtDexPc() {
Verify();
}
-mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
+ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
uint32_t dex_pc) {
Thread* self = Thread::Current();
StackHandleScope<3> hs(self);
@@ -464,7 +464,7 @@ mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
return verifier.FindAccessedFieldAtDexPc(dex_pc);
}
-mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) {
+ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) {
CHECK(code_item_ != nullptr); // This only makes sense for methods with code.
// Strictly speaking, we ought to be able to get away with doing a subset of the full method
@@ -3788,7 +3788,7 @@ void MethodVerifier::VerifyAPut(const Instruction* inst,
}
}
-mirror::ArtField* MethodVerifier::GetStaticField(int field_idx) {
+ArtField* MethodVerifier::GetStaticField(int field_idx) {
const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class
const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
@@ -3802,8 +3802,8 @@ mirror::ArtField* MethodVerifier::GetStaticField(int field_idx) {
return nullptr; // Can't resolve Class so no more to do here, will do checking at runtime.
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- mirror::ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_,
- class_loader_);
+ ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_,
+ class_loader_);
if (field == nullptr) {
VLOG(verifier) << "Unable to resolve static field " << field_idx << " ("
<< dex_file_->GetFieldName(field_id) << ") in "
@@ -3823,7 +3823,7 @@ mirror::ArtField* MethodVerifier::GetStaticField(int field_idx) {
return field;
}
-mirror::ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
+ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class
const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
@@ -3837,8 +3837,8 @@ mirror::ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int
return nullptr; // Can't resolve Class so no more to do here
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- mirror::ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_,
- class_loader_);
+ ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_,
+ class_loader_);
if (field == nullptr) {
VLOG(verifier) << "Unable to resolve instance field " << field_idx << " ("
<< dex_file_->GetFieldName(field_id) << ") in "
@@ -3894,7 +3894,7 @@ template <MethodVerifier::FieldAccessType kAccType>
void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType& insn_type,
bool is_primitive, bool is_static) {
uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
- mirror::ArtField* field;
+ ArtField* field;
if (is_static) {
field = GetStaticField(field_idx);
} else {
@@ -3914,12 +3914,8 @@ void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType&
}
}
- mirror::Class* field_type_class;
- {
- StackHandleScope<1> hs(self_);
- HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field));
- field_type_class = can_load_classes_ ? h_field->GetType<true>() : h_field->GetType<false>();
- }
+ mirror::Class* field_type_class =
+ can_load_classes_ ? field->GetType<true>() : field->GetType<false>();
if (field_type_class != nullptr) {
field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
field_type_class->CannotBeAssignedFromOtherTypes());
@@ -3988,7 +3984,7 @@ void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType&
}
}
-mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
+ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
RegisterLine* reg_line) {
DCHECK(IsInstructionIGetQuickOrIPutQuick(inst->Opcode())) << inst->Opcode();
const RegType& object_type = reg_line->GetRegisterType(this, inst->VRegB_22c());
@@ -3997,8 +3993,7 @@ mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
return nullptr;
}
uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c());
- mirror::ArtField* const f = mirror::ArtField::FindInstanceFieldWithOffset(object_type.GetClass(),
- field_offset);
+ ArtField* const f = ArtField::FindInstanceFieldWithOffset(object_type.GetClass(), field_offset);
DCHECK_EQ(f->GetOffset().Uint32Value(), field_offset);
if (f == nullptr) {
VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
@@ -4012,7 +4007,7 @@ void MethodVerifier::VerifyQuickFieldAccess(const Instruction* inst, const RegTy
bool is_primitive) {
DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
- mirror::ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
+ ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
if (field == nullptr) {
Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name();
return;
@@ -4030,12 +4025,8 @@ void MethodVerifier::VerifyQuickFieldAccess(const Instruction* inst, const RegTy
// Get the field type.
const RegType* field_type;
{
- mirror::Class* field_type_class;
- {
- StackHandleScope<1> hs(Thread::Current());
- HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field));
- field_type_class = can_load_classes_ ? h_field->GetType<true>() : h_field->GetType<false>();
- }
+ mirror::Class* field_type_class = can_load_classes_ ? field->GetType<true>() :
+ field->GetType<false>();
if (field_type_class != nullptr) {
field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 8c0321ee4a..cd414c28cd 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -191,7 +191,7 @@ class MethodVerifier {
// Returns the accessed field corresponding to the quick instruction's field
// offset at 'dex_pc' in method 'm'.
- static mirror::ArtField* FindAccessedFieldAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc)
+ static ArtField* FindAccessedFieldAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns the invoked method corresponding to the quick instruction's vtable
@@ -250,7 +250,7 @@ class MethodVerifier {
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns the access field of a quick field access (iget/iput-quick) or nullptr
// if it cannot be found.
- mirror::ArtField* GetQuickFieldAccess(const Instruction* inst, RegisterLine* reg_line)
+ ArtField* GetQuickFieldAccess(const Instruction* inst, RegisterLine* reg_line)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Is the method being verified a constructor?
@@ -301,7 +301,7 @@ class MethodVerifier {
void FindLocksAtDexPc() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- mirror::ArtField* FindAccessedFieldAtDexPc(uint32_t dex_pc)
+ ArtField* FindAccessedFieldAtDexPc(uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
mirror::ArtMethod* FindInvokedMethodAtDexPc(uint32_t dex_pc)
@@ -525,11 +525,11 @@ class MethodVerifier {
bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Lookup instance field and fail for resolution violations
- mirror::ArtField* GetInstanceField(const RegType& obj_type, int field_idx)
+ ArtField* GetInstanceField(const RegType& obj_type, int field_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Lookup static field and fail for resolution violations
- mirror::ArtField* GetStaticField(int field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtField* GetStaticField(int field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Perform verification of an iget/sget/iput/sput instruction.
enum class FieldAccessType { // private