Android5.1.1数据结构解析之ObjectReference、StackReference
@(Android研究)[Android|ObjectReference|StackReference]
[TOC]
ObjectReference
这个数据结构是一个模板类,它有两个模板参数kPoisonReferences和MirrorType,MirrorType表示所引用的类型,关于kPoisonReferences在下面会介绍到。它的源码在文件"art/runtime/mirror/object_reference.h"中,下面是它的源码和对这个类的解析:
// Value type representing a reference to a mirror::Object of type MirrorType.templateclass MANAGED ObjectReference { public: MirrorType* AsMirrorPtr() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return UnCompress(); } void Assign(MirrorType* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { reference_ = Compress(other); } void Clear() { reference_ = 0; } uint32_t AsVRegValue() const { return reference_; } protected: ObjectReference (MirrorType* mirror_ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : reference_(Compress(mirror_ptr)) { } // Compress reference to its bit representation. static uint32_t Compress(MirrorType* mirror_ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { uintptr_t as_bits = reinterpret_cast (mirror_ptr); return static_cast (kPoisonReferences ? -as_bits : as_bits); } // Uncompress an encoded reference from its bit representation. MirrorType* UnCompress() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { uintptr_t as_bits = kPoisonReferences ? -reference_ : reference_; return reinterpret_cast (as_bits); } friend class Object; // The encoded reference to a mirror::Object. uint32_t reference_;};
ObjectReference类的构造函数
ObjectReference类的构造函数唯一值得注意的是它调用了类的静态成员函数Compress,将函数Compress的返回值赋给成员变量reference_。
静态成员函数:Compress
在这个函数中首先将*<MirrorType>*类型的指针转换为了uintptr_t类型,然后根据kPoisonReferences的值是否为true来决定是否对as_bits的值乘以-1,计算完as_bits的值后将它返回。
如果kPoisonReferences为true,那么这个函数就相当于将参数传入的指针进行了加密。
非静态成员函数:UnCompress
根据kPoisonReferences的值是否为true来决定是否对成员变量reference_的值乘以-1。
如果kPoisonReferences为true,那么这个函数就相当于对reference_的值进行了解密。
非静态成员函数:AsMirrorPtr
这个函数调用了UnCompress函数对成员变量reference_中保存的值进行了解密,然后将解密后的值转换为*<MirrorType>*类型指针后返回,返回的是指针的一个拷贝。
非静态成员函数:Assign
这个函数将参数传入的*<MirrorType>*类型的指针经过Compress函数加密后保存到成员变量reference_中。
总结: ObjectReference类仅用于保存指针。当创建ObjectReference对象时传入模板参数kPoisonReferences为true时会对指针进行简单加密,如果kPoisonReferences为false则不对指针做任何操作。 当要更新ObjectReference对象中的指针时可以调用它的成员函数Assign,当要获得保存在ObjectReference对象中的指针时则要调用AsMirrorPtr函数。
StackReference
StackReference是一个模板类,它继承了ObjectReference,对这个类的模板参数的解释可以参考ObjectReference类的解析。它的源码在文件"art/runtime/stack.h"中,下面是它的源码和对这个类的解析:
// A reference from the shadow stack to a MirrorType object within the Java heap.templateclass MANAGED StackReference : public mirror::ObjectReference { public: StackReference () SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : mirror::ObjectReference (nullptr) {} static StackReference FromMirrorPtr(MirrorType* p) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { return StackReference (p); } private: StackReference (MirrorType* p) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) : mirror::ObjectReference (p) {}};
这个类有两个构造函数:公有构造函数没有参数,它创建的是一个默认设置的StackReference对象;私有构造函数被静态成员函数FromMirrorPtr调用。
静态成员函数:FromMirrorPtr
这个函数用于创建StackReference类的对象。它只有一个*<MirrorType>**类型的参数,将这个参数传入StackReference类的私有构造函数中创建StackReference对象,然后返回创建的对象。