Android5.1.1数据结构解析之ObjectReference、StackReference

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.
template<bool kPoisonReferences, class MirrorType>
class 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<kPoisonReferences, MirrorType>(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<uintptr_t>(mirror_ptr);
    return static_cast<uint32_t>(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<MirrorType*>(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.
template<class MirrorType>
class MANAGED StackReference : public mirror::ObjectReference<false, MirrorType> {
 public:
  StackReference<MirrorType>() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
      : mirror::ObjectReference<false, MirrorType>(nullptr) {}

  static StackReference<MirrorType> FromMirrorPtr(MirrorType* p)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    return StackReference<MirrorType>(p);
  }

 private:
  StackReference<MirrorType>(MirrorType* p) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
      : mirror::ObjectReference<false, MirrorType>(p) {}
};

这个类有两个构造函数:公有构造函数没有参数,它创建的是一个默认设置的StackReference对象;私有构造函数被静态成员函数FromMirrorPtr调用。

静态成员函数:FromMirrorPtr

这个函数用于创建StackReference类的对象。它只有一个*<MirrorType>**类型的参数,将这个参数传入StackReference类的私有构造函数中创建StackReference对象,然后返回创建的对象。

转载于:https://my.oschina.net/ibuwai/blog/523613

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值