// Report this field access to instrumentation if needed.
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
StackHandleScope<1> hs(self);
StackArtFieldHandleScope<1> rhs(self); // Wrap in handle wrapper in case the listener does thread suspension.
HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
ObjPtr<mirror::Object> this_object; if (!field->IsStatic()) {
this_object = obj;
}
instrumentation->FieldReadEvent(self,
this_object,
shadow_frame.GetMethod(),
shadow_frame.GetDexPC(),
field); if (UNLIKELY(self->IsExceptionPending())) { returnfalse;
}
}
switch (field_type) { case Primitive::kPrimBoolean:
result->SetZ(field->GetBoolean(obj)); break; case Primitive::kPrimByte:
result->SetB(field->GetByte(obj)); break; case Primitive::kPrimChar:
result->SetC(field->GetChar(obj)); break; case Primitive::kPrimShort:
result->SetS(field->GetShort(obj)); break; case Primitive::kPrimInt:
result->SetI(field->GetInt(obj)); break; case Primitive::kPrimLong:
result->SetJ(field->GetLong(obj)); break; case Primitive::kPrimNot:
result->SetL(field->GetObject(obj)); break; case Primitive::kPrimVoid:
LOG(FATAL) << "Unreachable " << field_type; break;
} returntrue;
}
// Report this field access to instrumentation if needed. Since we only have the offset of // the field from the base of the object, we need to look for it first.
instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
StackHandleScope<2> hs(self);
StackArtFieldHandleScope<1> rhs(self); // Save this and return value (if needed) in case the instrumentation causes a suspend.
HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
ObjPtr<mirror::Object> this_object = field->IsStatic() ? nullptr : obj;
mirror::Object* fake_root = nullptr;
HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>(
field_type == Primitive::kPrimNot ? value.GetGCRoot() : &fake_root));
instrumentation->FieldWriteEvent(self,
this_object,
shadow_frame.GetMethod(),
shadow_frame.GetDexPC(),
field,
value); if (UNLIKELY(self->IsExceptionPending())) { returnfalse;
} if (shadow_frame.GetForcePopFrame()) { // We need to check this here since we expect that the FieldWriteEvent happens before the // actual field write. If one pops the stack we should not modify the field. The next // instruction will force a pop. Return true.
DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); returntrue;
}
}
switch (field_type) { case Primitive::kPrimBoolean:
field->SetBoolean<transaction_active>(obj, value.GetZ()); break; case Primitive::kPrimByte:
field->SetByte<transaction_active>(obj, value.GetB()); break; case Primitive::kPrimChar:
field->SetChar<transaction_active>(obj, value.GetC()); break; case Primitive::kPrimShort:
field->SetShort<transaction_active>(obj, value.GetS()); break; case Primitive::kPrimInt:
field->SetInt<transaction_active>(obj, value.GetI()); break; case Primitive::kPrimLong:
field->SetLong<transaction_active>(obj, value.GetJ()); break; case Primitive::kPrimNot: {
ObjPtr<mirror::Object> reg = value.GetL(); if (reg != nullptr && !shadow_frame.GetMethod()->SkipAccessChecks()) { // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the // object in the destructor.
ObjPtr<mirror::Class> field_class;
{
StackHandleScope<2> hs(self);
StackArtFieldHandleScope<1> rhs(self);
HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(®));
HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
ReflectiveHandleWrapper<ArtField> fh(rhs.NewReflectiveHandleWrapper(&field));
field_class = field->ResolveType();
} // ArtField::ResolveType() may fail as evidenced with a dexing bug (b/78788577). if (UNLIKELY(field_class.IsNull())) {
Thread::Current()->AssertPendingException(); returnfalse;
} if (UNLIKELY(!reg->VerifierInstanceOf(field_class))) { // This should never happen.
std::string temp1, temp2;
self->ThrowNewExceptionF("Ljava/lang/InternalError;", "Put '%s' that is not instance of field '%s' in '%s'",
reg->GetClass()->GetDescriptor(&temp1),
field_class->GetDescriptor(&temp2),
field->GetDeclaringClassDescriptor()); returnfalse;
}
}
field->SetObj<transaction_active>(obj, reg); break;
} case Primitive::kPrimVoid: {
LOG(FATAL) << "Unreachable " << field_type; break;
}
} if (transaction_active) { if (UNLIKELY(self->IsExceptionPending())) { returnfalse;
}
} returntrue;
}
} // namespace art
#endif// ART_RUNTIME_COMMON_DEX_OPERATIONS_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.