Use ArtMethod* .bss entries for HInvokeStaticOrDirect.

Test: m test-art-host-gtest
Test: testrunner.py --host
Test: testrunner.py --target
Test: Nexus 6P boots.
Test: Build aosp_mips64-userdebug.
Bug: 30627598
Change-Id: I0e54fdd2e91e983d475b7a04d40815ba89ae3d4f
diff --git a/runtime/stride_iterator.h b/runtime/stride_iterator.h
index ac04c3b..0560c33 100644
--- a/runtime/stride_iterator.h
+++ b/runtime/stride_iterator.h
@@ -24,8 +24,11 @@
 namespace art {
 
 template<typename T>
-class StrideIterator : public std::iterator<std::forward_iterator_tag, T> {
+class StrideIterator : public std::iterator<std::random_access_iterator_tag, T> {
  public:
+  using difference_type =
+      typename std::iterator<std::random_access_iterator_tag, T>::difference_type;
+
   StrideIterator(const StrideIterator&) = default;
   StrideIterator(StrideIterator&&) = default;
   StrideIterator& operator=(const StrideIterator&) = default;
@@ -44,28 +47,56 @@
     return !(*this == other);
   }
 
-  StrideIterator operator++() {  // Value after modification.
+  StrideIterator& operator++() {  // Value after modification.
     ptr_ += stride_;
     return *this;
   }
 
   StrideIterator operator++(int) {
     StrideIterator<T> temp = *this;
-    ptr_ += stride_;
+    ++*this;
     return temp;
   }
 
-  StrideIterator operator+(ssize_t delta) const {
+  StrideIterator& operator--() {  // Value after modification.
+    ptr_ -= stride_;
+    return *this;
+  }
+
+  StrideIterator operator--(int) {
+    StrideIterator<T> temp = *this;
+    --*this;
+    return temp;
+  }
+
+  StrideIterator& operator+=(difference_type delta) {
+    ptr_ += static_cast<ssize_t>(stride_) * delta;
+    return *this;
+  }
+
+  StrideIterator operator+(difference_type delta) const {
     StrideIterator<T> temp = *this;
     temp += delta;
     return temp;
   }
 
-  StrideIterator& operator+=(ssize_t delta) {
-    ptr_ += static_cast<ssize_t>(stride_) * delta;
+  StrideIterator& operator-=(difference_type delta) {
+    ptr_ -= static_cast<ssize_t>(stride_) * delta;
     return *this;
   }
 
+  StrideIterator operator-(difference_type delta) const {
+    StrideIterator<T> temp = *this;
+    temp -= delta;
+    return temp;
+  }
+
+  difference_type operator-(const StrideIterator& rhs) {
+    DCHECK_EQ(stride_, rhs.stride_);
+    DCHECK_EQ((ptr_ - rhs.ptr_) % stride_, 0u);
+    return (ptr_ - rhs.ptr_) / stride_;
+  }
+
   T& operator*() const {
     return *reinterpret_cast<T*>(ptr_);
   }
@@ -74,12 +105,46 @@
     return &**this;
   }
 
+  T& operator[](difference_type n) {
+    return *(*this + n);
+  }
+
  private:
   uintptr_t ptr_;
   // Not const for operator=.
   size_t stride_;
+
+  template <typename U>
+  friend bool operator<(const StrideIterator<U>& lhs, const StrideIterator<U>& rhs);
 };
 
+template <typename T>
+StrideIterator<T> operator+(typename StrideIterator<T>::difference_type dist,
+                            const StrideIterator<T>& it) {
+  return it + dist;
+}
+
+template <typename T>
+bool operator<(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
+  DCHECK_EQ(lhs.stride_, rhs.stride_);
+  return lhs.ptr_ < rhs.ptr_;
+}
+
+template <typename T>
+bool operator>(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
+  return rhs < lhs;
+}
+
+template <typename T>
+bool operator<=(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
+  return !(rhs < lhs);
+}
+
+template <typename T>
+bool operator>=(const StrideIterator<T>& lhs, const StrideIterator<T>& rhs) {
+  return !(lhs < rhs);
+}
+
 }  // namespace art
 
 #endif  // ART_RUNTIME_STRIDE_ITERATOR_H_