summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2018-10-01 13:21:47 -0700
committer Alex Light <allight@google.com> 2018-10-01 14:57:18 -0700
commitbb68fda18ef3d7ea183a322831a5afd20b6a8bff (patch)
tree5745a64e0e410ac3fe66cd54abd2bbfb84539e93
parent29391756f70489a5ab659988f058e359527a7af1 (diff)
Move InterpreterCache to right below tlsPtr_
Change the position of the InterpreterCache field in Thread to be directly below the tlsPtr_ field. Since both members of the tlsPtr_ and InterpreterCache fields are used by asm_code we need their offsets in asm_support.h. The fields at the end of the Thread struct have been undergoing changes. By moving this field up we avoid the need to update asm_support.h whenever one of the fields is modified. Test: ./test.py --host Change-Id: Ic2863116ed446af155badfc3bf098add7ba0b699
-rw-r--r--runtime/asm_support.h11
-rw-r--r--runtime/entrypoints_order_test.cc7
-rw-r--r--runtime/thread.h13
3 files changed, 22 insertions, 9 deletions
diff --git a/runtime/asm_support.h b/runtime/asm_support.h
index 00c9360ba4..a9c743a5bf 100644
--- a/runtime/asm_support.h
+++ b/runtime/asm_support.h
@@ -27,6 +27,9 @@
#define ADD_TEST_EQ(x, y)
#endif
+// Rounds the value n up to the nearest multiple of sz. sz must be a multiple of two.
+#define ALIGN_UP(n, sz) (((n) + (sz - 1)) & ~((sz) - 1))
+
#if defined(__LP64__)
#define POINTER_SIZE_SHIFT 3
#define POINTER_SIZE art::PointerSize::k64
@@ -96,8 +99,10 @@ ADD_TEST_EQ(THREAD_LOCAL_ALLOC_STACK_TOP_OFFSET,
#define THREAD_LOCAL_ALLOC_STACK_END_OFFSET (THREAD_ROSALLOC_RUNS_OFFSET + 17 * __SIZEOF_POINTER__)
ADD_TEST_EQ(THREAD_LOCAL_ALLOC_STACK_END_OFFSET,
art::Thread::ThreadLocalAllocStackEndOffset<POINTER_SIZE>().Int32Value())
-// Offset of field Thread::interpreter_cache_.
-#define THREAD_INTERPRETER_CACHE_OFFSET (144 + 312 * __SIZEOF_POINTER__)
+// Offset of field Thread::interpreter_cache_. This is aligned on a 16 byte boundary so we need to
+// round up depending on the size of tlsPtr_.
+#define THREAD_INTERPRETER_CACHE_OFFSET \
+ (ALIGN_UP((THREAD_CARD_TABLE_OFFSET + 301 * __SIZEOF_POINTER__), 16))
ADD_TEST_EQ(THREAD_INTERPRETER_CACHE_OFFSET,
art::Thread::InterpreterCacheOffset<POINTER_SIZE>().Int32Value())
@@ -227,4 +232,6 @@ ADD_TEST_EQ(STRING_COMPRESSION_FEATURE, art::mirror::kUseStringCompression);
#undef DEFINED_ADD_TEST_EQ
#endif
+#undef ALIGN_UP
+
#endif // ART_RUNTIME_ASM_SUPPORT_H_
diff --git a/runtime/entrypoints_order_test.cc b/runtime/entrypoints_order_test.cc
index cb85804986..50c65ea505 100644
--- a/runtime/entrypoints_order_test.cc
+++ b/runtime/entrypoints_order_test.cc
@@ -140,8 +140,11 @@ class EntrypointsOrderTest : public CommonRuntimeTest {
EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, flip_function, method_verifier, sizeof(void*));
EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, method_verifier, thread_local_mark_stack, sizeof(void*));
EXPECT_OFFSET_DIFFP(Thread, tlsPtr_, thread_local_mark_stack, async_exception, sizeof(void*));
- EXPECT_OFFSET_DIFF(Thread, tlsPtr_.async_exception, Thread, wait_mutex_, sizeof(void*),
- thread_tlsptr_end);
+ // The first field after tlsPtr_ is forced to a 16 byte alignment so it might have some space.
+ auto offset_tlsptr_end = OFFSETOF_MEMBER(Thread, tlsPtr_) +
+ sizeof(decltype(reinterpret_cast<Thread*>(16)->tlsPtr_));
+ CHECKED(offset_tlsptr_end - OFFSETOF_MEMBER(Thread, tlsPtr_.async_exception) == sizeof(void*),
+ "async_exception last field");
}
void CheckJniEntryPoints() {
diff --git a/runtime/thread.h b/runtime/thread.h
index 3c85b80976..aaf6bae36f 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -1783,6 +1783,14 @@ class Thread {
mirror::Throwable* async_exception;
} tlsPtr_;
+ // Small thread-local cache to be used from the interpreter.
+ // It is keyed by dex instruction pointer.
+ // The value is opcode-depended (e.g. field offset).
+ InterpreterCache interpreter_cache_;
+
+ // All fields below this line should not be accessed by native code. This means these fields can
+ // be modified, rearranged, added or removed without having to modify asm_support.h
+
// Guards the 'wait_monitor_' members.
Mutex* wait_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER;
@@ -1812,11 +1820,6 @@ class Thread {
// be false for threads where '!can_call_into_java_'.
bool can_be_suspended_by_user_code_;
- // Small thread-local cache to be used from the interpreter.
- // It is keyed by dex instruction pointer.
- // The value is opcode-depended (e.g. field offset).
- InterpreterCache interpreter_cache_;
-
friend class Dbg; // For SetStateUnsafe.
friend class gc::collector::SemiSpace; // For getting stack traces.
friend class Runtime; // For CreatePeer.