Optimize access to gPageSize
This change refactors the global constants dependent on gPageSize in
a way that gPageSize and dependent constants are now internal to the
runtime. Also it removes static initialization dependency on gPageSize
and disallows accessing gPageSize during the static initialization
phase. Consequently, this removes a need in the condition check when
accessing gPageSize and allows compiler to recognise the value as
a constant that can be cached where used repeatedly.
From this point, gPageSize should only be used within libart. For most
of the other cases MemMap::GetPageSize() should be used. Where MemMap
is unavailable e.g. during static initialization or another stage when
MemMap isn't yet initialized, or in a component which might operate
without MemMap being initialized, the GetPageSizeSlow() would be
generally suitable. For performance-sensitive code, GetPageSizeSlow()
shouldn't be used without caching the value to remove repeated calls
of the function.
- The gPageSize constant is now local to libart. Access to the variable
is disallowed until Runtime is initialized, so removing the chance of
static initialization order issue related to this value.
The initializers for the other constants with initialization
that used to depend on the gPageSize value are now referring to
GetPageSizeSlow instead, so removing the static initialization
dependency, and consequently, possible order issues.
This removes the condition check upon each load of the gPageSize.
Also as the variable is defined with "hidden" visibility, it isn't
exported and so is unavailable to other DSOs.
This also removes one indirection level in accessing it as GOT lookup
is not required anymore.
- Remove gPMDSize and gPUDSize from libartbase
Move the constants to gc::Heap in form of functions computing their
values. Also move the BestPageTableAlignment function dependent on
the values, as it is only used within the GC.
Direct accesses to gPMDSize are only performed for assertions and so
replacing that with a function call shouldn't matter for performance.
gPUDSize isn't accessed directly.
The rest the values accesses are done via BestPageTableAlignment,
which is called from:
- MarkCompact constructor
- MarkCompact::AddLinearAllocSpaceData
- GcVisitedArenaPool::AddMap
In all cases, it's performed in conjunction with MapAnonymousAligned,
which involves an mmap system call. The potential slight slowdown
in BestPageTableAlignment - due to the dynamic computation of the
gPMDSize and gPUDSize values - is expected to be negligible in
comparison to the performance cost of mmap system call.
- Move gPageSize declaration and definition to the runtime / component
Replace the removed uses of gPageSize outside libart with
MemMap::GetPageSize() / GetPageSizeSlow().
There is one exception to the above statement in this change - in
FdFile, where the page size appears to be used arbitrarily to compute
the maximum buffer size: in that case replace the maximum buffer size
with a constant which would have matched the value when the page size
is 4K.
- Make gNumLrtSlots a member variable
The gNumLrtSlots global is only used within the SmallLrtAllocator
class. Move it inside the class as a member variable.
- Remove gStackOverflowProtectedSize global
Value of the gStackOverflowProtectedSize is computed as a page size
multiplied by a constant dependent on whether the address sanitizer
is enabled. If address sanitizer is disabled, the constant is 1,
in which case gStackOverflowProtectedSize is equal to the page size.
Replace the global with an always-inlined function which is expected
to expand into a simple reference to the gPageSize at each call site
if the address sanitizer is not enabled.
- Remove ART_PAGE_SIZE_AGNOSTIC_DECLARE_* macros
The macros aren't used anymore. Remove them and GlobalConst.
The tests were run for legacy 4K, page size agnostic 4K and 16K.
Co-authored-by: Ruben Ayrapetyan <ruben.ayrapetyan@arm.com>
Co-authored-by: Richard Neill <richard.neill@arm.com>
Test: art/tools/run-gtests.sh
Test: art/test/testrunner/testrunner.py --target --64
Test: art/tools/run-libcore-tests.sh --mode=device --variant=X64
Test: art/tools/run-libjdwp-tests.sh --mode=device --variant=X64
Test: cd art && mma
Change-Id: I07fd85cd35dd443dee5cff0f7435ab47ba727c6f
diff --git a/dex2oat/utils/swap_space.cc b/dex2oat/utils/swap_space.cc
index 336aad8..b0686a4 100644
--- a/dex2oat/utils/swap_space.cc
+++ b/dex2oat/utils/swap_space.cc
@@ -22,6 +22,7 @@
#include <numeric>
#include "base/bit_utils.h"
+#include "base/mem_map.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "thread-current-inl.h"
@@ -146,7 +147,8 @@
SwapSpace::SpaceChunk SwapSpace::NewFileChunk(size_t min_size) {
#if !defined(__APPLE__)
- size_t next_part = std::max(RoundUp(min_size, gPageSize), RoundUp(kMinimumMapSize, gPageSize));
+ const size_t page_size = MemMap::GetPageSize();
+ size_t next_part = std::max(RoundUp(min_size, page_size), RoundUp(kMinimumMapSize, page_size));
int result = TEMP_FAILURE_RETRY(ftruncate64(fd_, size_ + next_part));
if (result != 0) {
PLOG(FATAL) << "Unable to increase swap file.";