Fix sign problem, implement low-mem mmap wraparound

A signed value comparison meant that on 64b systems comparisons
were false when pointers > 2GB were in use (as happens in long-running
tests). Fix this to be uint.

Implement a simple wrap-around in the MAP_32BIT emulation code.

Change-Id: I09870b4755f2dca676e42e701fbb6f6eb4bb95d0
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index e8cea9d..297f1a8 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -30,9 +30,10 @@
                                   size_t dest_reg, size_t src_reg)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   // If both register locations contains the same value, the register probably holds a reference.
-  int32_t src_value = shadow_frame.GetVReg(src_reg);
+  // Uint required, so that sign extension does not make this wrong on 64b systems
+  uint32_t src_value = shadow_frame.GetVReg(src_reg);
   mirror::Object* o = shadow_frame.GetVRegReference<kVerifyNone>(src_reg);
-  if (src_value == reinterpret_cast<intptr_t>(o)) {
+  if (src_value == reinterpret_cast<uintptr_t>(o)) {
     new_shadow_frame->SetVRegReference(dest_reg, o);
   } else {
     new_shadow_frame->SetVReg(dest_reg, src_value);
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 5647d93..0af25e7 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -47,7 +47,10 @@
 }
 
 #if defined(__LP64__) && !defined(__x86_64__)
-uintptr_t MemMap::next_mem_pos_ = kPageSize * 2;   // first page to check for low-mem extent
+// Where to start with low memory allocation.
+static constexpr uintptr_t LOW_MEM_START = kPageSize * 2;
+
+uintptr_t MemMap::next_mem_pos_ = LOW_MEM_START;   // first page to check for low-mem extent
 #endif
 
 static bool CheckMapRequest(byte* expected_ptr, void* actual_ptr, size_t byte_count,
@@ -133,7 +136,22 @@
   if (low_4gb && expected == nullptr) {
     flags |= MAP_FIXED;
 
+    bool first_run = true;
+
     for (uintptr_t ptr = next_mem_pos_; ptr < 4 * GB; ptr += kPageSize) {
+      if (4U * GB - ptr < page_aligned_byte_count) {
+        // Not enough memory until 4GB.
+        if (first_run) {
+          // Try another time from the bottom;
+          next_mem_pos_ = LOW_MEM_START;
+          first_run = false;
+          continue;
+        } else {
+          // Second try failed.
+          break;
+        }
+      }
+
       uintptr_t tail_ptr;
 
       // Check pages are free.