summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TEST_MAPPING102
-rw-r--r--compiler/art_standalone_compiler_tests.xml10
-rw-r--r--compiler/optimizing/execution_subgraph.cc13
-rw-r--r--dex2oat/art_standalone_dex2oat_tests.xml54
-rw-r--r--dexoptanalyzer/art_standalone_dexoptanalyzer_tests.xml22
-rw-r--r--libartbase/base/memfd.h4
-rw-r--r--libartpalette/apex/palette.cc24
-rw-r--r--libartpalette/include/palette/palette_method_list.h10
-rw-r--r--libartpalette/libartpalette.map.txt1
-rw-r--r--libartpalette/system/palette_fake.cc13
-rw-r--r--libdexfile/Android.bp17
-rw-r--r--libdexfile/art_standalone_libdexfile_tests.xml14
-rw-r--r--libdexfile/dex/dex_file.h2
-rw-r--r--libprofile/art_standalone_libprofile_tests.xml10
-rw-r--r--oatdump/art_standalone_oatdump_tests.xml6
-rw-r--r--openjdkjvm/OpenjdkJvm.cc1
-rw-r--r--openjdkjvmti/ti_thread.cc1
-rw-r--r--profman/art_standalone_profman_tests.xml6
-rw-r--r--runtime/art_standalone_runtime_compiler_tests.xml10
-rw-r--r--runtime/art_standalone_runtime_tests.xml78
-rw-r--r--runtime/class_linker.cc159
-rw-r--r--runtime/class_linker.h20
-rw-r--r--runtime/gc/collector/concurrent_copying.cc50
-rw-r--r--runtime/jit/jit.cc3
-rw-r--r--runtime/jit/profile_saver.cc2
-rw-r--r--runtime/monitor_android.cc40
-rw-r--r--runtime/native/dalvik_system_VMStack.cc1
-rw-r--r--runtime/native/java_lang_Thread.cc1
-rw-r--r--runtime/oat_file.cc110
-rw-r--r--runtime/runtime.cc4
-rw-r--r--runtime/runtime.h14
-rw-r--r--runtime/thread.cc6
-rw-r--r--runtime/thread.h5
-rw-r--r--runtime/thread_list.cc30
-rw-r--r--runtime/thread_list.h5
-rw-r--r--runtime/vdex_file.cc3
-rw-r--r--runtime/vdex_file.h5
-rw-r--r--sigchainlib/sigchain.cc2
-rw-r--r--test/2011-stack-walk-concurrent-instrument/stack_walk_concurrent.cc2
-rw-r--r--test/826-infinite-loop/expected-stderr.txt0
-rw-r--r--test/826-infinite-loop/expected-stdout.txt0
-rw-r--r--test/826-infinite-loop/info.txt2
-rw-r--r--test/826-infinite-loop/src/Main.java26
-rw-r--r--test/831-unverified-bcp/expected-stderr.txt0
-rw-r--r--test/831-unverified-bcp/expected-stdout.txt1
-rw-r--r--test/831-unverified-bcp/info.txt2
-rw-r--r--test/831-unverified-bcp/smali-ex/NonVerifiedClass.smali23
-rw-r--r--test/831-unverified-bcp/src/Main.java46
-rw-r--r--test/art-gtests-target-standalone-template.xml4
-rw-r--r--test/knownfailures.json1
-rwxr-xr-xtest/utils/regen-test-files53
51 files changed, 737 insertions, 281 deletions
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 2d46a53fe1..3c07c656b4 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1128,6 +1128,57 @@
},
{
"name": "art-run-test-963-default-range-smali[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_cmdline_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_compiler_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_dex2oat_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_dexdump_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_dexlist_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_dexoptanalyzer_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_libartbase_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_libartpalette_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_libdexfile_support_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_libdexfile_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_libprofile_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_oatdump_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_odrefresh_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_profman_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_runtime_compiler_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_runtime_tests[com.google.android.art.apex]"
+ },
+ {
+ "name": "art_standalone_sigchain_tests[com.google.android.art.apex]"
}
],
"presubmit": [
@@ -2264,6 +2315,57 @@
},
{
"name": "art-run-test-963-default-range-smali"
+ },
+ {
+ "name": "art_standalone_cmdline_tests"
+ },
+ {
+ "name": "art_standalone_compiler_tests"
+ },
+ {
+ "name": "art_standalone_dex2oat_tests"
+ },
+ {
+ "name": "art_standalone_dexdump_tests"
+ },
+ {
+ "name": "art_standalone_dexlist_tests"
+ },
+ {
+ "name": "art_standalone_dexoptanalyzer_tests"
+ },
+ {
+ "name": "art_standalone_libartbase_tests"
+ },
+ {
+ "name": "art_standalone_libartpalette_tests"
+ },
+ {
+ "name": "art_standalone_libdexfile_support_tests"
+ },
+ {
+ "name": "art_standalone_libdexfile_tests"
+ },
+ {
+ "name": "art_standalone_libprofile_tests"
+ },
+ {
+ "name": "art_standalone_oatdump_tests"
+ },
+ {
+ "name": "art_standalone_odrefresh_tests"
+ },
+ {
+ "name": "art_standalone_profman_tests"
+ },
+ {
+ "name": "art_standalone_runtime_compiler_tests"
+ },
+ {
+ "name": "art_standalone_runtime_tests"
+ },
+ {
+ "name": "art_standalone_sigchain_tests"
}
]
}
diff --git a/compiler/art_standalone_compiler_tests.xml b/compiler/art_standalone_compiler_tests.xml
index 4137a183c3..4cf6e3d514 100644
--- a/compiler/art_standalone_compiler_tests.xml
+++ b/compiler/art_standalone_compiler_tests.xml
@@ -16,19 +16,19 @@
<configuration description="Runs art_standalone_compiler_tests.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_compiler_tests->/data/local/tmp/nativetest/art_standalone_compiler_tests" />
+ <option name="push" value="art_standalone_compiler_tests->/data/local/tmp/art_standalone_compiler_tests/art_standalone_compiler_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-ExceptionHandle.jar->/data/local/tmp/nativetest/art-gtest-jars-ExceptionHandle.jar" />
- <option name="push" value="art-gtest-jars-Interfaces.jar->/data/local/tmp/nativetest/art-gtest-jars-Interfaces.jar" />
- <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/nativetest/art-gtest-jars-MyClassNatives.jar" />
+ <option name="push" value="art-gtest-jars-ExceptionHandle.jar->/data/local/tmp/art_standalone_compiler_tests/art-gtest-jars-ExceptionHandle.jar" />
+ <option name="push" value="art-gtest-jars-Interfaces.jar->/data/local/tmp/art_standalone_compiler_tests/art-gtest-jars-Interfaces.jar" />
+ <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/art_standalone_compiler_tests/art-gtest-jars-MyClassNatives.jar" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_compiler_tests" />
<option name="module-name" value="art_standalone_compiler_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/compiler/optimizing/execution_subgraph.cc b/compiler/optimizing/execution_subgraph.cc
index 6d105668c0..66fdfcda5b 100644
--- a/compiler/optimizing/execution_subgraph.cc
+++ b/compiler/optimizing/execution_subgraph.cc
@@ -86,12 +86,6 @@ void ExecutionSubgraph::Prune() {
ScopedArenaVector<std::bitset<kMaxFilterableSuccessors>> results(
graph_->GetBlocks().size(), temporaries.Adapter(kArenaAllocLSA));
unreachable_blocks_.ClearAllBits();
- // TODO We should support infinite loops as well.
- if (UNLIKELY(graph_->GetExitBlock() == nullptr)) {
- // Infinite loop
- valid_ = false;
- return;
- }
// Fills up the 'results' map with what we need to add to update
// allowed_successors in order to prune sink nodes.
bool start_reaches_end = false;
@@ -170,8 +164,11 @@ void ExecutionSubgraph::Prune() {
<< "current path size: " << current_path.size()
<< " cur_block id: " << cur_block->GetBlockId() << " entry id "
<< graph_->GetEntryBlock()->GetBlockId();
- DCHECK(!visiting.IsBitSet(id))
- << "Somehow ended up in a loop! This should have been caught before now! " << id;
+ if (visiting.IsBitSet(id)) {
+ // TODO We should support infinite loops as well.
+ start_reaches_end = false;
+ break;
+ }
std::bitset<kMaxFilterableSuccessors>& result = results[id];
if (cur_block == graph_->GetExitBlock()) {
start_reaches_end = true;
diff --git a/dex2oat/art_standalone_dex2oat_tests.xml b/dex2oat/art_standalone_dex2oat_tests.xml
index ce429453c8..8f9689afd0 100644
--- a/dex2oat/art_standalone_dex2oat_tests.xml
+++ b/dex2oat/art_standalone_dex2oat_tests.xml
@@ -16,41 +16,41 @@
<configuration description="Runs art_standalone_dex2oat_tests.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_dex2oat_tests->/data/local/tmp/nativetest/art_standalone_dex2oat_tests" />
+ <option name="push" value="art_standalone_dex2oat_tests->/data/local/tmp/art_standalone_dex2oat_tests/art_standalone_dex2oat_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-AbstractMethod.jar->/data/local/tmp/nativetest/art-gtest-jars-AbstractMethod.jar" />
- <option name="push" value="art-gtest-jars-DefaultMethods.jar->/data/local/tmp/nativetest/art-gtest-jars-DefaultMethods.jar" />
- <option name="push" value="art-gtest-jars-DexToDexDecompiler.jar->/data/local/tmp/nativetest/art-gtest-jars-DexToDexDecompiler.jar" />
- <option name="push" value="art-gtest-jars-Dex2oatVdexPublicSdkDex.dex->/data/local/tmp/nativetest/art-gtest-jars-Dex2oatVdexPublicSdkDex.dex" />
- <option name="push" value="art-gtest-jars-Dex2oatVdexTestDex.jar->/data/local/tmp/nativetest/art-gtest-jars-Dex2oatVdexTestDex.jar" />
- <option name="push" value="art-gtest-jars-ImageLayoutA.jar->/data/local/tmp/nativetest/art-gtest-jars-ImageLayoutA.jar" />
- <option name="push" value="art-gtest-jars-ImageLayoutB.jar->/data/local/tmp/nativetest/art-gtest-jars-ImageLayoutB.jar" />
- <option name="push" value="art-gtest-jars-LinkageTest.dex->/data/local/tmp/nativetest/art-gtest-jars-LinkageTest.dex" />
- <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/nativetest/art-gtest-jars-Main.jar" />
- <option name="push" value="art-gtest-jars-MainEmptyUncompressed.jar->/data/local/tmp/nativetest/art-gtest-jars-MainEmptyUncompressed.jar" />
- <option name="push" value="art-gtest-jars-MainEmptyUncompressedAligned.jar->/data/local/tmp/nativetest/art-gtest-jars-MainEmptyUncompressedAligned.jar" />
- <option name="push" value="art-gtest-jars-MainStripped.jar->/data/local/tmp/nativetest/art-gtest-jars-MainStripped.jar" />
- <option name="push" value="art-gtest-jars-MainUncompressedAligned.jar->/data/local/tmp/nativetest/art-gtest-jars-MainUncompressedAligned.jar" />
- <option name="push" value="art-gtest-jars-ManyMethods.jar->/data/local/tmp/nativetest/art-gtest-jars-ManyMethods.jar" />
- <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDex.jar" />
- <option name="push" value="art-gtest-jars-MultiDexModifiedSecondary.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDexModifiedSecondary.jar" />
- <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/nativetest/art-gtest-jars-MyClassNatives.jar" />
- <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/nativetest/art-gtest-jars-Nested.jar" />
- <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-ProfileTestMultiDex.jar" />
- <option name="push" value="art-gtest-jars-StaticLeafMethods.jar->/data/local/tmp/nativetest/art-gtest-jars-StaticLeafMethods.jar" />
- <option name="push" value="art-gtest-jars-Statics.jar->/data/local/tmp/nativetest/art-gtest-jars-Statics.jar" />
- <option name="push" value="art-gtest-jars-StringLiterals.jar->/data/local/tmp/nativetest/art-gtest-jars-StringLiterals.jar" />
- <option name="push" value="art-gtest-jars-VerifierDeps.dex->/data/local/tmp/nativetest/art-gtest-jars-VerifierDeps.dex" />
- <option name="push" value="art-gtest-jars-VerifierDepsMulti.dex->/data/local/tmp/nativetest/art-gtest-jars-VerifierDepsMulti.dex" />
- <option name="push" value="art-gtest-jars-VerifySoftFailDuringClinit.dex->/data/local/tmp/nativetest/art-gtest-jars-VerifySoftFailDuringClinit.dex" />
+ <option name="push" value="art-gtest-jars-AbstractMethod.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-AbstractMethod.jar" />
+ <option name="push" value="art-gtest-jars-DefaultMethods.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-DefaultMethods.jar" />
+ <option name="push" value="art-gtest-jars-DexToDexDecompiler.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-DexToDexDecompiler.jar" />
+ <option name="push" value="art-gtest-jars-Dex2oatVdexPublicSdkDex.dex->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-Dex2oatVdexPublicSdkDex.dex" />
+ <option name="push" value="art-gtest-jars-Dex2oatVdexTestDex.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-Dex2oatVdexTestDex.jar" />
+ <option name="push" value="art-gtest-jars-ImageLayoutA.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-ImageLayoutA.jar" />
+ <option name="push" value="art-gtest-jars-ImageLayoutB.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-ImageLayoutB.jar" />
+ <option name="push" value="art-gtest-jars-LinkageTest.dex->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-LinkageTest.dex" />
+ <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-Main.jar" />
+ <option name="push" value="art-gtest-jars-MainEmptyUncompressed.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-MainEmptyUncompressed.jar" />
+ <option name="push" value="art-gtest-jars-MainEmptyUncompressedAligned.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-MainEmptyUncompressedAligned.jar" />
+ <option name="push" value="art-gtest-jars-MainStripped.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-MainStripped.jar" />
+ <option name="push" value="art-gtest-jars-MainUncompressedAligned.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-MainUncompressedAligned.jar" />
+ <option name="push" value="art-gtest-jars-ManyMethods.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-ManyMethods.jar" />
+ <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-MultiDex.jar" />
+ <option name="push" value="art-gtest-jars-MultiDexModifiedSecondary.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-MultiDexModifiedSecondary.jar" />
+ <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-MyClassNatives.jar" />
+ <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-Nested.jar" />
+ <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-ProfileTestMultiDex.jar" />
+ <option name="push" value="art-gtest-jars-StaticLeafMethods.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-StaticLeafMethods.jar" />
+ <option name="push" value="art-gtest-jars-Statics.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-Statics.jar" />
+ <option name="push" value="art-gtest-jars-StringLiterals.jar->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-StringLiterals.jar" />
+ <option name="push" value="art-gtest-jars-VerifierDeps.dex->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-VerifierDeps.dex" />
+ <option name="push" value="art-gtest-jars-VerifierDepsMulti.dex->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-VerifierDepsMulti.dex" />
+ <option name="push" value="art-gtest-jars-VerifySoftFailDuringClinit.dex->/data/local/tmp/art_standalone_dex2oat_tests/art-gtest-jars-VerifySoftFailDuringClinit.dex" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_dex2oat_tests" />
<option name="module-name" value="art_standalone_dex2oat_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/dexoptanalyzer/art_standalone_dexoptanalyzer_tests.xml b/dexoptanalyzer/art_standalone_dexoptanalyzer_tests.xml
index e9c8f59420..62cfcd2af6 100644
--- a/dexoptanalyzer/art_standalone_dexoptanalyzer_tests.xml
+++ b/dexoptanalyzer/art_standalone_dexoptanalyzer_tests.xml
@@ -18,25 +18,25 @@
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_dexoptanalyzer_tests->/data/local/tmp/nativetest/art_standalone_dexoptanalyzer_tests" />
+ <option name="push" value="art_standalone_dexoptanalyzer_tests->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art_standalone_dexoptanalyzer_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-LinkageTest.dex->/data/local/tmp/nativetest/art-gtest-jars-LinkageTest.dex" />
- <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/nativetest/art-gtest-jars-Main.jar" />
- <option name="push" value="art-gtest-jars-MainStripped.jar->/data/local/tmp/nativetest/art-gtest-jars-MainStripped.jar" />
- <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDex.jar" />
- <option name="push" value="art-gtest-jars-MultiDexModifiedSecondary.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDexModifiedSecondary.jar" />
- <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/nativetest/art-gtest-jars-MyClassNatives.jar" />
- <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/nativetest/art-gtest-jars-Nested.jar" />
- <option name="push" value="art-gtest-jars-VerifierDeps.dex->/data/local/tmp/nativetest/art-gtest-jars-VerifierDeps.dex" />
- <option name="push" value="art-gtest-jars-VerifierDepsMulti.dex->/data/local/tmp/nativetest/art-gtest-jars-VerifierDepsMulti.dex" />
+ <option name="push" value="art-gtest-jars-LinkageTest.dex->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-LinkageTest.dex" />
+ <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-Main.jar" />
+ <option name="push" value="art-gtest-jars-MainStripped.jar->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-MainStripped.jar" />
+ <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-MultiDex.jar" />
+ <option name="push" value="art-gtest-jars-MultiDexModifiedSecondary.jar->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-MultiDexModifiedSecondary.jar" />
+ <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-MyClassNatives.jar" />
+ <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-Nested.jar" />
+ <option name="push" value="art-gtest-jars-VerifierDeps.dex->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-VerifierDeps.dex" />
+ <option name="push" value="art-gtest-jars-VerifierDepsMulti.dex->/data/local/tmp/art_standalone_dexoptanalyzer_tests/art-gtest-jars-VerifierDepsMulti.dex" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_dexoptanalyzer_tests" />
<option name="module-name" value="art_standalone_dexoptanalyzer_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/libartbase/base/memfd.h b/libartbase/base/memfd.h
index 0bb336d45a..3c27dcb9e3 100644
--- a/libartbase/base/memfd.h
+++ b/libartbase/base/memfd.h
@@ -53,6 +53,10 @@
# define F_SEAL_FUTURE_WRITE 0x0010
#endif
+#ifndef MFD_CLOEXEC
+# define MFD_CLOEXEC 0x0001U
+#endif
+
#ifndef MFD_ALLOW_SEALING
# define MFD_ALLOW_SEALING 0x0002U
#endif
diff --git a/libartpalette/apex/palette.cc b/libartpalette/apex/palette.cc
index 71fd39ddb4..75a3878028 100644
--- a/libartpalette/apex/palette.cc
+++ b/libartpalette/apex/palette.cc
@@ -218,4 +218,28 @@ palette_status_t PaletteNotifyEndJniInvocation(JNIEnv* env) {
return m(env);
}
+palette_status_t PaletteReportLockContention(JNIEnv* env,
+ int32_t wait_ms,
+ const char* filename,
+ int32_t line_number,
+ const char* method_name,
+ const char* owner_filename,
+ int32_t owner_line_number,
+ const char* owner_method_name,
+ const char* proc_name,
+ const char* thread_name) {
+ PaletteReportLockContentionMethod m =
+ PaletteLoader::Instance().GetPaletteReportLockContentionMethod();
+ return m(env,
+ wait_ms,
+ filename,
+ line_number,
+ method_name,
+ owner_filename,
+ owner_line_number,
+ owner_method_name,
+ proc_name,
+ thread_name);
+}
+
} // extern "C"
diff --git a/libartpalette/include/palette/palette_method_list.h b/libartpalette/include/palette/palette_method_list.h
index 6a7822b1a2..066f24fb54 100644
--- a/libartpalette/include/palette/palette_method_list.h
+++ b/libartpalette/include/palette/palette_method_list.h
@@ -53,5 +53,15 @@
M(PaletteShouldReportJniInvocations, bool*) \
M(PaletteNotifyBeginJniInvocation, JNIEnv* env) \
M(PaletteNotifyEndJniInvocation, JNIEnv* env) \
+ M(PaletteReportLockContention, JNIEnv* env, \
+ int32_t wait_ms, \
+ const char* filename, \
+ int32_t line_number, \
+ const char* method_name, \
+ const char* owner_filename, \
+ int32_t owner_line_number, \
+ const char* owner_method_name, \
+ const char* proc_name, \
+ const char* thread_name) \
#endif // ART_LIBARTPALETTE_INCLUDE_PALETTE_PALETTE_METHOD_LIST_H_
diff --git a/libartpalette/libartpalette.map.txt b/libartpalette/libartpalette.map.txt
index 9c846b160b..6401010abe 100644
--- a/libartpalette/libartpalette.map.txt
+++ b/libartpalette/libartpalette.map.txt
@@ -35,6 +35,7 @@ LIBARTPALETTE_1 {
PaletteShouldReportJniInvocations; #apex
PaletteNotifyBeginJniInvocation; #apex
PaletteNotifyEndJniInvocation; #apex
+ PaletteReportLockContention; #apex
local:
*;
diff --git a/libartpalette/system/palette_fake.cc b/libartpalette/system/palette_fake.cc
index dbbbf89dfa..bbf8f2dd8c 100644
--- a/libartpalette/system/palette_fake.cc
+++ b/libartpalette/system/palette_fake.cc
@@ -128,3 +128,16 @@ palette_status_t PaletteNotifyBeginJniInvocation(JNIEnv* env ATTRIBUTE_UNUSED) {
palette_status_t PaletteNotifyEndJniInvocation(JNIEnv* env ATTRIBUTE_UNUSED) {
return PALETTE_STATUS_OK;
}
+
+palette_status_t PaletteReportLockContention(JNIEnv* env ATTRIBUTE_UNUSED,
+ int32_t wait_ms ATTRIBUTE_UNUSED,
+ const char* filename ATTRIBUTE_UNUSED,
+ int32_t line_number ATTRIBUTE_UNUSED,
+ const char* method_name ATTRIBUTE_UNUSED,
+ const char* owner_filename ATTRIBUTE_UNUSED,
+ int32_t owner_line_number ATTRIBUTE_UNUSED,
+ const char* owner_method_name ATTRIBUTE_UNUSED,
+ const char* proc_name ATTRIBUTE_UNUSED,
+ const char* thread_name ATTRIBUTE_UNUSED) {
+ return PALETTE_STATUS_OK;
+}
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index 31cf19711d..47f2e29a58 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -162,6 +162,15 @@ gensrcs {
art_cc_library {
name: "libdexfile",
+ visibility: [
+ // Allow libdexfile_support users to list this as a runtime_libs
+ // dependency - see comment for libdexfile_support. It shouldn't be used
+ // for any other purpose.
+ "//external/perfetto",
+ "//system/core/debuggerd",
+ "//system/extras/simpleperf",
+ "//system/unwinding/libunwindstack",
+ ],
defaults: [
"libdexfile_defaults",
"libart_nativeunwind_defaults",
@@ -369,6 +378,14 @@ art_cc_test {
// dependency on dex file logic. It is therefore safe to use from binaries
// compiled without dex file support, given they won't encounter any dex file
// stack frames.
+//
+// IMPORTANT: When adding a static_libs dependency on this library, please
+// remember to also add a corresponding
+//
+// runtime_libs: ["libdexfile"],
+//
+// That is necessary since Soong doesn't propagate dependencies transitively for
+// static libraries (b/169779783).
art_cc_library_static {
name: "libdexfile_support",
visibility: ["//visibility:public"],
diff --git a/libdexfile/art_standalone_libdexfile_tests.xml b/libdexfile/art_standalone_libdexfile_tests.xml
index 82cd4087a8..d00235a55f 100644
--- a/libdexfile/art_standalone_libdexfile_tests.xml
+++ b/libdexfile/art_standalone_libdexfile_tests.xml
@@ -16,21 +16,21 @@
<configuration description="Runs art_standalone_libdexfile_tests.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_libdexfile_tests->/data/local/tmp/nativetest/art_standalone_libdexfile_tests" />
+ <option name="push" value="art_standalone_libdexfile_tests->/data/local/tmp/art_standalone_libdexfile_tests/art_standalone_libdexfile_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-GetMethodSignature.jar->/data/local/tmp/nativetest/art-gtest-jars-GetMethodSignature.jar" />
- <option name="push" value="art-gtest-jars-Lookup.jar->/data/local/tmp/nativetest/art-gtest-jars-Lookup.jar" />
- <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/nativetest/art-gtest-jars-Main.jar" />
- <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDex.jar" />
- <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/nativetest/art-gtest-jars-Nested.jar" />
+ <option name="push" value="art-gtest-jars-GetMethodSignature.jar->/data/local/tmp/art_standalone_libdexfile_tests/art-gtest-jars-GetMethodSignature.jar" />
+ <option name="push" value="art-gtest-jars-Lookup.jar->/data/local/tmp/art_standalone_libdexfile_tests/art-gtest-jars-Lookup.jar" />
+ <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/art_standalone_libdexfile_tests/art-gtest-jars-Main.jar" />
+ <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/art_standalone_libdexfile_tests/art-gtest-jars-MultiDex.jar" />
+ <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/art_standalone_libdexfile_tests/art-gtest-jars-Nested.jar" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_libdexfile_tests" />
<option name="module-name" value="art_standalone_libdexfile_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index 5363b00c24..e3027fc95f 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -738,7 +738,7 @@ class DexFile {
}
// Used by oat writer.
- void SetOatDexFile(OatDexFile* oat_dex_file) const {
+ void SetOatDexFile(const OatDexFile* oat_dex_file) const {
oat_dex_file_ = oat_dex_file;
}
diff --git a/libprofile/art_standalone_libprofile_tests.xml b/libprofile/art_standalone_libprofile_tests.xml
index c7f2f669d2..f113668ae2 100644
--- a/libprofile/art_standalone_libprofile_tests.xml
+++ b/libprofile/art_standalone_libprofile_tests.xml
@@ -16,19 +16,19 @@
<configuration description="Runs art_standalone_libprofile_tests.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_libprofile_tests->/data/local/tmp/nativetest/art_standalone_libprofile_tests" />
+ <option name="push" value="art_standalone_libprofile_tests->/data/local/tmp/art_standalone_libprofile_tests/art_standalone_libprofile_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-ManyMethods.jar->/data/local/tmp/nativetest/art-gtest-jars-ManyMethods.jar" />
- <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDex.jar" />
- <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-ProfileTestMultiDex.jar" />
+ <option name="push" value="art-gtest-jars-ManyMethods.jar->/data/local/tmp/art_standalone_libprofile_tests/art-gtest-jars-ManyMethods.jar" />
+ <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/art_standalone_libprofile_tests/art-gtest-jars-MultiDex.jar" />
+ <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/art_standalone_libprofile_tests/art-gtest-jars-ProfileTestMultiDex.jar" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_libprofile_tests" />
<option name="module-name" value="art_standalone_libprofile_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/oatdump/art_standalone_oatdump_tests.xml b/oatdump/art_standalone_oatdump_tests.xml
index 089bb77f6e..57e91636f0 100644
--- a/oatdump/art_standalone_oatdump_tests.xml
+++ b/oatdump/art_standalone_oatdump_tests.xml
@@ -16,17 +16,17 @@
<configuration description="Runs art_standalone_oatdump_tests.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_oatdump_tests->/data/local/tmp/nativetest/art_standalone_oatdump_tests" />
+ <option name="push" value="art_standalone_oatdump_tests->/data/local/tmp/art_standalone_oatdump_tests/art_standalone_oatdump_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-ProfileTestMultiDex.jar" />
+ <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/art_standalone_oatdump_tests/art-gtest-jars-ProfileTestMultiDex.jar" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_oatdump_tests" />
<option name="module-name" value="art_standalone_oatdump_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/openjdkjvm/OpenjdkJvm.cc b/openjdkjvm/OpenjdkJvm.cc
index d64086d43c..9b514af452 100644
--- a/openjdkjvm/OpenjdkJvm.cc
+++ b/openjdkjvm/OpenjdkJvm.cc
@@ -423,7 +423,6 @@ JNIEXPORT void JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring jav
art::Thread* thread;
{
thread = thread_list->SuspendThreadByPeer(jthread,
- true,
art::SuspendReason::kInternal,
&timed_out);
}
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index bb8fa3b694..a9a6ee8895 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -898,7 +898,6 @@ jvmtiError ThreadUtil::SuspendOther(art::Thread* self,
bool timeout = true;
art::Thread* ret_target = art::Runtime::Current()->GetThreadList()->SuspendThreadByPeer(
target_jthread,
- /* request_suspension= */ true,
art::SuspendReason::kForUserCode,
&timeout);
if (ret_target == nullptr && !timeout) {
diff --git a/profman/art_standalone_profman_tests.xml b/profman/art_standalone_profman_tests.xml
index df62e09bd7..1710942259 100644
--- a/profman/art_standalone_profman_tests.xml
+++ b/profman/art_standalone_profman_tests.xml
@@ -18,17 +18,17 @@
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_profman_tests->/data/local/tmp/nativetest/art_standalone_profman_tests" />
+ <option name="push" value="art_standalone_profman_tests->/data/local/tmp/art_standalone_profman_tests/art_standalone_profman_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-ProfileTestMultiDex.jar" />
+ <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/art_standalone_profman_tests/art-gtest-jars-ProfileTestMultiDex.jar" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_profman_tests" />
<option name="module-name" value="art_standalone_profman_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/runtime/art_standalone_runtime_compiler_tests.xml b/runtime/art_standalone_runtime_compiler_tests.xml
index 3b21e578d0..2bacda1965 100644
--- a/runtime/art_standalone_runtime_compiler_tests.xml
+++ b/runtime/art_standalone_runtime_compiler_tests.xml
@@ -16,19 +16,19 @@
<configuration description="Runs art_standalone_runtime_compiler_tests.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_runtime_compiler_tests->/data/local/tmp/nativetest/art_standalone_runtime_compiler_tests" />
+ <option name="push" value="art_standalone_runtime_compiler_tests->/data/local/tmp/art_standalone_runtime_compiler_tests/art_standalone_runtime_compiler_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/nativetest/art-gtest-jars-Main.jar" />
- <option name="push" value="art-gtest-jars-NonStaticLeafMethods.jar->/data/local/tmp/nativetest/art-gtest-jars-NonStaticLeafMethods.jar" />
- <option name="push" value="art-gtest-jars-StaticLeafMethods.jar->/data/local/tmp/nativetest/art-gtest-jars-StaticLeafMethods.jar" />
+ <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/art_standalone_runtime_compiler_tests/art-gtest-jars-Main.jar" />
+ <option name="push" value="art-gtest-jars-NonStaticLeafMethods.jar->/data/local/tmp/art_standalone_runtime_compiler_tests/art-gtest-jars-NonStaticLeafMethods.jar" />
+ <option name="push" value="art-gtest-jars-StaticLeafMethods.jar->/data/local/tmp/art_standalone_runtime_compiler_tests/art-gtest-jars-StaticLeafMethods.jar" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_runtime_compiler_tests" />
<option name="module-name" value="art_standalone_runtime_compiler_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/runtime/art_standalone_runtime_tests.xml b/runtime/art_standalone_runtime_tests.xml
index 1bb80fdafe..a46b7b4fb9 100644
--- a/runtime/art_standalone_runtime_tests.xml
+++ b/runtime/art_standalone_runtime_tests.xml
@@ -16,53 +16,53 @@
<configuration description="Runs art_standalone_runtime_tests.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art_standalone_runtime_tests->/data/local/tmp/nativetest/art_standalone_runtime_tests" />
+ <option name="push" value="art_standalone_runtime_tests->/data/local/tmp/art_standalone_runtime_tests/art_standalone_runtime_tests" />
<option name="append-bitness" value="true" />
</target_preparer>
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="art-gtest-jars-AllFields.jar->/data/local/tmp/nativetest/art-gtest-jars-AllFields.jar" />
- <option name="push" value="art-gtest-jars-ErroneousA.jar->/data/local/tmp/nativetest/art-gtest-jars-ErroneousA.jar" />
- <option name="push" value="art-gtest-jars-ErroneousB.jar->/data/local/tmp/nativetest/art-gtest-jars-ErroneousB.jar" />
- <option name="push" value="art-gtest-jars-ErroneousInit.jar->/data/local/tmp/nativetest/art-gtest-jars-ErroneousInit.jar" />
- <option name="push" value="art-gtest-jars-Extension1.jar->/data/local/tmp/nativetest/art-gtest-jars-Extension1.jar" />
- <option name="push" value="art-gtest-jars-Extension2.jar->/data/local/tmp/nativetest/art-gtest-jars-Extension2.jar" />
- <option name="push" value="art-gtest-jars-ForClassLoaderA.jar->/data/local/tmp/nativetest/art-gtest-jars-ForClassLoaderA.jar" />
- <option name="push" value="art-gtest-jars-ForClassLoaderB.jar->/data/local/tmp/nativetest/art-gtest-jars-ForClassLoaderB.jar" />
- <option name="push" value="art-gtest-jars-ForClassLoaderC.jar->/data/local/tmp/nativetest/art-gtest-jars-ForClassLoaderC.jar" />
- <option name="push" value="art-gtest-jars-ForClassLoaderD.jar->/data/local/tmp/nativetest/art-gtest-jars-ForClassLoaderD.jar" />
- <option name="push" value="art-gtest-jars-HiddenApiSignatures.jar->/data/local/tmp/nativetest/art-gtest-jars-HiddenApiSignatures.jar" />
- <option name="push" value="art-gtest-jars-IMTA.jar->/data/local/tmp/nativetest/art-gtest-jars-IMTA.jar" />
- <option name="push" value="art-gtest-jars-IMTB.jar->/data/local/tmp/nativetest/art-gtest-jars-IMTB.jar" />
- <option name="push" value="art-gtest-jars-Instrumentation.jar->/data/local/tmp/nativetest/art-gtest-jars-Instrumentation.jar" />
- <option name="push" value="art-gtest-jars-Interfaces.jar->/data/local/tmp/nativetest/art-gtest-jars-Interfaces.jar" />
- <option name="push" value="art-gtest-jars-LinkageTest.dex->/data/local/tmp/nativetest/art-gtest-jars-LinkageTest.dex" />
- <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/nativetest/art-gtest-jars-Main.jar" />
- <option name="push" value="art-gtest-jars-MainStripped.jar->/data/local/tmp/nativetest/art-gtest-jars-MainStripped.jar" />
- <option name="push" value="art-gtest-jars-MainUncompressedAligned.jar->/data/local/tmp/nativetest/art-gtest-jars-MainUncompressedAligned.jar" />
- <option name="push" value="art-gtest-jars-MethodTypes.jar->/data/local/tmp/nativetest/art-gtest-jars-MethodTypes.jar" />
- <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDex.jar" />
- <option name="push" value="art-gtest-jars-MultiDexModifiedSecondary.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDexModifiedSecondary.jar" />
- <option name="push" value="art-gtest-jars-MultiDexUncompressedAligned.jar->/data/local/tmp/nativetest/art-gtest-jars-MultiDexUncompressedAligned.jar" />
- <option name="push" value="art-gtest-jars-MyClass.jar->/data/local/tmp/nativetest/art-gtest-jars-MyClass.jar" />
- <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/nativetest/art-gtest-jars-MyClassNatives.jar" />
- <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/nativetest/art-gtest-jars-Nested.jar" />
- <option name="push" value="art-gtest-jars-Packages.jar->/data/local/tmp/nativetest/art-gtest-jars-Packages.jar" />
- <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/nativetest/art-gtest-jars-ProfileTestMultiDex.jar" />
- <option name="push" value="art-gtest-jars-ProtoCompare.jar->/data/local/tmp/nativetest/art-gtest-jars-ProtoCompare.jar" />
- <option name="push" value="art-gtest-jars-ProtoCompare2.jar->/data/local/tmp/nativetest/art-gtest-jars-ProtoCompare2.jar" />
- <option name="push" value="art-gtest-jars-StaticLeafMethods.jar->/data/local/tmp/nativetest/art-gtest-jars-StaticLeafMethods.jar" />
- <option name="push" value="art-gtest-jars-Statics.jar->/data/local/tmp/nativetest/art-gtest-jars-Statics.jar" />
- <option name="push" value="art-gtest-jars-StaticsFromCode.jar->/data/local/tmp/nativetest/art-gtest-jars-StaticsFromCode.jar" />
- <option name="push" value="art-gtest-jars-Transaction.jar->/data/local/tmp/nativetest/art-gtest-jars-Transaction.jar" />
- <option name="push" value="art-gtest-jars-VerifierDeps.dex->/data/local/tmp/nativetest/art-gtest-jars-VerifierDeps.dex" />
- <option name="push" value="art-gtest-jars-VerifierDepsMulti.dex->/data/local/tmp/nativetest/art-gtest-jars-VerifierDepsMulti.dex" />
- <option name="push" value="art-gtest-jars-XandY.jar->/data/local/tmp/nativetest/art-gtest-jars-XandY.jar" />
+ <option name="push" value="art-gtest-jars-AllFields.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-AllFields.jar" />
+ <option name="push" value="art-gtest-jars-ErroneousA.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ErroneousA.jar" />
+ <option name="push" value="art-gtest-jars-ErroneousB.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ErroneousB.jar" />
+ <option name="push" value="art-gtest-jars-ErroneousInit.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ErroneousInit.jar" />
+ <option name="push" value="art-gtest-jars-Extension1.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Extension1.jar" />
+ <option name="push" value="art-gtest-jars-Extension2.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Extension2.jar" />
+ <option name="push" value="art-gtest-jars-ForClassLoaderA.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ForClassLoaderA.jar" />
+ <option name="push" value="art-gtest-jars-ForClassLoaderB.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ForClassLoaderB.jar" />
+ <option name="push" value="art-gtest-jars-ForClassLoaderC.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ForClassLoaderC.jar" />
+ <option name="push" value="art-gtest-jars-ForClassLoaderD.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ForClassLoaderD.jar" />
+ <option name="push" value="art-gtest-jars-HiddenApiSignatures.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-HiddenApiSignatures.jar" />
+ <option name="push" value="art-gtest-jars-IMTA.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-IMTA.jar" />
+ <option name="push" value="art-gtest-jars-IMTB.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-IMTB.jar" />
+ <option name="push" value="art-gtest-jars-Instrumentation.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Instrumentation.jar" />
+ <option name="push" value="art-gtest-jars-Interfaces.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Interfaces.jar" />
+ <option name="push" value="art-gtest-jars-LinkageTest.dex->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-LinkageTest.dex" />
+ <option name="push" value="art-gtest-jars-Main.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Main.jar" />
+ <option name="push" value="art-gtest-jars-MainStripped.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MainStripped.jar" />
+ <option name="push" value="art-gtest-jars-MainUncompressedAligned.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MainUncompressedAligned.jar" />
+ <option name="push" value="art-gtest-jars-MethodTypes.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MethodTypes.jar" />
+ <option name="push" value="art-gtest-jars-MultiDex.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MultiDex.jar" />
+ <option name="push" value="art-gtest-jars-MultiDexModifiedSecondary.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MultiDexModifiedSecondary.jar" />
+ <option name="push" value="art-gtest-jars-MultiDexUncompressedAligned.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MultiDexUncompressedAligned.jar" />
+ <option name="push" value="art-gtest-jars-MyClass.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MyClass.jar" />
+ <option name="push" value="art-gtest-jars-MyClassNatives.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-MyClassNatives.jar" />
+ <option name="push" value="art-gtest-jars-Nested.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Nested.jar" />
+ <option name="push" value="art-gtest-jars-Packages.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Packages.jar" />
+ <option name="push" value="art-gtest-jars-ProfileTestMultiDex.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ProfileTestMultiDex.jar" />
+ <option name="push" value="art-gtest-jars-ProtoCompare.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ProtoCompare.jar" />
+ <option name="push" value="art-gtest-jars-ProtoCompare2.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-ProtoCompare2.jar" />
+ <option name="push" value="art-gtest-jars-StaticLeafMethods.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-StaticLeafMethods.jar" />
+ <option name="push" value="art-gtest-jars-Statics.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Statics.jar" />
+ <option name="push" value="art-gtest-jars-StaticsFromCode.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-StaticsFromCode.jar" />
+ <option name="push" value="art-gtest-jars-Transaction.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-Transaction.jar" />
+ <option name="push" value="art-gtest-jars-VerifierDeps.dex->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-VerifierDeps.dex" />
+ <option name="push" value="art-gtest-jars-VerifierDepsMulti.dex->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-VerifierDepsMulti.dex" />
+ <option name="push" value="art-gtest-jars-XandY.jar->/data/local/tmp/art_standalone_runtime_tests/art-gtest-jars-XandY.jar" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/art_standalone_runtime_tests" />
<option name="module-name" value="art_standalone_runtime_tests" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 8b9e42a572..e21a004e33 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2621,6 +2621,26 @@ ClassPathEntry FindInClassPath(const char* descriptor,
return ClassPathEntry(nullptr, nullptr);
}
+// Helper macro to make sure each class loader lookup call handles the case the
+// class loader is not recognized, or the lookup threw an exception.
+#define RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(call_, result_, thread_) \
+do { \
+ auto local_call = call_; \
+ if (!local_call) { \
+ return false; \
+ } \
+ auto local_result = result_; \
+ if (local_result != nullptr) { \
+ return true; \
+ } \
+ auto local_thread = thread_; \
+ if (local_thread->IsExceptionPending()) { \
+ /* Pending exception means there was an error other than */ \
+ /* ClassNotFound that must be returned to the caller. */ \
+ return false; \
+ } \
+} while (0)
+
bool ClassLinker::FindClassInSharedLibraries(ScopedObjectAccessAlreadyRunnable& soa,
Thread* self,
const char* descriptor,
@@ -2640,12 +2660,10 @@ bool ClassLinker::FindClassInSharedLibraries(ScopedObjectAccessAlreadyRunnable&
MutableHandle<mirror::ClassLoader> temp_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
for (auto loader : shared_libraries.Iterate<mirror::ClassLoader>()) {
temp_loader.Assign(loader);
- if (!FindClassInBaseDexClassLoader(soa, self, descriptor, hash, temp_loader, result)) {
- return false; // One of the shared libraries is not supported.
- }
- if (*result != nullptr) {
- return true; // Found the class up the chain.
- }
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInBaseDexClassLoader(soa, self, descriptor, hash, temp_loader, result),
+ *result,
+ self);
}
return true;
}
@@ -2658,7 +2676,8 @@ bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnabl
/*out*/ ObjPtr<mirror::Class>* result) {
// Termination case: boot class loader.
if (IsBootClassLoader(soa, class_loader.Get())) {
- *result = FindClassInBootClassLoaderClassPath(self, descriptor, hash);
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInBootClassLoaderClassPath(self, descriptor, hash, result), *result, self);
return true;
}
@@ -2668,26 +2687,24 @@ bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnabl
// - shared libraries
// - class loader dex files
- // Handles as RegisterDexFile may allocate dex caches (and cause thread suspension).
+ // Create a handle as RegisterDexFile may allocate dex caches (and cause thread suspension).
StackHandleScope<1> hs(self);
Handle<mirror::ClassLoader> h_parent(hs.NewHandle(class_loader->GetParent()));
- if (!FindClassInBaseDexClassLoader(soa, self, descriptor, hash, h_parent, result)) {
- return false; // One of the parents is not supported.
- }
- if (*result != nullptr) {
- return true; // Found the class up the chain.
- }
-
- if (!FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result)) {
- return false; // One of the shared library loader is not supported.
- }
- if (*result != nullptr) {
- return true; // Found the class in a shared library.
- }
-
- // Search the current class loader classpath.
- *result = FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader);
- return !soa.Self()->IsExceptionPending();
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInBaseDexClassLoader(soa, self, descriptor, hash, h_parent, result),
+ *result,
+ self);
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result),
+ *result,
+ self);
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader, result),
+ *result,
+ self);
+ // We did not find a class, but the class loader chain was recognized, so we
+ // return true.
+ return true;
}
if (IsDelegateLastClassLoader(soa, class_loader)) {
@@ -2696,37 +2713,27 @@ bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnabl
// - shared libraries
// - class loader dex files
// - parent
- *result = FindClassInBootClassLoaderClassPath(self, descriptor, hash);
- if (*result != nullptr) {
- return true; // The class is part of the boot class path.
- }
- if (self->IsExceptionPending()) {
- // Pending exception means there was an error other than ClassNotFound that must be returned
- // to the caller.
- return false;
- }
-
- if (!FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result)) {
- return false; // One of the shared library loader is not supported.
- }
- if (*result != nullptr) {
- return true; // Found the class in a shared library.
- }
-
- *result = FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader);
- if (*result != nullptr) {
- return true; // Found the class in the current class loader
- }
- if (self->IsExceptionPending()) {
- // Pending exception means there was an error other than ClassNotFound that must be returned
- // to the caller.
- return false;
- }
-
- // Handles as RegisterDexFile may allocate dex caches (and cause thread suspension).
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInBootClassLoaderClassPath(self, descriptor, hash, result), *result, self);
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result),
+ *result,
+ self);
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader, result),
+ *result,
+ self);
+
+ // Create a handle as RegisterDexFile may allocate dex caches (and cause thread suspension).
StackHandleScope<1> hs(self);
Handle<mirror::ClassLoader> h_parent(hs.NewHandle(class_loader->GetParent()));
- return FindClassInBaseDexClassLoader(soa, self, descriptor, hash, h_parent, result);
+ RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION(
+ FindClassInBaseDexClassLoader(soa, self, descriptor, hash, h_parent, result),
+ *result,
+ self);
+ // We did not find a class, but the class loader chain was recognized, so we
+ // return true.
+ return true;
}
// Unsupported class loader.
@@ -2734,6 +2741,8 @@ bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnabl
return false;
}
+#undef RETURN_IF_UNRECOGNIZED_OR_FOUND_OR_EXCEPTION
+
namespace {
// Matches exceptions caught in DexFile.defineClass.
@@ -2761,36 +2770,38 @@ ALWAYS_INLINE void FilterDexFileCaughtExceptions(Thread* self, ClassLinker* clas
// Finds the class in the boot class loader.
// If the class is found the method returns the resolved class. Otherwise it returns null.
-ObjPtr<mirror::Class> ClassLinker::FindClassInBootClassLoaderClassPath(Thread* self,
- const char* descriptor,
- size_t hash) {
- ObjPtr<mirror::Class> result = nullptr;
+bool ClassLinker::FindClassInBootClassLoaderClassPath(Thread* self,
+ const char* descriptor,
+ size_t hash,
+ /*out*/ ObjPtr<mirror::Class>* result) {
ClassPathEntry pair = FindInClassPath(descriptor, hash, boot_class_path_);
if (pair.second != nullptr) {
ObjPtr<mirror::Class> klass = LookupClass(self, descriptor, hash, nullptr);
if (klass != nullptr) {
- result = EnsureResolved(self, descriptor, klass);
+ *result = EnsureResolved(self, descriptor, klass);
} else {
- result = DefineClass(self,
- descriptor,
- hash,
- ScopedNullHandle<mirror::ClassLoader>(),
- *pair.first,
- *pair.second);
- }
- if (result == nullptr) {
+ *result = DefineClass(self,
+ descriptor,
+ hash,
+ ScopedNullHandle<mirror::ClassLoader>(),
+ *pair.first,
+ *pair.second);
+ }
+ if (*result == nullptr) {
CHECK(self->IsExceptionPending()) << descriptor;
FilterDexFileCaughtExceptions(self, this);
}
}
- return result;
+ // The boot classloader is always a known lookup.
+ return true;
}
-ObjPtr<mirror::Class> ClassLinker::FindClassInBaseDexClassLoaderClassPath(
+bool ClassLinker::FindClassInBaseDexClassLoaderClassPath(
ScopedObjectAccessAlreadyRunnable& soa,
const char* descriptor,
size_t hash,
- Handle<mirror::ClassLoader> class_loader) {
+ Handle<mirror::ClassLoader> class_loader,
+ /*out*/ ObjPtr<mirror::Class>* result) {
DCHECK(IsPathOrDexClassLoader(soa, class_loader) ||
IsInMemoryDexClassLoader(soa, class_loader) ||
IsDelegateLastClassLoader(soa, class_loader))
@@ -2810,17 +2821,17 @@ ObjPtr<mirror::Class> ClassLinker::FindClassInBaseDexClassLoaderClassPath(
};
VisitClassLoaderDexFiles(soa, class_loader, find_class_def);
- ObjPtr<mirror::Class> klass = nullptr;
if (class_def != nullptr) {
- klass = DefineClass(soa.Self(), descriptor, hash, class_loader, *dex_file, *class_def);
- if (UNLIKELY(klass == nullptr)) {
+ *result = DefineClass(soa.Self(), descriptor, hash, class_loader, *dex_file, *class_def);
+ if (UNLIKELY(*result == nullptr)) {
CHECK(soa.Self()->IsExceptionPending()) << descriptor;
FilterDexFileCaughtExceptions(soa.Self(), this);
} else {
DCHECK(!soa.Self()->IsExceptionPending());
}
}
- return klass;
+ // A BaseDexClassLoader is always a known lookup.
+ return true;
}
ObjPtr<mirror::Class> ClassLinker::FindClass(Thread* self,
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 547753a6d6..5faf7602cb 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -1024,20 +1024,26 @@ class ClassLinker {
// dex files and does not recurse into its parent.
// The method checks that the provided class loader is either a PathClassLoader or a
// DexClassLoader.
- // If the class is found the method returns the resolved class. Otherwise it returns null.
- ObjPtr<mirror::Class> FindClassInBaseDexClassLoaderClassPath(
+ // If the class is found the method updates `result`.
+ // The method always returns true, to notify to the caller a
+ // BaseDexClassLoader has a known lookup.
+ bool FindClassInBaseDexClassLoaderClassPath(
ScopedObjectAccessAlreadyRunnable& soa,
const char* descriptor,
size_t hash,
- Handle<mirror::ClassLoader> class_loader)
+ Handle<mirror::ClassLoader> class_loader,
+ /*out*/ ObjPtr<mirror::Class>* result)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
// Finds the class in the boot class loader.
- // If the class is found the method returns the resolved class. Otherwise it returns null.
- ObjPtr<mirror::Class> FindClassInBootClassLoaderClassPath(Thread* self,
- const char* descriptor,
- size_t hash)
+ // If the class is found the method updates `result`.
+ // The method always returns true, to notify to the caller the
+ // boot class loader has a known lookup.
+ bool FindClassInBootClassLoaderClassPath(Thread* self,
+ const char* descriptor,
+ size_t hash,
+ /*out*/ ObjPtr<mirror::Class>* result)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::dex_lock_);
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index 538d7bef7c..936b9199b5 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -1630,11 +1630,16 @@ void ConcurrentCopying::CopyingPhase() {
// for the last time before transitioning to the shared mark stack mode, which would process new
// refs that may have been concurrently pushed onto the mark stack during the ProcessMarkStack()
// call above. At the same time, disable weak ref accesses using a per-thread flag. It's
- // important to do these together in a single checkpoint so that we can ensure that mutators
- // won't newly gray objects and push new refs onto the mark stack due to weak ref accesses and
+ // important to do these together so that we can ensure that mutators won't
+ // newly gray objects and push new refs onto the mark stack due to weak ref accesses and
// mutators safely transition to the shared mark stack mode (without leaving unprocessed refs on
// the thread-local mark stacks), without a race. This is why we use a thread-local weak ref
// access flag Thread::tls32_.weak_ref_access_enabled_ instead of the global ones.
+ // We must use a stop-the-world pause to disable weak ref access. A checkpoint may lead to a
+ // deadlock if one mutator acquires a low-level mutex and then gets blocked while accessing
+ // a weak-ref (after participating in the checkpoint), and another mutator indefinitely waits
+ // for the mutex before it participates in the checkpoint. Consequently, the gc-thread blocks
+ // forever as the checkpoint never finishes (See runtime/mutator_gc_coord.md).
SwitchToSharedMarkStackMode();
CHECK(!self->GetWeakRefAccessEnabled());
// Now that weak refs accesses are disabled, once we exhaust the shared mark stack again here
@@ -2044,21 +2049,36 @@ class ConcurrentCopying::AssertToSpaceInvariantFieldVisitor {
void ConcurrentCopying::RevokeThreadLocalMarkStacks(bool disable_weak_ref_access,
Closure* checkpoint_callback) {
Thread* self = Thread::Current();
- RevokeThreadLocalMarkStackCheckpoint check_point(this, disable_weak_ref_access);
+ Locks::mutator_lock_->AssertSharedHeld(self);
ThreadList* thread_list = Runtime::Current()->GetThreadList();
- gc_barrier_->Init(self, 0);
- size_t barrier_count = thread_list->RunCheckpoint(&check_point, checkpoint_callback);
- // If there are no threads to wait which implys that all the checkpoint functions are finished,
- // then no need to release the mutator lock.
- if (barrier_count == 0) {
- return;
- }
- Locks::mutator_lock_->SharedUnlock(self);
- {
- ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun);
- gc_barrier_->Increment(self, barrier_count);
+ RevokeThreadLocalMarkStackCheckpoint check_point(this, disable_weak_ref_access);
+ if (disable_weak_ref_access) {
+ // We're the only thread that could possibly ask for exclusive access here.
+ Locks::mutator_lock_->SharedUnlock(self);
+ {
+ ScopedPause pause(this);
+ MutexLock mu(self, *Locks::thread_list_lock_);
+ checkpoint_callback->Run(self);
+ for (Thread* thread : thread_list->GetList()) {
+ check_point.Run(thread);
+ }
+ }
+ Locks::mutator_lock_->SharedLock(self);
+ } else {
+ gc_barrier_->Init(self, 0);
+ size_t barrier_count = thread_list->RunCheckpoint(&check_point, checkpoint_callback);
+ // If there are no threads to wait which implys that all the checkpoint functions are finished,
+ // then no need to release the mutator lock.
+ if (barrier_count == 0) {
+ return;
+ }
+ Locks::mutator_lock_->SharedUnlock(self);
+ {
+ ScopedThreadStateChange tsc(self, kWaitingForCheckPointsToRun);
+ gc_barrier_->Increment(self, barrier_count);
+ }
+ Locks::mutator_lock_->SharedLock(self);
}
- Locks::mutator_lock_->SharedLock(self);
}
void ConcurrentCopying::RevokeThreadLocalMarkStack(Thread* thread) {
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 5ee88718dc..876e12091c 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -1238,7 +1238,8 @@ void Jit::CreateThreadPool() {
// Start with '/boot' and end with '.art' to match the pattern recognized
// by android_os_Debug.cpp for boot images.
const char* name = "/boot-image-methods.art";
- unique_fd mem_fd = unique_fd(art::memfd_create(name, /* flags= */ MFD_ALLOW_SEALING));
+ unique_fd mem_fd =
+ unique_fd(art::memfd_create(name, /* flags= */ MFD_ALLOW_SEALING | MFD_CLOEXEC));
if (mem_fd.get() == -1) {
PLOG(WARNING) << "Could not create boot image methods file descriptor";
return;
diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc
index 425eadca41..b86badcba5 100644
--- a/runtime/jit/profile_saver.cc
+++ b/runtime/jit/profile_saver.cc
@@ -189,7 +189,7 @@ void ProfileSaver::Run() {
// We might have been woken up by a huge number of notifications to guarantee saving.
// If we didn't meet the minimum saving period go back to sleep (only if missed by
// a reasonable margin).
- uint64_t min_save_period_ns = options_.GetMinSavePeriodMs();
+ uint64_t min_save_period_ns = MsToNs(options_.GetMinSavePeriodMs());
while (min_save_period_ns * 0.9 > sleep_time) {
{
MutexLock mu(self, wait_lock_);
diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc
index 19e1f3d2c4..f661631789 100644
--- a/runtime/monitor_android.cc
+++ b/runtime/monitor_android.cc
@@ -24,6 +24,8 @@
#include <log/log_event_list.h>
#include "art_method.h"
+#include "jni/jni_env_ext.h"
+#include "palette/palette.h"
#include "thread.h"
#define EVENT_LOG_TAG_dvm_lock_sample 20003
@@ -41,14 +43,13 @@ void Monitor::LogContentionEvent(Thread* self,
int32_t owner_line_number;
TranslateLocation(owner_method, owner_dex_pc, &owner_filename, &owner_line_number);
- // Emit the process name, <= 37 bytes.
+ // Emit the process name, <= 33 bytes.
+ char proc_name[33] = {};
{
int fd = open("/proc/self/cmdline", O_RDONLY | O_CLOEXEC);
- char procName[33];
- memset(procName, 0, sizeof(procName));
- read(fd, procName, sizeof(procName) - 1);
+ read(fd, proc_name, sizeof(proc_name) - 1);
close(fd);
- ctx << procName;
+ ctx << proc_name;
}
// Emit the sensitive thread ("main thread") status. We follow tradition that this corresponds
@@ -58,20 +59,19 @@ void Monitor::LogContentionEvent(Thread* self,
ctx << (Thread::IsSensitiveThread() ? kIsSensitive : kIsNotSensitive);
// Emit self thread name string.
- {
- std::string thread_name;
- self->GetThreadName(thread_name);
- ctx << thread_name;
- }
+ std::string thread_name;
+ self->GetThreadName(thread_name);
+ ctx << thread_name;
// Emit the wait time.
ctx << wait_ms;
const char* filename = nullptr;
+ int32_t line_number;
+ std::string method_name;
{
uint32_t pc;
ArtMethod* m = self->GetCurrentMethod(&pc);
- int32_t line_number;
TranslateLocation(m, pc, &filename, &line_number);
// Emit the source code file name.
@@ -81,7 +81,8 @@ void Monitor::LogContentionEvent(Thread* self,
ctx << line_number;
// Emit the method name.
- ctx << ArtMethod::PrettyMethod(m);
+ method_name = ArtMethod::PrettyMethod(m);
+ ctx << method_name;
}
// Emit the lock owner source code file name.
@@ -97,12 +98,25 @@ void Monitor::LogContentionEvent(Thread* self,
ctx << owner_line_number;
// Emit the owner method name.
- ctx << ArtMethod::PrettyMethod(owner_method);
+ std::string owner_method_name = ArtMethod::PrettyMethod(owner_method);
+ ctx << owner_method_name;
// Emit the sample percentage.
ctx << sample_percent;
ctx << LOG_ID_EVENTS;
+
+ // Now report to other interested parties.
+ PaletteReportLockContention(self->GetJniEnv(),
+ wait_ms,
+ filename,
+ line_number,
+ method_name.c_str(),
+ owner_filename,
+ owner_line_number,
+ owner_method_name.c_str(),
+ proc_name,
+ thread_name.c_str());
}
} // namespace art
diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc
index 9d2dfac069..e88516e248 100644
--- a/runtime/native/dalvik_system_VMStack.cc
+++ b/runtime/native/dalvik_system_VMStack.cc
@@ -59,7 +59,6 @@ static ResultT GetThreadStack(const ScopedFastNativeObjectAccess& soa,
ThreadList* thread_list = Runtime::Current()->GetThreadList();
bool timed_out;
Thread* thread = thread_list->SuspendThreadByPeer(peer,
- /* request_suspension= */ true,
SuspendReason::kInternal,
&timed_out);
if (thread != nullptr) {
diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc
index 37b3fe642e..c3b4fe09de 100644
--- a/runtime/native/java_lang_Thread.cc
+++ b/runtime/native/java_lang_Thread.cc
@@ -148,7 +148,6 @@ static void Thread_setNativeName(JNIEnv* env, jobject peer, jstring java_name) {
bool timed_out;
// Take suspend thread lock to avoid races with threads trying to suspend this one.
Thread* thread = thread_list->SuspendThreadByPeer(peer,
- /* request_suspension= */ true,
SuspendReason::kInternal,
&timed_out);
if (thread != nullptr) {
diff --git a/runtime/oat_file.cc b/runtime/oat_file.cc
index 8f653c2282..14e7a1b60e 100644
--- a/runtime/oat_file.cc
+++ b/runtime/oat_file.cc
@@ -168,7 +168,7 @@ class OatFileBase : public OatFile {
bool Setup(int zip_fd, ArrayRef<const std::string> dex_filenames, std::string* error_msg);
- void Setup(const std::vector<const DexFile*>& dex_files);
+ bool Setup(const std::vector<const DexFile*>& dex_files, std::string* error_msg);
// Setters exposed for ElfOatFile.
@@ -476,18 +476,71 @@ static bool ReadIndexBssMapping(OatFile* oat_file,
return true;
}
-void OatFileBase::Setup(const std::vector<const DexFile*>& dex_files) {
+static bool ComputeAndCheckTypeLookupTableData(const DexFile::Header& header,
+ const uint8_t* type_lookup_table_start,
+ const VdexFile* vdex_file,
+ const uint8_t** type_lookup_table_data,
+ std::string* error_msg) {
+ if (type_lookup_table_start == nullptr ||
+ reinterpret_cast<const uint32_t*>(type_lookup_table_start)[0] == 0) {
+ *type_lookup_table_data = nullptr;
+ return true;
+ }
+
+ *type_lookup_table_data = type_lookup_table_start + sizeof(uint32_t);
+ size_t expected_table_size = TypeLookupTable::RawDataLength(header.class_defs_size_);
+ size_t found_size = reinterpret_cast<const uint32_t*>(type_lookup_table_start)[0];
+ if (UNLIKELY(found_size != expected_table_size)) {
+ *error_msg =
+ StringPrintf("In vdex file '%s' unexpected type lookup table size: found %zu, expected %zu",
+ vdex_file->GetName().c_str(),
+ found_size,
+ expected_table_size);
+ return false;
+ }
+ if (UNLIKELY(!vdex_file->Contains(*type_lookup_table_data))) {
+ *error_msg =
+ StringPrintf("In vdex file '%s' found invalid type lookup table pointer %p not in [%p, %p]",
+ vdex_file->GetName().c_str(),
+ type_lookup_table_data,
+ vdex_file->Begin(),
+ vdex_file->End());
+ return false;
+ }
+ if (UNLIKELY(!vdex_file->Contains(*type_lookup_table_data + expected_table_size - 1))) {
+ *error_msg =
+ StringPrintf("In vdex file '%s' found overflowing type lookup table %p not in [%p, %p]",
+ vdex_file->GetName().c_str(),
+ type_lookup_table_data + expected_table_size,
+ vdex_file->Begin(),
+ vdex_file->End());
+ return false;
+ }
+ if (UNLIKELY(!IsAligned<4>(type_lookup_table_start))) {
+ *error_msg =
+ StringPrintf("In vdex file '%s' found invalid type lookup table alignment %p",
+ vdex_file->GetName().c_str(),
+ type_lookup_table_start);
+ return false;
+ }
+ return true;
+}
+
+bool OatFileBase::Setup(const std::vector<const DexFile*>& dex_files, std::string* error_msg) {
uint32_t i = 0;
const uint8_t* type_lookup_table_start = nullptr;
for (const DexFile* dex_file : dex_files) {
- type_lookup_table_start = vdex_->GetNextTypeLookupTableData(type_lookup_table_start, i++);
std::string dex_location = dex_file->GetLocation();
std::string canonical_location = DexFileLoader::GetDexCanonicalLocation(dex_location.c_str());
+ type_lookup_table_start = vdex_->GetNextTypeLookupTableData(type_lookup_table_start, i++);
const uint8_t* type_lookup_table_data = nullptr;
- if (type_lookup_table_start != nullptr &&
- (reinterpret_cast<uint32_t*>(type_lookup_table_start[0]) != 0)) {
- type_lookup_table_data = type_lookup_table_start + sizeof(uint32_t);
+ if (!ComputeAndCheckTypeLookupTableData(dex_file->GetHeader(),
+ type_lookup_table_start,
+ vdex_.get(),
+ &type_lookup_table_data,
+ error_msg)) {
+ return false;
}
// Create an OatDexFile and add it to the owning container.
OatDexFile* oat_dex_file = new OatDexFile(
@@ -497,7 +550,6 @@ void OatFileBase::Setup(const std::vector<const DexFile*>& dex_files) {
dex_location,
canonical_location,
type_lookup_table_data);
- dex_file->SetOatDexFile(oat_dex_file);
oat_dex_files_storage_.push_back(oat_dex_file);
// Add the location and canonical location (if different) to the oat_dex_files_ table.
@@ -508,6 +560,11 @@ void OatFileBase::Setup(const std::vector<const DexFile*>& dex_files) {
oat_dex_files_.Put(canonical_key, oat_dex_file);
}
}
+ // Now that we've created all the OatDexFile, update the dex files.
+ for (i = 0; i < dex_files.size(); ++i) {
+ dex_files[i]->SetOatDexFile(oat_dex_files_storage_[i]);
+ }
+ return true;
}
bool OatFileBase::Setup(int zip_fd,
@@ -1583,7 +1640,11 @@ class OatFileBackedByVdex final : public OatFileBase {
oat_file->SetVdex(vdex_file.release());
oat_file->SetupHeader(dex_files.size());
// Initialize OatDexFiles.
- oat_file->Setup(dex_files);
+ std::string error_msg;
+ if (!oat_file->Setup(dex_files, &error_msg)) {
+ LOG(WARNING) << "Could not create in-memory vdex file: " << error_msg;
+ return nullptr;
+ }
return oat_file.release();
}
@@ -1601,6 +1662,25 @@ class OatFileBackedByVdex final : public OatFileBase {
for (const uint8_t* dex_file_start = vdex_file->GetNextDexFileData(nullptr, i);
dex_file_start != nullptr;
dex_file_start = vdex_file->GetNextDexFileData(dex_file_start, ++i)) {
+ const DexFile::Header* header = reinterpret_cast<const DexFile::Header*>(dex_file_start);
+ if (UNLIKELY(!vdex_file->Contains(dex_file_start))) {
+ *error_msg =
+ StringPrintf("In vdex file '%s' found invalid dex file pointer %p not in [%p, %p]",
+ dex_location.c_str(),
+ dex_file_start,
+ vdex_file->Begin(),
+ vdex_file->End());
+ return nullptr;
+ }
+ if (UNLIKELY(!vdex_file->Contains(dex_file_start + header->file_size_ - 1))) {
+ *error_msg =
+ StringPrintf("In vdex file '%s' found overflowing dex file %p not in [%p, %p]",
+ dex_location.c_str(),
+ dex_file_start + header->file_size_,
+ vdex_file->Begin(),
+ vdex_file->End());
+ return nullptr;
+ }
if (UNLIKELY(!DexFileLoader::IsVersionAndMagicValid(dex_file_start))) {
*error_msg =
StringPrintf("In vdex file '%s' found dex file with invalid dex file version",
@@ -1612,10 +1692,14 @@ class OatFileBackedByVdex final : public OatFileBase {
std::string canonical_location = DexFileLoader::GetDexCanonicalLocation(location.c_str());
type_lookup_table_start = vdex_file->GetNextTypeLookupTableData(type_lookup_table_start, i);
const uint8_t* type_lookup_table_data = nullptr;
- if (type_lookup_table_start != nullptr &&
- (reinterpret_cast<uint32_t*>(type_lookup_table_start[0]) != 0)) {
- type_lookup_table_data = type_lookup_table_start + sizeof(uint32_t);
+ if (!ComputeAndCheckTypeLookupTableData(*header,
+ type_lookup_table_start,
+ vdex_file,
+ &type_lookup_table_data,
+ error_msg)) {
+ return nullptr;
}
+
OatDexFile* oat_dex_file = new OatDexFile(oat_file.get(),
dex_file_start,
vdex_file->GetLocationChecksum(i),
@@ -1656,7 +1740,9 @@ class OatFileBackedByVdex final : public OatFileBase {
return nullptr;
}
oat_file->SetupHeader(oat_file->external_dex_files_.size());
- oat_file->Setup(MakeNonOwningPointerVector(oat_file->external_dex_files_));
+ if (!oat_file->Setup(MakeNonOwningPointerVector(oat_file->external_dex_files_), error_msg)) {
+ return nullptr;
+ }
}
return oat_file.release();
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 433f564b2d..6c99c1fa8d 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -410,7 +410,7 @@ Runtime::~Runtime() {
while (threads_being_born_ > 0) {
shutdown_cond_->Wait(self);
}
- shutting_down_ = true;
+ SetShuttingDown();
}
// Shutdown and wait for the daemons.
CHECK(self != nullptr);
@@ -641,7 +641,7 @@ void Runtime::Abort(const char* msg) {
// May be coming from an unattached thread.
if (Thread::Current() == nullptr) {
Runtime* current = Runtime::Current();
- if (current != nullptr && current->IsStarted() && !current->IsShuttingDown(nullptr)) {
+ if (current != nullptr && current->IsStarted() && !current->IsShuttingDownUnsafe()) {
// We do not flag this to the unexpected-signal handler so that that may dump the stack.
abort();
UNREACHABLE();
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 68456cd37b..b2093a303c 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -222,7 +222,13 @@ class Runtime {
bool IsShuttingDown(Thread* self);
bool IsShuttingDownLocked() const REQUIRES(Locks::runtime_shutdown_lock_) {
- return shutting_down_;
+ return shutting_down_.load(std::memory_order_relaxed);
+ }
+ bool IsShuttingDownUnsafe() const {
+ return shutting_down_.load(std::memory_order_relaxed);
+ }
+ void SetShuttingDown() REQUIRES(Locks::runtime_shutdown_lock_) {
+ shutting_down_.store(true, std::memory_order_relaxed);
}
size_t NumberOfThreadsBeingBorn() const REQUIRES(Locks::runtime_shutdown_lock_) {
@@ -1190,8 +1196,10 @@ class Runtime {
// Waited upon until no threads are being born.
std::unique_ptr<ConditionVariable> shutdown_cond_ GUARDED_BY(Locks::runtime_shutdown_lock_);
- // Set when runtime shutdown is past the point that new threads may attach.
- bool shutting_down_ GUARDED_BY(Locks::runtime_shutdown_lock_);
+ // Set when runtime shutdown is past the point that new threads may attach. Usually
+ // GUARDED_BY(Locks::runtime_shutdown_lock_). But we need to check it in Abort without the
+ // lock, because we may already own it.
+ std::atomic<bool> shutting_down_;
// The runtime is starting to shutdown but is blocked waiting on shutdown_cond_.
bool shutting_down_started_ GUARDED_BY(Locks::runtime_shutdown_lock_);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 46aa2b59ad..16a5f93be4 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -4468,6 +4468,12 @@ bool Thread::IsSystemDaemon() const {
WellKnownClasses::java_lang_Thread_systemDaemon)->GetBoolean(GetPeer());
}
+std::string Thread::StateAndFlagsAsHexString() const {
+ std::stringstream result_stream;
+ result_stream << std::hex << tls32_.state_and_flags.as_atomic_int.load();
+ return result_stream.str();
+}
+
ScopedExceptionStorage::ScopedExceptionStorage(art::Thread* self)
: self_(self), hs_(self_), excp_(hs_.NewHandle<art::mirror::Throwable>(self_->GetException())) {
self_->ClearException();
diff --git a/runtime/thread.h b/runtime/thread.h
index 7a408021c1..676bfd81de 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -254,7 +254,7 @@ class Thread {
bool IsSuspended() const {
union StateAndFlags state_and_flags;
- state_and_flags.as_int = tls32_.state_and_flags.as_int;
+ state_and_flags.as_int = tls32_.state_and_flags.as_atomic_int.load(std::memory_order_relaxed);
return state_and_flags.as_struct.state != kRunnable &&
(state_and_flags.as_struct.flags & kSuspendRequest) != 0;
}
@@ -1517,6 +1517,9 @@ class Thread {
};
static_assert(sizeof(StateAndFlags) == sizeof(int32_t), "Weird state_and_flags size");
+ // Format state and flags as a hex string. For diagnostic output.
+ std::string StateAndFlagsAsHexString() const;
+
static void ThreadExitCallback(void* arg);
// Maximum number of suspend barriers.
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index f8e99e8f62..84b7384c46 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -874,10 +874,11 @@ static void ThreadSuspendByPeerWarning(Thread* self,
}
Thread* ThreadList::SuspendThreadByPeer(jobject peer,
- bool request_suspension,
SuspendReason reason,
bool* timed_out) {
+ bool request_suspension = true;
const uint64_t start_time = NanoTime();
+ int self_suspend_count = 0;
useconds_t sleep_us = kThreadSuspendInitialSleepUs;
*timed_out = false;
Thread* const self = Thread::Current();
@@ -926,6 +927,7 @@ Thread* ThreadList::SuspendThreadByPeer(jobject peer,
// We hold the suspend count lock but another thread is trying to suspend us. Its not
// safe to try to suspend another thread in case we get a cycle. Start the loop again
// which will allow this thread to be suspended.
+ ++self_suspend_count;
continue;
}
CHECK(suspended_thread == nullptr);
@@ -957,20 +959,22 @@ Thread* ThreadList::SuspendThreadByPeer(jobject peer,
}
const uint64_t total_delay = NanoTime() - start_time;
if (total_delay >= thread_suspend_timeout_ns_) {
- ThreadSuspendByPeerWarning(self,
- ::android::base::FATAL,
- "Thread suspension timed out",
- peer);
- if (suspended_thread != nullptr) {
+ if (suspended_thread == nullptr) {
+ ThreadSuspendByPeerWarning(self,
+ ::android::base::FATAL,
+ "Failed to issue suspend request",
+ peer);
+ } else {
CHECK_EQ(suspended_thread, thread);
- bool updated = suspended_thread->ModifySuspendCount(soa.Self(),
- -1,
- nullptr,
- reason);
- DCHECK(updated);
+ LOG(WARNING) << "Suspended thread state_and_flags: "
+ << suspended_thread->StateAndFlagsAsHexString()
+ << ", self_suspend_count = " << self_suspend_count;
+ ThreadSuspendByPeerWarning(self,
+ ::android::base::FATAL,
+ "Thread suspension timed out",
+ peer);
}
- *timed_out = true;
- return nullptr;
+ UNREACHABLE();
} else if (sleep_us == 0 &&
total_delay > static_cast<uint64_t>(kThreadSuspendMaxYieldUs) * 1000) {
// We have spun for kThreadSuspendMaxYieldUs time, switch to sleeps to prevent
diff --git a/runtime/thread_list.h b/runtime/thread_list.h
index 87a4c8dc61..f5b58a0c54 100644
--- a/runtime/thread_list.h
+++ b/runtime/thread_list.h
@@ -81,11 +81,8 @@ class ThreadList {
// Suspend a thread using a peer, typically used by the debugger. Returns the thread on success,
// else null. The peer is used to identify the thread to avoid races with the thread terminating.
- // If the thread should be suspended then value of request_suspension should be true otherwise
- // the routine will wait for a previous suspend request. If the suspension times out then *timeout
- // is set to true.
+ // If the suspension times out then *timeout is set to true.
Thread* SuspendThreadByPeer(jobject peer,
- bool request_suspension,
SuspendReason reason,
bool* timed_out)
REQUIRES(!Locks::mutator_lock_,
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index 29efd4016f..967167961c 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -192,7 +192,8 @@ const uint8_t* VdexFile::GetNextTypeLookupTableData(const uint8_t* cursor,
} else {
const uint8_t* data = cursor + sizeof(uint32_t) + reinterpret_cast<const uint32_t*>(cursor)[0];
// TypeLookupTables are required to be 4 byte aligned. the OatWriter makes sure they are.
- CHECK_ALIGNED(data, 4);
+ // We don't check this here to be defensive against corrupted vdex files.
+ // Callers should check the returned value matches their expectations.
return data;
}
}
diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h
index eb8b81742b..a66ff88fb2 100644
--- a/runtime/vdex_file.h
+++ b/runtime/vdex_file.h
@@ -157,8 +157,6 @@ class VdexFile {
return size;
}
- bool IsDexSectionValid() const;
-
bool HasDexSection() const {
return GetSectionHeader(VdexSection::kDexFileSection).section_size != 0u;
}
@@ -251,6 +249,9 @@ class VdexFile {
const uint8_t* Begin() const { return mmap_.Begin(); }
const uint8_t* End() const { return mmap_.End(); }
size_t Size() const { return mmap_.Size(); }
+ bool Contains(const uint8_t* pointer) const {
+ return pointer >= Begin() && pointer < End();
+ }
const VdexFileHeader& GetVdexFileHeader() const {
return *reinterpret_cast<const VdexFileHeader*>(Begin());
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc
index 1935d454f8..8aa47600bf 100644
--- a/sigchainlib/sigchain.cc
+++ b/sigchainlib/sigchain.cc
@@ -405,7 +405,7 @@ void SignalChain::Handler(int signo, siginfo_t* siginfo, void* ucontext_raw) {
if (handler == SIG_IGN) {
return;
} else if (handler == SIG_DFL) {
- fatal("exiting due to SIG_DFL handler for signal %d", signo);
+ fatal("exiting due to SIG_DFL handler for signal %d, ucontext %p", signo, ucontext);
} else {
handler(signo);
}
diff --git a/test/2011-stack-walk-concurrent-instrument/stack_walk_concurrent.cc b/test/2011-stack-walk-concurrent-instrument/stack_walk_concurrent.cc
index a185446ca5..a10fe2e905 100644
--- a/test/2011-stack-walk-concurrent-instrument/stack_walk_concurrent.cc
+++ b/test/2011-stack-walk-concurrent-instrument/stack_walk_concurrent.cc
@@ -81,7 +81,7 @@ extern "C" JNIEXPORT void JNICALL Java_Main_waitAndDeopt(JNIEnv*, jobject, jobje
}
bool timed_out = false;
Thread* other = Runtime::Current()->GetThreadList()->SuspendThreadByPeer(
- target, true, SuspendReason::kInternal, &timed_out);
+ target, SuspendReason::kInternal, &timed_out);
CHECK(!timed_out);
CHECK(other != nullptr);
ScopedSuspendAll ssa(__FUNCTION__);
diff --git a/test/826-infinite-loop/expected-stderr.txt b/test/826-infinite-loop/expected-stderr.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/826-infinite-loop/expected-stderr.txt
diff --git a/test/826-infinite-loop/expected-stdout.txt b/test/826-infinite-loop/expected-stdout.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/826-infinite-loop/expected-stdout.txt
diff --git a/test/826-infinite-loop/info.txt b/test/826-infinite-loop/info.txt
new file mode 100644
index 0000000000..13a89d8ca2
--- /dev/null
+++ b/test/826-infinite-loop/info.txt
@@ -0,0 +1,2 @@
+Regression test for partial escape elimination, which used to crash when
+visiting an infinite loop.
diff --git a/test/826-infinite-loop/src/Main.java b/test/826-infinite-loop/src/Main.java
new file mode 100644
index 0000000000..85bcb28baf
--- /dev/null
+++ b/test/826-infinite-loop/src/Main.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+final class Main {
+ public static void main(String[] args) {
+ Object o = new Object();
+ if (args.length == 0) {
+ while (true) {
+ System.out.println(new Object());
+ }
+ }
+ }
+}
diff --git a/test/831-unverified-bcp/expected-stderr.txt b/test/831-unverified-bcp/expected-stderr.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/831-unverified-bcp/expected-stderr.txt
diff --git a/test/831-unverified-bcp/expected-stdout.txt b/test/831-unverified-bcp/expected-stdout.txt
new file mode 100644
index 0000000000..6a5618ebc6
--- /dev/null
+++ b/test/831-unverified-bcp/expected-stdout.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/831-unverified-bcp/info.txt b/test/831-unverified-bcp/info.txt
new file mode 100644
index 0000000000..b4f7aebcad
--- /dev/null
+++ b/test/831-unverified-bcp/info.txt
@@ -0,0 +1,2 @@
+Regression test for class resolution, where the class linker would not check if
+an exception was pending after looking up a class in the boot classpath.
diff --git a/test/831-unverified-bcp/smali-ex/NonVerifiedClass.smali b/test/831-unverified-bcp/smali-ex/NonVerifiedClass.smali
new file mode 100644
index 0000000000..986f70a5cf
--- /dev/null
+++ b/test/831-unverified-bcp/smali-ex/NonVerifiedClass.smali
@@ -0,0 +1,23 @@
+# Copyright 2021 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.
+
+.class public LNonVerifiedClass;
+.super Ljava/util/Objects;
+
+.method public constructor <init>()V
+ .registers 1
+ invoke-direct {p0}, Ljava/util/Objects;-><init>()V
+ return-void
+.end method
+
diff --git a/test/831-unverified-bcp/src/Main.java b/test/831-unverified-bcp/src/Main.java
new file mode 100644
index 0000000000..853d8ed8d2
--- /dev/null
+++ b/test/831-unverified-bcp/src/Main.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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 dalvik.system.PathClassLoader;
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.util.Arrays;
+
+public class Main {
+
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[0]);
+ appendToBootClassLoader(OTHER_DEX, /* isCorePlatform */ false);
+
+ try {
+ Class.forName("NonVerifiedClass");
+ throw new Error("Expected VerifyError");
+ } catch (VerifyError e) {
+ // Expected.
+ }
+ }
+
+ private static native int appendToBootClassLoader(String dexPath, boolean isCorePlatform);
+
+ private static final String OTHER_DEX =
+ new File(System.getenv("DEX_LOCATION"), "831-unverified-bcp-ex.jar").getAbsolutePath();
+}
+
+// Define the class also in the classpath, to trigger the AssertNoPendingException crash.
+class NonVerifiedClass {
+}
diff --git a/test/art-gtests-target-standalone-template.xml b/test/art-gtests-target-standalone-template.xml
index d644aceac2..015b60ea9d 100644
--- a/test/art-gtests-target-standalone-template.xml
+++ b/test/art-gtests-target-standalone-template.xml
@@ -17,12 +17,12 @@
<configuration description="Runs {MODULE}.">
<target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
<option name="cleanup" value="true" />
- <option name="push" value="{MODULE}->/data/local/tmp/nativetest/{MODULE}" />
+ <option name="push" value="{MODULE}->/data/local/tmp/{MODULE}/{MODULE}" />
<option name="append-bitness" value="true" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
- <option name="native-test-device-path" value="/data/local/tmp/nativetest" />
+ <option name="native-test-device-path" value="/data/local/tmp/{MODULE}" />
<option name="module-name" value="{MODULE}" />
<option name="ld-library-path-32" value="/apex/com.android.art/lib" />
<option name="ld-library-path-64" value="/apex/com.android.art/lib64" />
diff --git a/test/knownfailures.json b/test/knownfailures.json
index d9b089d17a..dc968541cd 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1142,6 +1142,7 @@
"820-vdex-multidex",
"821-many-args",
"822-hiddenapi-future",
+ "831-unverified-bcp",
"999-redefine-hiddenapi",
"1000-non-moving-space-stress",
"1001-app-image-regions",
diff --git a/test/utils/regen-test-files b/test/utils/regen-test-files
index 588a2b02fb..3fe9bac545 100755
--- a/test/utils/regen-test-files
+++ b/test/utils/regen-test-files
@@ -462,6 +462,34 @@ presubmit_tests_percentage = 100
# This value has to be a number between 0 and 100.
mainline_presubmit_tests_percentage = 100
+# ART gtests that do not need root access to the device.
+art_gtest_user_module_names = [
+ "art_standalone_cmdline_tests",
+ "art_standalone_compiler_tests",
+ "art_standalone_dex2oat_tests",
+ "art_standalone_dexdump_tests",
+ "art_standalone_dexlist_tests",
+ "art_standalone_libartbase_tests",
+ "art_standalone_libartpalette_tests",
+ "art_standalone_libdexfile_support_tests",
+ "art_standalone_libdexfile_tests",
+ "art_standalone_libprofile_tests",
+ "art_standalone_oatdump_tests",
+ "art_standalone_odrefresh_tests",
+ "art_standalone_runtime_compiler_tests",
+ "art_standalone_runtime_tests",
+ "art_standalone_sigchain_tests",
+]
+
+# ART gtests that need root access to the device.
+art_gtest_eng_only_module_names = [
+ "art_standalone_dexoptanalyzer_tests",
+ "art_standalone_profman_tests",
+]
+
+# All supported ART gtests.
+art_gtest_module_names = sorted(art_gtest_user_module_names + art_gtest_eng_only_module_names)
+
# Is `run_test` a Checker test (i.e. a test containing Checker
# assertions)?
@@ -608,10 +636,12 @@ class Generator:
run_test_module_names = [ART_RUN_TEST_MODULE_NAME_PREFIX + t for t in art_run_tests]
# Mainline presubmits.
- mainline_presubmit_run_tests = [t + "[com.google.android.art.apex]"
- for t
- in run_test_module_names[0:num_mainline_presubmit_run_tests]]
- mainline_presubmit_tests_dict = [{"name": t} for t in mainline_presubmit_run_tests]
+ mainline_presubmit_run_tests = run_test_module_names[0:num_mainline_presubmit_run_tests]
+ mainline_presubmit_tests = mainline_presubmit_run_tests + art_gtest_module_names
+ mainline_presubmit_tests_with_apex = [t + "[com.google.android.art.apex]"
+ for t
+ in mainline_presubmit_tests]
+ mainline_presubmit_tests_dict = [{"name": t} for t in mainline_presubmit_tests_with_apex]
# Presubmits.
other_presubmit_tests = [
@@ -619,7 +649,7 @@ class Generator:
"BootImageProfileTest",
]
presubmit_run_tests = run_test_module_names[0:num_presubmit_run_tests]
- presubmit_tests = other_presubmit_tests + presubmit_run_tests
+ presubmit_tests = other_presubmit_tests + presubmit_run_tests + art_gtest_module_names
presubmit_tests_dict = [{"name": t} for t in presubmit_tests]
# Postsubmits.
@@ -910,13 +940,16 @@ class Generator:
print(f"Generated TEST_MAPPING entries for {len(expected_succeeding_tests)} ART run-tests out"
f" of {len(run_tests)} ({expected_succeeding_tests_percentage}%):")
- for (num_tests, tests_percentage, test_group_name) in [
- (num_mainline_presubmit_run_tests, mainline_presubmit_tests_percentage,
+ for (num_tests, test_kind, tests_percentage, test_group_name) in [
+ (num_mainline_presubmit_run_tests, "ART run-tests", mainline_presubmit_tests_percentage,
"mainline-presubmit"),
- (num_presubmit_run_tests, presubmit_tests_percentage, "presubmit"),
- (num_postsubmit_tests, postsubmit_tests_percentage, "postsubmit"),
+ (len(art_gtest_module_names), "ART gtests", 100, "mainline-presubmit"),
+ (num_presubmit_run_tests, "ART run-tests", presubmit_tests_percentage, "presubmit"),
+ (len(art_gtest_module_names), "ART gtests", 100, "presubmit"),
+ (num_postsubmit_tests, "ART run-tests", postsubmit_tests_percentage, "postsubmit"),
]:
- print(f" {num_tests} tests ({tests_percentage}%) in `{test_group_name}` test group.")
+ print(
+ f" {num_tests:3d} {test_kind} ({tests_percentage}%) in `{test_group_name}` test group.")
# Regenerate ART MTS definition (optional).
# -----------------------------------------