Move ArtField to native
Add linear alloc. Moved ArtField to be native object. Changed image
writer to put ArtFields after the mirror section.
Savings:
2MB on low ram devices
4MB on normal devices
Total PSS measurements before (normal N5, 95s after shell start):
Image size: 7729152 bytes
23112 kB: .NonMoving
23212 kB: .NonMoving
22868 kB: .NonMoving
23072 kB: .NonMoving
22836 kB: .NonMoving
19618 kB: .Zygote
19850 kB: .Zygote
19623 kB: .Zygote
19924 kB: .Zygote
19612 kB: .Zygote
Avg: 42745.4 kB
After:
Image size: 7462912 bytes
17440 kB: .NonMoving
16776 kB: .NonMoving
16804 kB: .NonMoving
17812 kB: .NonMoving
16820 kB: .NonMoving
18788 kB: .Zygote
18856 kB: .Zygote
19064 kB: .Zygote
18841 kB: .Zygote
18629 kB: .Zygote
3499 kB: .LinearAlloc
3408 kB: .LinearAlloc
3424 kB: .LinearAlloc
3600 kB: .LinearAlloc
3436 kB: .LinearAlloc
Avg: 39439.4 kB
No reflection performance changes.
Bug: 19264997
Bug: 17643507
Change-Id: I10c73a37913332080aeb978c7c94713bdfe4fe1c
diff --git a/runtime/Android.mk b/runtime/Android.mk
index c0e7f47..d3488fc 100644
--- a/runtime/Android.mk
+++ b/runtime/Android.mk
@@ -19,6 +19,7 @@
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 @@
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 0769687..d7de119 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 @@
}
-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 @@
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 @@
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 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 @@
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 @@
#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 @@
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 @@
#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 @@
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 @@
#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 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 @@
}
#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 @@
#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 @@
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 @@
// 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 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 @@
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 @@
// 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
similarity index 78%
rename from runtime/mirror/art_field-inl.h
rename to runtime/art_field-inl.h
index 986852f..aeb1273 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 @@
}
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 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 @@
}
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 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 @@
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
}
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 @@
}
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 @@
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 @@
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/art_field.cc b/runtime/art_field.cc
new file mode 100644
index 0000000..cdf8967
--- /dev/null
+++ b/runtime/art_field.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 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 "art_field.h"
+
+#include "art_field-inl.h"
+#include "gc/accounting/card_table-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 {
+
+ArtField::ArtField() : access_flags_(0), field_dex_idx_(0), offset_(0) {
+ declaring_class_ = GcRoot<mirror::Class>(nullptr);
+}
+
+void ArtField::SetOffset(MemberOffset num_bytes) {
+ DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
+ if (kIsDebugBuild && Runtime::Current()->IsAotCompiler() &&
+ Runtime::Current()->IsCompilingBootImage()) {
+ Primitive::Type type = GetTypeAsPrimitiveType();
+ if (type == Primitive::kPrimDouble || type == Primitive::kPrimLong) {
+ DCHECK_ALIGNED(num_bytes.Uint32Value(), 8);
+ }
+ }
+ // Not called within a transaction.
+ offset_ = num_bytes.Uint32Value();
+}
+
+void ArtField::VisitRoots(RootVisitor* visitor) {
+ declaring_class_.VisitRoot(visitor, RootInfo(kRootStickyClass));
+}
+
+ArtField* ArtField::FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset) {
+ DCHECK(klass != nullptr);
+ 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.
+ return (klass->GetSuperClass() != nullptr) ?
+ FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset) : nullptr;
+}
+
+} // namespace art
diff --git a/runtime/art_field.h b/runtime/art_field.h
new file mode 100644
index 0000000..5bdbe71
--- /dev/null
+++ b/runtime/art_field.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2011 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_ART_FIELD_H_
+#define ART_RUNTIME_ART_FIELD_H_
+
+#include <jni.h>
+
+#include "gc_root.h"
+#include "modifiers.h"
+#include "object_callbacks.h"
+#include "offsets.h"
+#include "primitive.h"
+#include "read_barrier_option.h"
+
+namespace art {
+
+class DexFile;
+class ScopedObjectAccessAlreadyRunnable;
+
+namespace mirror {
+class Class;
+class DexCache;
+class Object;
+class String;
+} // namespace mirror
+
+class ArtField {
+ public:
+ ArtField();
+
+ mirror::Class* GetDeclaringClass() 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.
+ access_flags_ = new_access_flags;
+ }
+
+ bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return (GetAccessFlags() & kAccPublic) != 0;
+ }
+
+ bool IsStatic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return (GetAccessFlags() & kAccStatic) != 0;
+ }
+
+ bool IsFinal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return (GetAccessFlags() & kAccFinal) != 0;
+ }
+
+ uint32_t GetDexFieldIndex() {
+ return field_dex_idx_;
+ }
+
+ void SetDexFieldIndex(uint32_t new_idx) {
+ // Not called within a transaction.
+ field_dex_idx_ = new_idx;
+ }
+
+ // Offset to field within an Object.
+ MemberOffset GetOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static MemberOffset OffsetOffset() {
+ return MemberOffset(OFFSETOF_MEMBER(ArtField, offset_));
+ }
+
+ MemberOffset GetOffsetDuringLinking() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetOffset(MemberOffset num_bytes) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // field access, null object for static fields
+ uint8_t GetBoolean(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ template<bool kTransactionActive>
+ 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(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(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(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(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(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(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(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(mirror::Object* object, mirror::Object* l)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Raw field accesses.
+ uint32_t Get32(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ template<bool kTransactionActive>
+ 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 Set64(mirror::Object* object, uint64_t new_value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ mirror::Object* GetObj(mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ 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_) {
+ return (GetAccessFlags() & kAccVolatile) != 0;
+ }
+
+ // Returns an instance field with this offset in the given class or nullptr if not found.
+ static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Resolves / returns the name from the dex cache.
+ mirror::String* GetStringName(Thread* self, bool resolve)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Primitive::Type GetTypeAsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ template <bool kResolve>
+ mirror::Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ GcRoot<mirror::Class>& DeclaringClassRoot() {
+ return declaring_class_;
+ }
+
+ private:
+ GcRoot<mirror::Class> declaring_class_;
+
+ uint32_t access_flags_;
+
+ // Dex cache index of field id
+ uint32_t field_dex_idx_;
+
+ // Offset of field within an instance or in the Class' static fields
+ uint32_t offset_;
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_ART_FIELD_H_
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index dba4af8..4c83e88 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -135,13 +135,13 @@
#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 dd29404..59d38ad 100644
--- a/runtime/base/arena_allocator.cc
+++ b/runtime/base/arena_allocator.cc
@@ -132,11 +132,10 @@
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 @@
}
}
-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 @@
}
}
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 @@
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 cc7b856..3a86b61 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -165,7 +165,7 @@
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 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 @@
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 @@
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 af00834..6e4b96c 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -73,6 +73,7 @@
kRosAllocBulkFreeLock,
kAllocSpaceLock,
kBumpPointerSpaceBlockLock,
+ kArenaPoolLock,
kDexFileMethodInlinerLock,
kDexFileToMethodInlinerMapLock,
kMarkSweepMarkStackLock,
diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc
index 2b0167d..f94ebea 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 @@
return false;
}
- mirror::ArtField* f = CheckFieldID(soa, fid);
+ ArtField* f = CheckFieldID(soa, fid);
if (f == nullptr) {
return false;
}
@@ -248,7 +248,7 @@
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 @@
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 @@
}
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 @@
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 5198769..87d1c4c 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 @@
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 @@
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 @@
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 12fa546..935c401 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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::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 @@
}
}
}
+ buffered_visitor.Flush(); // Flush before clearing new_class_roots_.
if ((flags & kVisitRootFlagClearRootLog) != 0) {
new_class_roots_.clear();
}
@@ -1077,7 +1099,6 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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::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 @@
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 @@
}
}
+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 @@
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 @@
} 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::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 @@
// 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 @@
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 @@
}
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 @@
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 @@
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 @@
// 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 @@
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 @@
// 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 @@
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::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 @@
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 @@
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 @@
"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 @@
}
// 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 @@
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 @@
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 @@
// 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 @@
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 577fec2..2427462 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -70,12 +70,10 @@
kJavaLangString,
kJavaLangDexCache,
kJavaLangRefReference,
- kJavaLangReflectArtField,
kJavaLangReflectArtMethod,
kJavaLangReflectField,
kJavaLangReflectProxy,
kJavaLangStringArrayClass,
- kJavaLangReflectArtFieldArrayClass,
kJavaLangReflectArtMethodArrayClass,
kJavaLangReflectFieldArrayClass,
kJavaLangClassLoader,
@@ -201,7 +199,7 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 3f6c5a0..a31a785 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 @@
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 d400010..60b7fa2 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -398,7 +398,7 @@
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 @@
// 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 36de221..407746f 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 @@
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 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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 9e749e3..df95cf9 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 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 @@
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 @@
// 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 a909a1a..12fe863 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 @@
}
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 @@
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 @@
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::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::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 @@
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::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 @@
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 @@
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 @@
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 @@
// 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 @@
} 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 @@
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 @@
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 @@
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 @@
}
// 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::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 @@
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::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::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 dd7f9c5..c287121 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 @@
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 @@
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 @@
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 8685d8e..03a47a3 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 @@
}
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 @@
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 @@
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 8e2d6c2..5bdd9b6 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -37,11 +37,11 @@
// 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 @@
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 8a13d34..cbfba12 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -252,7 +252,7 @@
}
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 @@
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 @@
// 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 @@
#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 70e2851..1d8df68 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 77eec46..8d419f8 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 @@
};
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 @@
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 22bf939..b5a7c09 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 a3fac58..cd3f910 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 b16a146..eeb385e 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 ad8d988..2da8325 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 @@
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 @@
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 6a68880..eabb1c2 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 8902df8..3c247cd 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 104ed36..4e3845e 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 79d1034..ed2e295 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 b9153c1..83da5a8 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 @@
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 @@
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 @@
// 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 1fb3252..e28e8d7 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -43,8 +43,9 @@
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 @@
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 @@
*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 @@
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 @@
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 @@
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 d7f8057..9ae2af4 100644
--- a/runtime/gc/space/image_space.h
+++ b/runtime/gc/space/image_space.h
@@ -145,7 +145,7 @@
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 ac8751c..4d7fd2e 100644
--- a/runtime/globals.h
+++ b/runtime/globals.h
@@ -71,8 +71,6 @@
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 cdb3e2a..23af25d 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 @@
__ 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 @@
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 @@
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 3cb2580..2d8c1c4 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 @@
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 3c527b8..613414a 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -32,6 +32,8 @@
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 @@
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 @@
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 @@
// 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 680b563..f8c0e83 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -929,7 +929,7 @@
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::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 77314c60..41821a6 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 @@
// 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 @@
// 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 @@
// 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 @@
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 375d644..3ae611b 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -281,11 +281,10 @@
// 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(®));
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 2f8bf55..0e0d56a 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 9af8102..dd8c57b 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -208,20 +208,22 @@
// 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 31c9a0b..a503b17 100644
--- a/runtime/jdwp/jdwp.h
+++ b/runtime/jdwp/jdwp.h
@@ -33,11 +33,11 @@
namespace art {
+class ArtField;
union JValue;
class Thread;
namespace mirror {
- class ArtField;
class ArtMethod;
class Class;
class Object;
@@ -207,7 +207,7 @@
* "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 c9a4483..ccf8bff 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 @@
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 @@
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 425d2d3..9d5d74f 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 @@
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 9ec64d4..8a5461b 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 0000000..fe6bee6
--- /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 0000000..6d8eda6
--- /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 588615f..edd2888 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -622,7 +622,7 @@
}
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 6452f31..8b3418d 100644
--- a/runtime/mirror/array-inl.h
+++ b/runtime/mirror/array-inl.h
@@ -203,7 +203,7 @@
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 115fcf2..832ad68 100644
--- a/runtime/mirror/array.h
+++ b/runtime/mirror/array.h
@@ -54,7 +54,7 @@
}
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_field.cc b/runtime/mirror/art_field.cc
deleted file mode 100644
index 83602d4..0000000
--- a/runtime/mirror/art_field.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 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 "art_field.h"
-
-#include "art_field-inl.h"
-#include "gc/accounting/card_table-inl.h"
-#include "object-inl.h"
-#include "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);
-}
-
-void ArtField::SetOffset(MemberOffset num_bytes) {
- DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
- if (kIsDebugBuild && Runtime::Current()->IsAotCompiler() &&
- Runtime::Current()->IsCompilingBootImage()) {
- Primitive::Type type = GetTypeAsPrimitiveType();
- if (type == Primitive::kPrimDouble || type == Primitive::kPrimLong) {
- DCHECK_ALIGNED(num_bytes.Uint32Value(), 8);
- }
- }
- // Not called within a transaction.
- SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, offset_), num_bytes.Uint32Value());
-}
-
-void ArtField::VisitRoots(RootVisitor* visitor) {
- java_lang_reflect_ArtField_.VisitRootIfNonNull(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;
- }
- }
- }
- // We did not find field in the class: look into superclass.
- if (klass->GetSuperClass() != NULL) {
- return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset);
- } else {
- return nullptr;
- }
-}
-
-} // namespace mirror
-} // namespace art
diff --git a/runtime/mirror/art_field.h b/runtime/mirror/art_field.h
deleted file mode 100644
index 9d95cb9..0000000
--- a/runtime/mirror/art_field.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2011 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_MIRROR_ART_FIELD_H_
-#define ART_RUNTIME_MIRROR_ART_FIELD_H_
-
-#include <jni.h>
-
-#include "gc_root.h"
-#include "modifiers.h"
-#include "object.h"
-#include "object_callbacks.h"
-#include "primitive.h"
-#include "read_barrier_option.h"
-
-namespace art {
-
-struct ArtFieldOffsets;
-class DexFile;
-class ScopedObjectAccessAlreadyRunnable;
-
-namespace mirror {
-
-class DexCache;
-
-// C++ mirror of java.lang.reflect.ArtField
-class MANAGED ArtField FINAL : public Object {
- public:
- // Size of java.lang.reflect.ArtField.class.
- static uint32_t ClassSize();
-
- // Size of an instance of java.lang.reflect.ArtField not including its value array.
- static constexpr uint32_t InstanceSize() {
- return sizeof(ArtField);
- }
-
- Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void SetDeclaringClass(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);
- }
-
- bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return (GetAccessFlags() & kAccPublic) != 0;
- }
-
- bool IsStatic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return (GetAccessFlags() & kAccStatic) != 0;
- }
-
- bool IsFinal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return (GetAccessFlags() & kAccFinal) != 0;
- }
-
- uint32_t GetDexFieldIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtField, field_dex_idx_));
- }
-
- void SetDexFieldIndex(uint32_t new_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // Not called within a transaction.
- SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtField, field_dex_idx_), new_idx);
- }
-
- // Offset to field within an Object.
- MemberOffset GetOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static MemberOffset OffsetOffset() {
- return MemberOffset(OFFSETOF_MEMBER(ArtField, offset_));
- }
-
- MemberOffset GetOffsetDuringLinking() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- 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_);
- 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_);
- 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_);
- 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_);
- 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_);
- 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_);
- 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_);
- 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_);
- 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_);
- template<bool kTransactionActive>
- void SetObject(Object* object, 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_);
- 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_);
- template<bool kTransactionActive>
- void SetObj(Object* object, Object* 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>();
- }
-
- static void SetClass(Class* java_lang_reflect_ArtField);
- static void ResetClass();
- static void VisitRoots(RootVisitor* visitor)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool IsVolatile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return (GetAccessFlags() & kAccVolatile) != 0;
- }
-
- // Returns an instance field with this offset in the given class or nullptr if not found.
- static ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint32_t field_offset)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- 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_);
-
- const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- Primitive::Type GetTypeAsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- template <bool kResolve>
- Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- private:
- // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- // The class we are a part of
- HeapReference<Class> declaring_class_;
-
- uint32_t access_flags_;
-
- // Dex cache index of field id
- uint32_t field_dex_idx_;
-
- // 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_
diff --git a/runtime/mirror/art_method.cc b/runtime/mirror/art_method.cc
index edbbb4a..92aea1f 100644
--- a/runtime/mirror/art_method.cc
+++ b/runtime/mirror/art_method.cc
@@ -53,7 +53,7 @@
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 c368dc6..5b72e5a 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -397,9 +397,9 @@
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 @@
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() {
+inline void Class::SetIFieldsUnchecked(ArtField* new_ifields) {
+ SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields);
+}
+
+inline ArtField* Class::GetSFieldsUnchecked() {
+ return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+}
+
+inline ArtField* Class::GetIFieldsUnchecked() {
+ return GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_));
+}
+
+inline ArtField* Class::GetSFields() {
DCHECK(IsLoaded() || IsErroneous()) << GetStatus();
- return GetFieldObject<ObjectArray<ArtField>>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_));
+ return GetSFieldsUnchecked();
}
-inline void Class::SetSFields(ObjectArray<ArtField>* new_sfields)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+inline void Class::SetSFields(ArtField* new_sfields) {
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);
+ GetFieldPtr<ArtField*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_)) == nullptr);
+ SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
}
-inline uint32_t Class::NumStaticFields() {
- return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
+inline void Class::SetSFieldsUnchecked(ArtField* new_sfields) {
+ SetFieldPtr<false, true, kVerifyNone>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields);
}
-
-inline ArtField* Class::GetStaticField(uint32_t i) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetSFields()->GetWithoutChecks(i);
+inline ArtField* Class::GetStaticField(uint32_t i) {
+ DCHECK_LT(i, NumStaticFields());
+ return &GetSFields()[i];
}
-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 uint32_t Class::NumInstanceFields() {
- return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
-}
-
-inline ArtField* Class::GetInstanceField(uint32_t i) { // TODO: uint16_t
- DCHECK_NE(NumInstanceFields(), 0U);
- return GetIFields()->GetWithoutChecks(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 @@
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 @@
}
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 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 @@
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 b82a58f..92493bc 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 @@
namespace mirror {
-class ArtField;
class ArtMethod;
class ClassLoader;
class DexCache;
@@ -420,9 +420,6 @@
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 @@
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,18 +886,24 @@
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_);
+
+ 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
ArtField* GetStaticField(uint32_t i) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- // TODO: uint16_t
- void SetStaticField(uint32_t i, ArtField* f) 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,
const StringPiece& type)
@@ -974,6 +982,10 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
// 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 6758e22..1cb437e 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 @@
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 @@
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 d6c11e8..ade8bd2 100644
--- a/runtime/mirror/dex_cache.cc
+++ b/runtime/mirror/dex_cache.cc
@@ -36,7 +36,7 @@
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 @@
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 c548c03..7e30b89 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -50,7 +50,7 @@
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 @@
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 @@
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 @@
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 53e5534..1d6846b 100644
--- a/runtime/mirror/dex_cache_test.cc
+++ b/runtime/mirror/dex_cache_test.cc
@@ -47,7 +47,7 @@
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 @@
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 24ebc48..7db1811 100644
--- a/runtime/mirror/field-inl.h
+++ b/runtime/mirror/field-inl.h
@@ -27,9 +27,8 @@
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 @@
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 82cc26e..70311bb 100644
--- a/runtime/mirror/field.cc
+++ b/runtime/mirror/field.cc
@@ -55,7 +55,7 @@
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 cea06f5..9988f84 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 @@
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 d690163..af0e856 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -225,18 +225,6 @@
}
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 @@
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 @@
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 @@
}
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 57ac46f..04d0cd8 100644
--- a/runtime/mirror/object.cc
+++ b/runtime/mirror/object.cc
@@ -204,22 +204,19 @@
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 @@
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 cfc8549..bfd5d4d 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 @@
namespace mirror {
-class ArtField;
class ArtMethod;
class Array;
class Class;
@@ -191,12 +191,6 @@
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 80d5135..30bc1cd 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 @@
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 1ce298d..747a008 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -722,14 +722,12 @@
"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 760038a..1a6adf8 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -313,8 +313,8 @@
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 @@
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 @@
}
}
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 b657aec..5ad18f8 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 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 @@
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 @@
// 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 @@
}
}
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 @@
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 1ffcbdf..681b261 100644
--- a/runtime/native/java_lang_reflect_Array.cc
+++ b/runtime/native/java_lang_reflect_Array.cc
@@ -63,7 +63,7 @@
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 765f548..5e1a4c5 100644
--- a/runtime/native/java_lang_reflect_Constructor.cc
+++ b/runtime/native/java_lang_reflect_Constructor.cc
@@ -57,8 +57,6 @@
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 d2362a2..37c6353 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 @@
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 32bfdaf..3818487 100644
--- a/runtime/primitive.h
+++ b/runtime/primitive.h
@@ -27,21 +27,11 @@
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 @@
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 cb97049..a3156b4 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 @@
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 @@
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 44e2844..efaa0ac 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 @@
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 471b37c..52d83a2 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 4e94de4..3e1315c 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 @@
#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 @@
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 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 @@
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 @@
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 ff970e5..c2d406a 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 1cd0a96..66d38ce 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 @@
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 @@
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 @@
// 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 @@
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 baa4d18..d95640d 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -42,6 +42,7 @@
class ArenaPool;
class CompilerCallbacks;
+class LinearAlloc;
namespace gc {
class Heap;
@@ -549,6 +550,9 @@
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 @@
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 adf3480..11b7df6 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 @@
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 af11f73..58b272b 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 @@
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 @@
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 @@
}
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 @@
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 5375dc0..7326865 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -582,7 +582,7 @@
}
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::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 80f926f..d8bd428 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 @@
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 24ecf6b..9792eca 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 @@
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 @@
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 @@
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 8a23ff7..f13da8b 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 @@
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 e6a6b1d..6dee5fe 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 @@
// 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 833427e..623a3ec 100644
--- a/runtime/utils_test.cc
+++ b/runtime/utils_test.cc
@@ -146,7 +146,7 @@
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 9fc2658..065df05 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 @@
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 @@
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 @@
}
}
-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 @@
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 @@
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 @@
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 @@
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 @@
}
}
- 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 = ®_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
field_type_class->CannotBeAssignedFromOtherTypes());
@@ -3988,7 +3984,7 @@
}
}
-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 @@
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 @@
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 @@
// 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 = ®_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 8c0321e..cd414c2 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -191,7 +191,7 @@
// 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 @@
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 @@
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 @@
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