void ClassLinker::LoadClassMembers(Thread
*
self
,const DexFile& dex_file,const uint8_t
*
class_data,Handle<mirror::Class> klass) {
{
/
/
Note: We cannot have thread suspension until the field
and
method arrays are setup
or
else
/
/
Class::VisitFieldRoots may miss some fields
or
methods.
ScopedAssertNoThreadSuspension nts(__FUNCTION__);
/
/
Load static fields.
...
for
(; it.HasNextStaticField(); it.
Next
()) {
uint32_t field_idx
=
it.GetMemberIndex();
DCHECK_GE(field_idx, last_field_idx);
/
/
Ordering enforced by DexFileVerifier.
if
(num_sfields
=
=
0
|| LIKELY(field_idx > last_field_idx)) {
DCHECK_LT(num_sfields, it.NumStaticFields());
LoadField(it, klass, &sfields
-
>At(num_sfields));
+
+
num_sfields;
last_field_idx
=
field_idx;
}
}
/
/
Load instance fields.
LengthPrefixedArray<ArtField>
*
ifields
=
AllocArtFieldArray(
self
,allocator,it.NumInstanceFields());
size_t num_ifields
=
0u
;
last_field_idx
=
0u
;
for
(; it.HasNextInstanceField(); it.
Next
()) {
uint32_t field_idx
=
it.GetMemberIndex();
DCHECK_GE(field_idx, last_field_idx);
/
/
Ordering enforced by DexFileVerifier.
if
(num_ifields
=
=
0
|| LIKELY(field_idx > last_field_idx)) {
DCHECK_LT(num_ifields, it.NumInstanceFields());
LoadField(it, klass, &ifields
-
>At(num_ifields));
+
+
num_ifields;
last_field_idx
=
field_idx;
}
}
...
/
/
Set
the field arrays.
klass
-
>SetSFieldsPtr(sfields);
DCHECK_EQ(klass
-
>NumStaticFields(), num_sfields);
klass
-
>SetIFieldsPtr(ifields);
DCHECK_EQ(klass
-
>NumInstanceFields(), num_ifields);
/
/
Load methods.
bool
has_oat_class
=
false;
const OatFile::OatClass oat_class
=
(Runtime::Current()
-
>IsStarted() && !Runtime::Current()
-
>IsAotCompiler())
? OatFile::FindOatClass(dex_file, klass
-
>GetDexClassDefIndex(), &has_oat_class)
: OatFile::OatClass::Invalid();
const OatFile::OatClass
*
oat_class_ptr
=
has_oat_class ? &oat_class : nullptr;
klass
-
>SetMethodsPtr(
AllocArtMethodArray(
self
, allocator, it.NumDirectMethods()
+
it.NumVirtualMethods()),
it.NumDirectMethods(),
it.NumVirtualMethods());
size_t class_def_method_index
=
0
;
uint32_t last_dex_method_index
=
DexFile::kDexNoIndex;
size_t last_class_def_method_index
=
0
;
/
/
TODO These should really use the iterators.
for
(size_t i
=
0
; it.HasNextDirectMethod(); i
+
+
, it.
Next
()) {
ArtMethod
*
method
=
klass
-
>GetDirectMethodUnchecked(i, image_pointer_size_);
LoadMethod(dex_file, it, klass, method);
LinkCode(this, method, oat_class_ptr, class_def_method_index);
uint32_t it_method_index
=
it.GetMemberIndex();
if
(last_dex_method_index
=
=
it_method_index) {
/
/
duplicate case
method
-
>SetMethodIndex(last_class_def_method_index);
}
else
{
method
-
>SetMethodIndex(class_def_method_index);
last_dex_method_index
=
it_method_index;
last_class_def_method_index
=
class_def_method_index;
}
class_def_method_index
+
+
;
}
for
(size_t i
=
0
; it.HasNextVirtualMethod(); i
+
+
, it.
Next
()) {
ArtMethod
*
method
=
klass
-
>GetVirtualMethodUnchecked(i, image_pointer_size_);
LoadMethod(dex_file, it, klass, method);
DCHECK_EQ(class_def_method_index, it.NumDirectMethods()
+
i);
LinkCode(this, method, oat_class_ptr, class_def_method_index);
class_def_method_index
+
+
;
}
DCHECK(!it.HasNext());
}
/
/
Ensure that the card
is
marked so that remembered sets pick up native roots.
Runtime::Current()
-
>GetHeap()
-
>WriteBarrierEveryFieldOf(klass.Get());
self
-
>AllowThreadSuspension();
}