diff options
author | 2015-08-31 17:10:05 -0700 | |
---|---|---|
committer | 2015-09-01 23:30:00 +0000 | |
commit | db00eaf64e94ab1b4289952699c3b81f73ca406a (patch) | |
tree | f1014a0d1a36a9af529b8039423e0b8329a21fdf | |
parent | 4bc27eb21222cd9d0fd680442d34185e42ae4373 (diff) |
Add GC coverage test for moving GC
Adds testing coverage for collector transitions and homogeneous space
compaction.
Bug: 10808403
Change-Id: Ia79fecb47c33fc95d940243d6cb1068e9ee9dc9a
-rw-r--r-- | runtime/gc/heap.cc | 10 | ||||
-rw-r--r-- | runtime/gc/heap.h | 9 | ||||
-rwxr-xr-x | test/1337-gc-coverage/check | 22 | ||||
-rw-r--r-- | test/1337-gc-coverage/expected.txt | 0 | ||||
-rw-r--r-- | test/1337-gc-coverage/gc_coverage.cc | 64 | ||||
-rw-r--r-- | test/1337-gc-coverage/info.txt | 1 | ||||
-rw-r--r-- | test/1337-gc-coverage/src/Main.java | 107 | ||||
-rw-r--r-- | test/Android.libarttest.mk | 1 |
8 files changed, 210 insertions, 4 deletions
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index aec8d631f4..4bc44d3fd9 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -1900,6 +1900,11 @@ void Heap::CollectGarbage(bool clear_soft_references) { CollectGarbageInternal(gc_plan_.back(), kGcCauseExplicit, clear_soft_references); } +bool Heap::SupportHomogeneousSpaceCompactAndCollectorTransitions() const { + return main_space_backup_.get() != nullptr && main_space_ != nullptr && + foreground_collector_type_ == kCollectorTypeCMS; +} + HomogeneousSpaceCompactResult Heap::PerformHomogeneousSpaceCompact() { Thread* self = Thread::Current(); // Inc requested homogeneous space compaction. @@ -1919,7 +1924,10 @@ HomogeneousSpaceCompactResult Heap::PerformHomogeneousSpaceCompact() { // exit. if (disable_moving_gc_count_ != 0 || IsMovingGc(collector_type_) || !main_space_->CanMoveObjects()) { - return HomogeneousSpaceCompactResult::kErrorReject; + return kErrorReject; + } + if (!SupportHomogeneousSpaceCompactAndCollectorTransitions()) { + return kErrorUnsupported; } collector_type_running_ = kCollectorTypeHomogeneousSpaceCompact; } diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 85688ae3ee..8bffe5e6e9 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -105,6 +105,8 @@ enum HomogeneousSpaceCompactResult { kSuccess, // Reject due to disabled moving GC. kErrorReject, + // Unsupported due to the current configuration. + kErrorUnsupported, // System is shutting down. kErrorVMShuttingDown, }; @@ -753,6 +755,10 @@ class Heap { void DisableGCForShutdown() REQUIRES(!*gc_complete_lock_); + // Create a new alloc space and compact default alloc space to it. + HomogeneousSpaceCompactResult PerformHomogeneousSpaceCompact() REQUIRES(!*gc_complete_lock_); + bool SupportHomogeneousSpaceCompactAndCollectorTransitions() const; + private: class ConcurrentGCTask; class CollectorTransitionTask; @@ -905,9 +911,6 @@ class Heap { // Find a collector based on GC type. collector::GarbageCollector* FindCollectorByGcType(collector::GcType gc_type); - // Create a new alloc space and compact default alloc space to it. - HomogeneousSpaceCompactResult PerformHomogeneousSpaceCompact() REQUIRES(!*gc_complete_lock_); - // Create the main free list malloc space, either a RosAlloc space or DlMalloc space. void CreateMainMallocSpace(MemMap* mem_map, size_t initial_size, diff --git a/test/1337-gc-coverage/check b/test/1337-gc-coverage/check new file mode 100755 index 0000000000..842bdc6ae8 --- /dev/null +++ b/test/1337-gc-coverage/check @@ -0,0 +1,22 @@ +#!/bin/bash +# +# Copyright (C) 2015 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Check that the string "error" isn't present +if grep error "$2"; then + exit 1 +else + exit 0 +fi diff --git a/test/1337-gc-coverage/expected.txt b/test/1337-gc-coverage/expected.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/1337-gc-coverage/expected.txt diff --git a/test/1337-gc-coverage/gc_coverage.cc b/test/1337-gc-coverage/gc_coverage.cc new file mode 100644 index 0000000000..7cf30bd5b9 --- /dev/null +++ b/test/1337-gc-coverage/gc_coverage.cc @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gc/heap.h" +#include "jni.h" +#include "runtime.h" +#include "scoped_thread_state_change.h" +#include "thread-inl.h" + +namespace art { +namespace { + +extern "C" JNIEXPORT jboolean JNICALL Java_Main_performHomogeneousSpaceCompact(JNIEnv*, jclass) { + return Runtime::Current()->GetHeap()->PerformHomogeneousSpaceCompact() == gc::kSuccess ? + JNI_TRUE : JNI_FALSE; +} + +extern "C" JNIEXPORT jboolean JNICALL Java_Main_supportHomogeneousSpaceCompact(JNIEnv*, jclass) { + return Runtime::Current()->GetHeap()->SupportHomogeneousSpaceCompactAndCollectorTransitions() ? + JNI_TRUE : JNI_FALSE; +} + +extern "C" JNIEXPORT void JNICALL Java_Main_incrementDisableMovingGC(JNIEnv*, jclass) { + Runtime::Current()->GetHeap()->IncrementDisableMovingGC(Thread::Current()); +} + +extern "C" JNIEXPORT void JNICALL Java_Main_decrementDisableMovingGC(JNIEnv*, jclass) { + Runtime::Current()->GetHeap()->DecrementDisableMovingGC(Thread::Current()); +} + +extern "C" JNIEXPORT jlong JNICALL Java_Main_objectAddress(JNIEnv* env, jclass, jobject object) { + ScopedObjectAccess soa(env); + return reinterpret_cast<jlong>(soa.Decode<mirror::Object*>(object)); +} + +extern "C" JNIEXPORT jboolean JNICALL Java_Main_supportCollectorTransition(JNIEnv*, jclass) { + // Same as supportHomogeneousSpaceCompact for now. + return Runtime::Current()->GetHeap()->SupportHomogeneousSpaceCompactAndCollectorTransitions() ? + JNI_TRUE : JNI_FALSE; +} + +extern "C" JNIEXPORT void JNICALL Java_Main_transitionToSS(JNIEnv*, jclass) { + Runtime::Current()->GetHeap()->TransitionCollector(gc::kCollectorTypeSS); +} + +extern "C" JNIEXPORT void JNICALL Java_Main_transitionToCMS(JNIEnv*, jclass) { + Runtime::Current()->GetHeap()->TransitionCollector(gc::kCollectorTypeCMS); +} + +} // namespace +} // namespace art diff --git a/test/1337-gc-coverage/info.txt b/test/1337-gc-coverage/info.txt new file mode 100644 index 0000000000..7e3acd3a8f --- /dev/null +++ b/test/1337-gc-coverage/info.txt @@ -0,0 +1 @@ +Tests internal GC functions which are not exposed through normal APIs.
\ No newline at end of file diff --git a/test/1337-gc-coverage/src/Main.java b/test/1337-gc-coverage/src/Main.java new file mode 100644 index 0000000000..7875eb1824 --- /dev/null +++ b/test/1337-gc-coverage/src/Main.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.TreeMap; + +public class Main { + private static TreeMap treeMap = new TreeMap(); + + public static void main(String[] args) { + System.loadLibrary(args[0]); + testHomogeneousCompaction(); + testCollectorTransitions(); + System.out.println("Done."); + } + + private static void allocateStuff() { + for (int i = 0; i < 1000; ++i) { + Object o = new Object(); + treeMap.put(o.hashCode(), o); + } + } + + public static void testHomogeneousCompaction() { + System.out.println("Attempting homogeneous compaction"); + final boolean supportHSC = supportHomogeneousSpaceCompact(); + Object o = new Object(); + long addressBefore = objectAddress(o); + long addressAfter; + allocateStuff(); + final boolean success = performHomogeneousSpaceCompact(); + allocateStuff(); + System.out.println("Homogeneous compaction support=" + supportHSC + " success=" + success); + if (supportHSC != success) { + System.out.println("error: Expected " + supportHSC + " but got " + success); + } + if (success) { + allocateStuff(); + addressAfter = objectAddress(o); + // This relies on the compaction copying from one space to another space and there being no + // overlap. + if (addressBefore == addressAfter) { + System.out.println("error: Expected different adddress " + addressBefore + " vs " + + addressAfter); + } + } + if (supportHSC) { + incrementDisableMovingGC(); + if (performHomogeneousSpaceCompact()) { + System.out.println("error: Compaction succeeded when moving GC is disabled"); + } + decrementDisableMovingGC(); + if (!performHomogeneousSpaceCompact()) { + System.out.println("error: Compaction failed when moving GC is enabled"); + } + } + } + + private static void testCollectorTransitions() { + if (supportCollectorTransition()) { + Object o = new Object(); + // Transition to semi-space collector. + allocateStuff(); + transitionToSS(); + allocateStuff(); + long addressBefore = objectAddress(o); + Runtime.getRuntime().gc(); + long addressAfter = objectAddress(o); + if (addressBefore == addressAfter) { + System.out.println("error: Expected different adddress " + addressBefore + " vs " + + addressAfter); + } + // Transition back to CMS. + transitionToCMS(); + allocateStuff(); + addressBefore = objectAddress(o); + Runtime.getRuntime().gc(); + addressAfter = objectAddress(o); + if (addressBefore != addressAfter) { + System.out.println("error: Expected same adddress " + addressBefore + " vs " + + addressAfter); + } + } + } + + // Methods to get access to ART internals. + private static native boolean supportHomogeneousSpaceCompact(); + private static native boolean performHomogeneousSpaceCompact(); + private static native void incrementDisableMovingGC(); + private static native void decrementDisableMovingGC(); + private static native long objectAddress(Object object); + private static native boolean supportCollectorTransition(); + private static native void transitionToSS(); + private static native void transitionToCMS(); +} diff --git a/test/Android.libarttest.mk b/test/Android.libarttest.mk index 82f8c79512..e51e44416b 100644 --- a/test/Android.libarttest.mk +++ b/test/Android.libarttest.mk @@ -29,6 +29,7 @@ LIBARTTEST_COMMON_SRC_FILES := \ 116-nodex2oat/nodex2oat.cc \ 117-nopatchoat/nopatchoat.cc \ 118-noimage-dex2oat/noimage-dex2oat.cc \ + 1337-gc-coverage/gc_coverage.cc \ 137-cfi/cfi.cc \ 139-register-natives/regnative.cc \ 454-get-vreg/get_vreg_jni.cc \ |