summaryrefslogtreecommitdiff
path: root/runtime/intern_table_test.cc
diff options
context:
space:
mode:
author Alexey Grebenkin <a.grebenkin@partner.samsung.com> 2016-12-02 17:44:54 +0300
committer Artem Udovichenko <artem.u@samsung.com> 2016-12-20 16:53:03 +0300
commit21f2364f11a709c7c22320588abe2adc91c69b6a (patch)
tree9c0404499b37dcf5cae6d982b6e65c925e57f772 /runtime/intern_table_test.cc
parent06ce6d4359ed897f1d1b39be4e748f0c4f3ca2ff (diff)
Fix incorrect string hash value extension during cross-compilation.
Previouly, having a 32-bit Android device and a 64-bit host to compile boot.oat could lead to an interning table be fulfilled using one hash function and be worked with using another hash function (which is caused by sign extension). Target case is any string with a negative .GetHashCode(). Test: test-art-host-gtest-intern_table_test Change-Id: I3f417e1ac990ef681f0651160292130e9b3632f0
Diffstat (limited to 'runtime/intern_table_test.cc')
-rw-r--r--runtime/intern_table_test.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/runtime/intern_table_test.cc b/runtime/intern_table_test.cc
index b91d946095..3991d6550d 100644
--- a/runtime/intern_table_test.cc
+++ b/runtime/intern_table_test.cc
@@ -16,6 +16,7 @@
#include "intern_table.h"
+#include "base/hash_set.h"
#include "common_runtime_test.h"
#include "mirror/object.h"
#include "handle_scope-inl.h"
@@ -62,6 +63,25 @@ TEST_F(InternTableTest, Size) {
EXPECT_EQ(2U, t.Size());
}
+// Check if table indexes match on 64 and 32 bit machines.
+// This is done by ensuring hash values are the same on every machine and limited to 32-bit wide.
+// Otherwise cross compilation can cause a table to be filled on host using one indexing algorithm
+// and later on a device with different sizeof(size_t) can use another indexing algorithm.
+// Thus the table may provide wrong data.
+TEST_F(InternTableTest, CrossHash) {
+ ScopedObjectAccess soa(Thread::Current());
+ InternTable t;
+
+ // A string that has a negative hash value.
+ GcRoot<mirror::String> str(mirror::String::AllocFromModifiedUtf8(soa.Self(), "00000000"));
+
+ MutexLock mu(Thread::Current(), *Locks::intern_table_lock_);
+ for (InternTable::Table::UnorderedSet& table : t.strong_interns_.tables_) {
+ // The negative hash value shall be 32-bit wide on every host.
+ ASSERT_TRUE(IsUint<32>(table.hashfn_(str)));
+ }
+}
+
class TestPredicate : public IsMarkedVisitor {
public:
mirror::Object* IsMarked(mirror::Object* s) OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_) {