summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.common_path.mk17
-rw-r--r--build/Android.common_test.mk4
-rw-r--r--build/Android.gtest.mk5
-rw-r--r--build/apex/Android.bp13
-rw-r--r--build/apex/ld.config.txt1
-rw-r--r--compiler/debug/elf_debug_writer.cc79
-rw-r--r--compiler/debug/elf_debug_writer.h2
-rw-r--r--compiler/linker/elf_builder.h45
-rw-r--r--compiler/optimizing/optimizing_compiler.cc2
-rw-r--r--dex2oat/dex2oat_test.cc23
-rw-r--r--dex2oat/linker/image_test.h3
-rw-r--r--dexoptanalyzer/dexoptanalyzer_test.cc4
-rw-r--r--imgdiag/imgdiag_test.cc28
-rw-r--r--libartbase/base/common_art_test.cc46
-rw-r--r--libartbase/base/common_art_test.h6
-rw-r--r--oatdump/oatdump_test.h9
-rw-r--r--openjdkjvmti/ti_thread.cc3
-rw-r--r--runtime/arch/arm/instruction_set_features_arm.cc3
-rw-r--r--runtime/arch/arm64/instruction_set_features_arm64.cc14
-rw-r--r--runtime/common_runtime_test.cc44
-rw-r--r--runtime/common_runtime_test.h3
-rw-r--r--runtime/dexopt_test.cc24
-rw-r--r--runtime/gc/collector/concurrent_copying.cc8
-rw-r--r--runtime/gc/collector/garbage_collector.cc1
-rw-r--r--runtime/gc/heap.cc16
-rw-r--r--runtime/gc/heap.h18
-rw-r--r--runtime/gc/space/image_space.cc30
-rw-r--r--runtime/image.h8
-rw-r--r--runtime/native/dalvik_system_ZygoteHooks.cc38
-rw-r--r--runtime/runtime.cc26
-rw-r--r--runtime/runtime.h11
-rw-r--r--runtime/thread_pool.cc11
-rw-r--r--runtime/thread_pool.h18
-rw-r--r--test/118-noimage-dex2oat/run21
-rw-r--r--test/Android.run-test.mk2
-rwxr-xr-xtest/etc/run-test-jar45
-rwxr-xr-xtools/bootjars.sh26
-rw-r--r--tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeHandlerTest.java8
-rw-r--r--tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeMultiHandlerTest.java4
-rw-r--r--tools/class2greylist/test/src/com/android/class2greylist/UnsupportedAppUsageAnnotationHandlerTest.java36
-rw-r--r--tools/class2greylist/test/src/com/android/javac/Javac.java16
-rw-r--r--tools/libcore_failures.txt4
42 files changed, 423 insertions, 302 deletions
diff --git a/build/Android.common_path.mk b/build/Android.common_path.mk
index 96d3648ff6..03e68ae93c 100644
--- a/build/Android.common_path.mk
+++ b/build/Android.common_path.mk
@@ -74,18 +74,21 @@ HOST_CORE_IMG_LOCATION := $(HOST_OUT_JAVA_LIBRARIES)/core.art
TARGET_CORE_IMG_LOCATION := $(ART_TARGET_TEST_OUT)/core.art
# Jar files for core.art.
-HOST_CORE_DEX_LOCATIONS := $(foreach jar,$(HOST_CORE_JARS), $(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
+TEST_CORE_JARS := core-oj core-libart core-simple conscrypt okhttp bouncycastle
+HOST_TEST_CORE_JARS := $(addsuffix -hostdex,$(TEST_CORE_JARS))
+TARGET_TEST_CORE_JARS := $(addsuffix -testdex,$(TEST_CORE_JARS))
+HOST_CORE_DEX_LOCATIONS := $(foreach jar,$(HOST_TEST_CORE_JARS), $(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
ifeq ($(ART_TEST_ANDROID_ROOT),)
-TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_CORE_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
+TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_TEST_CORE_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
else
-TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_CORE_JARS),$(ART_TEST_ANDROID_ROOT)/framework/$(jar).jar)
+TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_TEST_CORE_JARS),$(ART_TEST_ANDROID_ROOT)/framework/$(jar).jar)
endif
-HOST_CORE_DEX_FILES := $(foreach jar,$(HOST_CORE_JARS), $(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),t,COMMON)/javalib.jar)
-TARGET_CORE_DEX_FILES := $(foreach jar,$(TARGET_CORE_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar), ,COMMON)/javalib.jar)
+HOST_CORE_DEX_FILES := $(foreach jar,$(HOST_TEST_CORE_JARS), $(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),t,COMMON)/javalib.jar)
+TARGET_CORE_DEX_FILES := $(foreach jar,$(TARGET_TEST_CORE_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar), ,COMMON)/javalib.jar)
-ART_HOST_DEX_DEPENDENCIES := $(foreach jar,$(HOST_CORE_JARS),$(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
-ART_TARGET_DEX_DEPENDENCIES := $(foreach jar,$(TARGET_CORE_JARS),$(TARGET_OUT_JAVA_LIBRARIES)/$(jar).jar)
+ART_HOST_DEX_DEPENDENCIES := $(foreach jar,$(HOST_TEST_CORE_JARS),$(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
+ART_TARGET_DEX_DEPENDENCIES := $(foreach jar,$(TARGET_TEST_CORE_JARS),$(TARGET_OUT_JAVA_LIBRARIES)/$(jar).jar)
ART_CORE_SHARED_LIBRARIES := libjavacore libopenjdk libopenjdkjvm libopenjdkjvmti
ART_CORE_SHARED_DEBUG_LIBRARIES := libopenjdkd libopenjdkjvmd libopenjdkjvmtid
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index 17d0232c04..d8014bd55f 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -129,7 +129,7 @@ define build-art-test-dex
LOCAL_DEX_PREOPT := false
LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_test.mk $(4)
LOCAL_MODULE_TAGS := tests
- LOCAL_JAVA_LIBRARIES := $(TARGET_CORE_JARS)
+ LOCAL_JAVA_LIBRARIES := $(TARGET_TEST_CORE_JARS)
LOCAL_MODULE_PATH := $(3)
LOCAL_DEX_PREOPT_IMAGE_LOCATION := $(TARGET_CORE_IMG_OUT)
ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
@@ -145,7 +145,7 @@ define build-art-test-dex
LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_DEX_PREOPT := false
LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_test.mk $(4)
- LOCAL_JAVA_LIBRARIES := $(HOST_CORE_JARS)
+ LOCAL_JAVA_LIBRARIES := $(HOST_TEST_CORE_JARS)
LOCAL_DEX_PREOPT_IMAGE := $(HOST_CORE_IMG_LOCATION)
ifneq ($(wildcard $(LOCAL_PATH)/$(2)/main.list),)
LOCAL_DX_FLAGS := --multi-dex --main-dex-list=$(LOCAL_PATH)/$(2)/main.list --minimal-main-dex
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 9a5e26b178..6885946c40 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -454,7 +454,10 @@ define define-art-gtest-rule-target
$$($(3)TARGET_OUT_SHARED_LIBRARIES)/libopenjdkd.so \
$$(TARGET_OUT_JAVA_LIBRARIES)/core-libart-testdex.jar \
$$(TARGET_OUT_JAVA_LIBRARIES)/core-oj-testdex.jar \
- $$(TARGET_OUT_JAVA_LIBRARIES)/core-simple-testdex.jar
+ $$(TARGET_OUT_JAVA_LIBRARIES)/core-simple-testdex.jar \
+ $$(TARGET_OUT_JAVA_LIBRARIES)/conscrypt-testdex.jar \
+ $$(TARGET_OUT_JAVA_LIBRARIES)/okhttp-testdex.jar \
+ $$(TARGET_OUT_JAVA_LIBRARIES)/bouncycastle-testdex.jar
ART_TEST_TARGET_GTEST_DEPENDENCIES += $$(gtest_deps)
diff --git a/build/apex/Android.bp b/build/apex/Android.bp
index 159e5c1992..f1a21e8428 100644
--- a/build/apex/Android.bp
+++ b/build/apex/Android.bp
@@ -72,6 +72,13 @@ apex_key {
private_key: "com.android.runtime.pem",
}
+prebuilt_etc {
+ name: "com.android.runtime.ld.config.txt",
+ src: "ld.config.txt",
+ filename: "ld.config.txt",
+ installable: false,
+}
+
// TODO: Introduce `apex_defaults` to factor common parts of `apex`
// module definitions below?
@@ -97,9 +104,8 @@ apex {
binaries: [],
}
},
+ prebuilts: ["com.android.runtime.ld.config.txt"],
key: "com.android.runtime.key",
- // TODO: Also package a `ld.config.txt` config file (to be placed in `etc/`).
- // ...
}
// "Debug" version of the Runtime APEX module (containing both release and
@@ -126,7 +132,6 @@ apex {
binaries: art_tools_binaries,
}
},
+ prebuilts: ["com.android.runtime.ld.config.txt"],
key: "com.android.runtime.key",
- // TODO: Also package a `ld.config.txt` config file (to be placed in `etc/`).
- // ...
}
diff --git a/build/apex/ld.config.txt b/build/apex/ld.config.txt
new file mode 100644
index 0000000000..ac4d1eb81f
--- /dev/null
+++ b/build/apex/ld.config.txt
@@ -0,0 +1 @@
+# TODO: Write me.
diff --git a/compiler/debug/elf_debug_writer.cc b/compiler/debug/elf_debug_writer.cc
index 71422d48a5..baf8643e9b 100644
--- a/compiler/debug/elf_debug_writer.cc
+++ b/compiler/debug/elf_debug_writer.cc
@@ -16,8 +16,9 @@
#include "elf_debug_writer.h"
-#include <vector>
+#include <type_traits>
#include <unordered_map>
+#include <vector>
#include "base/array_ref.h"
#include "debug/dwarf/dwarf_constants.h"
@@ -29,6 +30,7 @@
#include "debug/elf_symtab_writer.h"
#include "debug/method_debug_info.h"
#include "debug/xz_utils.h"
+#include "elf.h"
#include "linker/elf_builder.h"
#include "linker/vector_output_stream.h"
#include "oat.h"
@@ -36,6 +38,8 @@
namespace art {
namespace debug {
+using ElfRuntimeTypes = std::conditional<sizeof(void*) == 4, ElfTypes32, ElfTypes64>::type;
+
template <typename ElfTypes>
void WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder,
const DebugInfo& debug_info,
@@ -165,22 +169,16 @@ std::vector<uint8_t> MakeMiniDebugInfo(
}
}
-template <typename ElfTypes>
-static std::vector<uint8_t> MakeElfFileForJITInternal(
+std::vector<uint8_t> MakeElfFileForJIT(
InstructionSet isa,
const InstructionSetFeatures* features,
bool mini_debug_info,
- ArrayRef<const MethodDebugInfo> method_infos) {
- CHECK_GT(method_infos.size(), 0u);
- uint64_t min_address = std::numeric_limits<uint64_t>::max();
- uint64_t max_address = 0;
- for (const MethodDebugInfo& mi : method_infos) {
- CHECK_EQ(mi.is_code_address_text_relative, false);
- min_address = std::min(min_address, mi.code_address);
- max_address = std::max(max_address, mi.code_address + mi.code_size);
- }
+ const MethodDebugInfo& method_info) {
+ using ElfTypes = ElfRuntimeTypes;
+ CHECK_EQ(sizeof(ElfTypes::Addr), static_cast<size_t>(GetInstructionSetPointerSize(isa)));
+ CHECK_EQ(method_info.is_code_address_text_relative, false);
DebugInfo debug_info{};
- debug_info.compiled_methods = method_infos;
+ debug_info.compiled_methods = ArrayRef<const MethodDebugInfo>(&method_info, 1);
std::vector<uint8_t> buffer;
buffer.reserve(KB);
linker::VectorOutputStream out("Debug ELF file", &buffer);
@@ -188,28 +186,16 @@ static std::vector<uint8_t> MakeElfFileForJITInternal(
new linker::ElfBuilder<ElfTypes>(isa, features, &out));
// No program headers since the ELF file is not linked and has no allocated sections.
builder->Start(false /* write_program_headers */);
+ builder->GetText()->AllocateVirtualMemory(method_info.code_address, method_info.code_size);
if (mini_debug_info) {
- if (method_infos.size() > 1) {
- std::vector<uint8_t> mdi = MakeMiniDebugInfo(isa,
- features,
- min_address,
- max_address - min_address,
- /* dex_section_address */ 0,
- /* dex_section_size */ 0,
- debug_info);
- builder->WriteSection(".gnu_debugdata", &mdi);
- } else {
- // The compression is great help for multiple methods but it is not worth it for a
- // single method due to the overheads so skip the compression here for performance.
- builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address);
- WriteDebugSymbols(builder.get(), true /* mini-debug-info */, debug_info);
- WriteCFISection(builder.get(),
- debug_info.compiled_methods,
- dwarf::DW_DEBUG_FRAME_FORMAT,
- false /* write_oat_paches */);
- }
+ // The compression is great help for multiple methods but it is not worth it for a
+ // single method due to the overheads so skip the compression here for performance.
+ WriteDebugSymbols(builder.get(), true /* mini-debug-info */, debug_info);
+ WriteCFISection(builder.get(),
+ debug_info.compiled_methods,
+ dwarf::DW_DEBUG_FRAME_FORMAT,
+ false /* write_oat_paches */);
} else {
- builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address);
WriteDebugInfo(builder.get(),
debug_info,
dwarf::DW_DEBUG_FRAME_FORMAT,
@@ -220,24 +206,13 @@ static std::vector<uint8_t> MakeElfFileForJITInternal(
return buffer;
}
-std::vector<uint8_t> MakeElfFileForJIT(
- InstructionSet isa,
- const InstructionSetFeatures* features,
- bool mini_debug_info,
- ArrayRef<const MethodDebugInfo> method_infos) {
- if (Is64BitInstructionSet(isa)) {
- return MakeElfFileForJITInternal<ElfTypes64>(isa, features, mini_debug_info, method_infos);
- } else {
- return MakeElfFileForJITInternal<ElfTypes32>(isa, features, mini_debug_info, method_infos);
- }
-}
-
-template <typename ElfTypes>
-static std::vector<uint8_t> WriteDebugElfFileForClassesInternal(
+std::vector<uint8_t> WriteDebugElfFileForClasses(
InstructionSet isa,
const InstructionSetFeatures* features,
const ArrayRef<mirror::Class*>& types)
REQUIRES_SHARED(Locks::mutator_lock_) {
+ using ElfTypes = ElfRuntimeTypes;
+ CHECK_EQ(sizeof(ElfTypes::Addr), static_cast<size_t>(GetInstructionSetPointerSize(isa)));
std::vector<uint8_t> buffer;
buffer.reserve(KB);
linker::VectorOutputStream out("Debug ELF file", &buffer);
@@ -256,16 +231,6 @@ static std::vector<uint8_t> WriteDebugElfFileForClassesInternal(
return buffer;
}
-std::vector<uint8_t> WriteDebugElfFileForClasses(InstructionSet isa,
- const InstructionSetFeatures* features,
- const ArrayRef<mirror::Class*>& types) {
- if (Is64BitInstructionSet(isa)) {
- return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, features, types);
- } else {
- return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, features, types);
- }
-}
-
// Explicit instantiations
template void WriteDebugInfo<ElfTypes32>(
linker::ElfBuilder<ElfTypes32>* builder,
diff --git a/compiler/debug/elf_debug_writer.h b/compiler/debug/elf_debug_writer.h
index e442e0016c..8ad0c4219a 100644
--- a/compiler/debug/elf_debug_writer.h
+++ b/compiler/debug/elf_debug_writer.h
@@ -54,7 +54,7 @@ std::vector<uint8_t> MakeElfFileForJIT(
InstructionSet isa,
const InstructionSetFeatures* features,
bool mini_debug_info,
- ArrayRef<const MethodDebugInfo> method_infos);
+ const MethodDebugInfo& method_info);
std::vector<uint8_t> WriteDebugElfFileForClasses(
InstructionSet isa,
diff --git a/compiler/linker/elf_builder.h b/compiler/linker/elf_builder.h
index 81ecc175b5..44f3296e90 100644
--- a/compiler/linker/elf_builder.h
+++ b/compiler/linker/elf_builder.h
@@ -18,6 +18,7 @@
#define ART_COMPILER_LINKER_ELF_BUILDER_H_
#include <vector>
+#include <deque>
#include "arch/instruction_set.h"
#include "arch/mips/instruction_set_features_mips.h"
@@ -357,57 +358,49 @@ class ElfBuilder final {
}
// Buffer symbol for this section. It will be written later.
- // If the symbol's section is null, it will be considered absolute (SHN_ABS).
- // (we use this in JIT to reference code which is stored outside the debug ELF file)
void Add(Elf_Word name,
const Section* section,
Elf_Addr addr,
Elf_Word size,
uint8_t binding,
uint8_t type) {
- Elf_Word section_index;
- if (section != nullptr) {
- DCHECK_LE(section->GetAddress(), addr);
- DCHECK_LE(addr, section->GetAddress() + section->header_.sh_size);
- section_index = section->GetSectionIndex();
- } else {
- section_index = static_cast<Elf_Word>(SHN_ABS);
- }
- Add(name, section_index, addr, size, binding, type);
- }
-
- // Buffer symbol for this section. It will be written later.
- void Add(Elf_Word name,
- Elf_Word section_index,
- Elf_Addr addr,
- Elf_Word size,
- uint8_t binding,
- uint8_t type) {
Elf_Sym sym = Elf_Sym();
sym.st_name = name;
sym.st_value = addr;
sym.st_size = size;
sym.st_other = 0;
- sym.st_shndx = section_index;
sym.st_info = (binding << 4) + (type & 0xf);
- syms_.push_back(sym);
+ Add(sym, section);
+ }
+
+ // Buffer symbol for this section. It will be written later.
+ void Add(Elf_Sym sym, const Section* section) {
+ DCHECK(section != nullptr);
+ DCHECK_LE(section->GetAddress(), sym.st_value);
+ DCHECK_LE(sym.st_value, section->GetAddress() + section->header_.sh_size);
+ sym.st_shndx = section->GetSectionIndex();
// The sh_info file must be set to index one-past the last local symbol.
- if (binding == STB_LOCAL) {
- this->header_.sh_info = syms_.size();
+ if (sym.getBinding() == STB_LOCAL) {
+ DCHECK_EQ(syms_.back().getBinding(), STB_LOCAL);
+ this->header_.sh_info = syms_.size() + 1;
}
+
+ syms_.push_back(sym);
}
Elf_Word GetCacheSize() { return syms_.size() * sizeof(Elf_Sym); }
void WriteCachedSection() {
this->Start();
- this->WriteFully(syms_.data(), syms_.size() * sizeof(Elf_Sym));
+ for (; !syms_.empty(); syms_.pop_front()) {
+ this->WriteFully(&syms_.front(), sizeof(Elf_Sym));
+ }
this->End();
}
private:
- std::vector<Elf_Sym> syms_; // Buffered/cached content of the whole section.
+ std::deque<Elf_Sym> syms_; // Buffered/cached content of the whole section.
};
class AbiflagsSection final : public Section {
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc
index 1d3fcf3002..641368b87a 100644
--- a/compiler/optimizing/optimizing_compiler.cc
+++ b/compiler/optimizing/optimizing_compiler.cc
@@ -1469,7 +1469,7 @@ void OptimizingCompiler::GenerateJitDebugInfo(
compiler_options.GetInstructionSet(),
compiler_options.GetInstructionSetFeatures(),
mini_debug_info,
- ArrayRef<const debug::MethodDebugInfo>(&info, 1));
+ info);
MutexLock mu(Thread::Current(), *Locks::native_debug_interface_lock_);
AddNativeDebugInfoForJit(reinterpret_cast<const void*>(info.code_address), elf_file);
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 97a5f2453e..92dd9328b3 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -192,24 +192,12 @@ class Dex2oatTest : public Dex2oatEnvironmentTest {
}
int Dex2Oat(const std::vector<std::string>& dex2oat_args, std::string* error_msg) {
- Runtime* runtime = Runtime::Current();
-
- const std::vector<gc::space::ImageSpace*>& image_spaces =
- runtime->GetHeap()->GetBootImageSpaces();
- if (image_spaces.empty()) {
- *error_msg = "No image location found for Dex2Oat.";
- return false;
- }
- std::string image_location = image_spaces[0]->GetImageLocation();
-
std::vector<std::string> argv;
- argv.push_back(runtime->GetCompilerExecutable());
-
- if (runtime->IsJavaDebuggable()) {
- argv.push_back("--debuggable");
+ if (!CommonRuntimeTest::StartDex2OatCommandLine(&argv, error_msg)) {
+ return false;
}
- runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
+ Runtime* runtime = Runtime::Current();
if (!runtime->IsVerificationEnabled()) {
argv.push_back("--compiler-filter=assume-verified");
}
@@ -226,11 +214,6 @@ class Dex2oatTest : public Dex2oatEnvironmentTest {
argv.push_back("--host");
}
- argv.push_back("--boot-image=" + image_location);
-
- std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
- argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());
-
argv.insert(argv.end(), dex2oat_args.begin(), dex2oat_args.end());
// We must set --android-root.
diff --git a/dex2oat/linker/image_test.h b/dex2oat/linker/image_test.h
index 844a72803e..6ffcef12a7 100644
--- a/dex2oat/linker/image_test.h
+++ b/dex2oat/linker/image_test.h
@@ -442,6 +442,9 @@ inline void ImageTest::TestWriteRead(ImageHeader::StorageMode storage_mode,
MemMap::Init();
RuntimeOptions options;
+ options.emplace_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()), nullptr);
+ options.emplace_back(
+ GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()), nullptr);
std::string image("-Ximage:");
image.append(helper.image_locations[0].GetFilename());
options.push_back(std::make_pair(image.c_str(), static_cast<void*>(nullptr)));
diff --git a/dexoptanalyzer/dexoptanalyzer_test.cc b/dexoptanalyzer/dexoptanalyzer_test.cc
index b9116f0fb8..f6fd1fb014 100644
--- a/dexoptanalyzer/dexoptanalyzer_test.cc
+++ b/dexoptanalyzer/dexoptanalyzer_test.cc
@@ -46,6 +46,10 @@ class DexoptAnalyzerTest : public DexoptTest {
if (assume_profile_changed) {
argv_str.push_back("--assume-profile-changed");
}
+ argv_str.push_back("--runtime-arg");
+ argv_str.push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
+ argv_str.push_back("--runtime-arg");
+ argv_str.push_back(GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
argv_str.push_back("--image=" + GetImageLocation());
argv_str.push_back("--android-data=" + android_data_);
diff --git a/imgdiag/imgdiag_test.cc b/imgdiag/imgdiag_test.cc
index 73df2a2b03..739d9b8329 100644
--- a/imgdiag/imgdiag_test.cc
+++ b/imgdiag/imgdiag_test.cc
@@ -34,12 +34,8 @@
namespace art {
-static const char* kImgDiagDiffPid = "--image-diff-pid";
-static const char* kImgDiagBootImage = "--boot-image";
static const char* kImgDiagBinaryName = "imgdiag";
-static const char* kImgDiagZygoteDiffPid = "--zygote-diff-pid";
-
// from kernel <include/linux/threads.h>
#define PID_MAX_LIMIT (4*1024*1024) // Upper bound. Most kernel configs will have smaller max pid.
@@ -93,25 +89,15 @@ class ImgDiagTest : public CommonRuntimeTest {
EXPECT_TRUE(OS::FileExists(file_path.c_str())) << file_path << " should be a valid file path";
// Run imgdiag --image-diff-pid=$image_diff_pid and wait until it's done with a 0 exit code.
- std::string diff_pid_args;
- std::string zygote_diff_pid_args;
- {
- std::stringstream diff_pid_args_ss;
- diff_pid_args_ss << kImgDiagDiffPid << "=" << image_diff_pid;
- diff_pid_args = diff_pid_args_ss.str();
- }
- {
- std::stringstream zygote_pid_args_ss;
- zygote_pid_args_ss << kImgDiagZygoteDiffPid << "=" << image_diff_pid;
- zygote_diff_pid_args = zygote_pid_args_ss.str();
- }
- std::string boot_image_args = std::string(kImgDiagBootImage) + "=" + boot_image;
-
std::vector<std::string> exec_argv = {
file_path,
- diff_pid_args,
- zygote_diff_pid_args,
- boot_image_args
+ "--image-diff-pid=" + std::to_string(image_diff_pid),
+ "--zygote-diff-pid=" + std::to_string(image_diff_pid),
+ "--runtime-arg",
+ GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()),
+ "--runtime-arg",
+ GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()),
+ "--boot-image=" + boot_image
};
return ::art::Exec(exec_argv, error_msg);
diff --git a/libartbase/base/common_art_test.cc b/libartbase/base/common_art_test.cc
index 5a0b425bca..278203da23 100644
--- a/libartbase/base/common_art_test.cc
+++ b/libartbase/base/common_art_test.cc
@@ -24,6 +24,7 @@
#include "nativehelper/scoped_local_ref.h"
#include "android-base/stringprintf.h"
+#include "android-base/strings.h"
#include "android-base/unique_fd.h"
#include <unicode/uvernum.h>
@@ -328,9 +329,48 @@ static std::string GetDexFileName(const std::string& jar_prefix, bool host) {
}
std::vector<std::string> CommonArtTestImpl::GetLibCoreDexFileNames() {
- return std::vector<std::string>({GetDexFileName("core-oj", IsHost()),
- GetDexFileName("core-libart", IsHost()),
- GetDexFileName("core-simple", IsHost())});
+ // Note: This must match the TEST_CORE_JARS in Android.common_path.mk
+ // because that's what we use for compiling the core.art image.
+ static const char* const kLibcoreModules[] = {
+ "core-oj",
+ "core-libart",
+ "core-simple",
+ "conscrypt",
+ "okhttp",
+ "bouncycastle",
+ };
+
+ std::vector<std::string> result;
+ result.reserve(arraysize(kLibcoreModules));
+ for (const char* module : kLibcoreModules) {
+ result.push_back(GetDexFileName(module, IsHost()));
+ }
+ return result;
+}
+
+std::vector<std::string> CommonArtTestImpl::GetLibCoreDexLocations() {
+ std::vector<std::string> result = GetLibCoreDexFileNames();
+ if (IsHost()) {
+ // Strip the ANDROID_BUILD_TOP directory including the directory separator '/'.
+ const char* host_dir = getenv("ANDROID_BUILD_TOP");
+ CHECK(host_dir != nullptr);
+ std::string prefix = host_dir;
+ CHECK(!prefix.empty());
+ if (prefix.back() != '/') {
+ prefix += '/';
+ }
+ for (std::string& location : result) {
+ CHECK_GT(location.size(), prefix.size());
+ CHECK_EQ(location.compare(0u, prefix.size(), prefix), 0);
+ location.erase(0u, prefix.size());
+ }
+ }
+ return result;
+}
+
+std::string CommonArtTestImpl::GetClassPathOption(const char* option,
+ const std::vector<std::string>& class_path) {
+ return option + android::base::Join(class_path, ':');
}
std::string CommonArtTestImpl::GetTestAndroidRoot() {
diff --git a/libartbase/base/common_art_test.h b/libartbase/base/common_art_test.h
index 0f4800dfc5..3e2340f0a7 100644
--- a/libartbase/base/common_art_test.h
+++ b/libartbase/base/common_art_test.h
@@ -99,6 +99,12 @@ class CommonArtTestImpl {
// Gets the paths of the libcore dex files.
static std::vector<std::string> GetLibCoreDexFileNames();
+ // Gets the locations of the libcore dex files.
+ static std::vector<std::string> GetLibCoreDexLocations();
+
+ static std::string GetClassPathOption(const char* option,
+ const std::vector<std::string>& class_path);
+
// Returns bin directory which contains host's prebuild tools.
static std::string GetAndroidHostToolsDir();
diff --git a/oatdump/oatdump_test.h b/oatdump/oatdump_test.h
index 4ee510130b..728939f93c 100644
--- a/oatdump/oatdump_test.h
+++ b/oatdump/oatdump_test.h
@@ -122,6 +122,10 @@ class OatDumpTest : public CommonRuntimeTest {
"-Xmx512m",
"--runtime-arg",
"-Xnorelocate",
+ "--runtime-arg",
+ GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()),
+ "--runtime-arg",
+ GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()),
"--boot-image=" + GetCoreArtLocation(),
"--instruction-set=" + std::string(GetInstructionSetString(kRuntimeISA)),
"--dex-file=" + GetTestDexFileName(GetAppBaseName().c_str()),
@@ -181,6 +185,11 @@ class OatDumpTest : public CommonRuntimeTest {
expected_prefixes.push_back("IMAGE BEGIN:");
expected_prefixes.push_back("kDexCaches:");
} else if (mode == kModeOatWithBootImage) {
+ exec_argv.push_back("--runtime-arg");
+ exec_argv.push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
+ exec_argv.push_back("--runtime-arg");
+ exec_argv.push_back(
+ GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
exec_argv.push_back("--boot-image=" + GetCoreArtLocation());
exec_argv.push_back("--instruction-set=" + std::string(
GetInstructionSetString(kRuntimeISA)));
diff --git a/openjdkjvmti/ti_thread.cc b/openjdkjvmti/ti_thread.cc
index 2131120a11..051db4c67e 100644
--- a/openjdkjvmti/ti_thread.cc
+++ b/openjdkjvmti/ti_thread.cc
@@ -91,7 +91,8 @@ struct ThreadCallback : public art::ThreadLifecycleCallback {
self->GetThreadName(name);
if (name != "JDWP" &&
name != "Signal Catcher" &&
- !android::base::StartsWith(name, "Jit thread pool")) {
+ !android::base::StartsWith(name, "Jit thread pool") &&
+ !android::base::StartsWith(name, "Runtime worker thread")) {
LOG(FATAL) << "Unexpected thread before start: " << name << " id: "
<< self->GetThreadId();
}
diff --git a/runtime/arch/arm/instruction_set_features_arm.cc b/runtime/arch/arm/instruction_set_features_arm.cc
index e97d2cbd92..58ae394fb4 100644
--- a/runtime/arch/arm/instruction_set_features_arm.cc
+++ b/runtime/arch/arm/instruction_set_features_arm.cc
@@ -54,7 +54,8 @@ ArmFeaturesUniquePtr ArmInstructionSetFeatures::FromVariant(
"cortex-a76",
"exynos-m1",
"denver",
- "kryo"
+ "kryo",
+ "kryo385",
};
bool has_armv8a = FindVariantInArray(arm_variants_with_armv8a,
arraysize(arm_variants_with_armv8a),
diff --git a/runtime/arch/arm64/instruction_set_features_arm64.cc b/runtime/arch/arm64/instruction_set_features_arm64.cc
index 7796ca7745..963c207842 100644
--- a/runtime/arch/arm64/instruction_set_features_arm64.cc
+++ b/runtime/arch/arm64/instruction_set_features_arm64.cc
@@ -57,10 +57,6 @@ Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromVariant(
static const char* arm64_variants_with_crc[] = {
"default",
"generic",
- "kryo",
- "exynos-m1",
- "exynos-m2",
- "exynos-m3",
"cortex-a35",
"cortex-a53",
"cortex-a53.a57",
@@ -71,18 +67,25 @@ Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromVariant(
"cortex-a55",
"cortex-a75",
"cortex-a76",
+ "exynos-m1",
+ "exynos-m2",
+ "exynos-m3",
+ "kryo",
+ "kryo385",
};
static const char* arm64_variants_with_lse[] = {
"cortex-a55",
"cortex-a75",
"cortex-a76",
+ "kryo385",
};
static const char* arm64_variants_with_fp16[] = {
"cortex-a55",
"cortex-a75",
"cortex-a76",
+ "kryo385",
};
static const char* arm64_variants_with_dotprod[] = {
@@ -124,7 +127,8 @@ Arm64FeaturesUniquePtr Arm64InstructionSetFeatures::FromVariant(
"exynos-m2",
"exynos-m3",
"denver64",
- "kryo"
+ "kryo",
+ "kryo385",
};
if (!FindVariantInArray(arm64_known_variants, arraysize(arm64_known_variants), variant)) {
std::ostringstream os;
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 0300fa155f..a101976a87 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -44,6 +44,7 @@
#include "dex/dex_file_loader.h"
#include "dex/primitive.h"
#include "gc/heap.h"
+#include "gc/space/image_space.h"
#include "gc_root-inl.h"
#include "gtest/gtest.h"
#include "handle_scope-inl.h"
@@ -111,15 +112,14 @@ void CommonRuntimeTestImpl::SetUp() {
std::string min_heap_string(StringPrintf("-Xms%zdm", gc::Heap::kDefaultInitialSize / MB));
std::string max_heap_string(StringPrintf("-Xmx%zdm", gc::Heap::kDefaultMaximumSize / MB));
-
RuntimeOptions options;
- std::string boot_class_path_string = "-Xbootclasspath";
- for (const std::string &core_dex_file_name : GetLibCoreDexFileNames()) {
- boot_class_path_string += ":";
- boot_class_path_string += core_dex_file_name;
- }
+ std::string boot_class_path_string =
+ GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames());
+ std::string boot_class_path_locations_string =
+ GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations());
options.push_back(std::make_pair(boot_class_path_string, nullptr));
+ options.push_back(std::make_pair(boot_class_path_locations_string, nullptr));
options.push_back(std::make_pair("-Xcheck:jni", nullptr));
options.push_back(std::make_pair(min_heap_string, nullptr));
options.push_back(std::make_pair(max_heap_string, nullptr));
@@ -386,6 +386,38 @@ void CommonRuntimeTestImpl::SetUpRuntimeOptionsForFillHeap(RuntimeOptions *optio
}
}
+bool CommonRuntimeTestImpl::StartDex2OatCommandLine(/*out*/std::vector<std::string>* argv,
+ /*out*/std::string* error_msg) {
+ DCHECK(argv != nullptr);
+ DCHECK(argv->empty());
+
+ Runtime* runtime = Runtime::Current();
+ const std::vector<gc::space::ImageSpace*>& image_spaces =
+ runtime->GetHeap()->GetBootImageSpaces();
+ if (image_spaces.empty()) {
+ *error_msg = "No image location found for Dex2Oat.";
+ return false;
+ }
+ std::string image_location = image_spaces[0]->GetImageLocation();
+
+ argv->push_back(runtime->GetCompilerExecutable());
+ if (runtime->IsJavaDebuggable()) {
+ argv->push_back("--debuggable");
+ }
+ runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(argv);
+
+ argv->push_back("--runtime-arg");
+ argv->push_back(GetClassPathOption("-Xbootclasspath:", GetLibCoreDexFileNames()));
+ argv->push_back("--runtime-arg");
+ argv->push_back(GetClassPathOption("-Xbootclasspath-locations:", GetLibCoreDexLocations()));
+
+ argv->push_back("--boot-image=" + image_location);
+
+ std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
+ argv->insert(argv->end(), compiler_options.begin(), compiler_options.end());
+ return true;
+}
+
CheckJniAbortCatcher::CheckJniAbortCatcher() : vm_(Runtime::Current()->GetJavaVM()) {
vm_->SetCheckJniAbortHook(Hook, &actual_);
}
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 0fee797015..319c7c7111 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -97,6 +97,9 @@ class CommonRuntimeTestImpl : public CommonArtTestImpl {
return true;
}
+ static bool StartDex2OatCommandLine(/*out*/std::vector<std::string>* argv,
+ /*out*/std::string* error_msg);
+
protected:
// Allow subclases such as CommonCompilerTest to add extra options.
virtual void SetUpRuntimeOptions(RuntimeOptions* options ATTRIBUTE_UNUSED) {}
diff --git a/runtime/dexopt_test.cc b/runtime/dexopt_test.cc
index f52a0f9430..b46c93383e 100644
--- a/runtime/dexopt_test.cc
+++ b/runtime/dexopt_test.cc
@@ -46,26 +46,13 @@ void DexoptTest::PostRuntimeCreate() {
ReserveImageSpace();
}
-static std::string ImageLocation() {
- Runtime* runtime = Runtime::Current();
- const std::vector<gc::space::ImageSpace*>& image_spaces =
- runtime->GetHeap()->GetBootImageSpaces();
- if (image_spaces.empty()) {
- return "";
- }
- return image_spaces[0]->GetImageLocation();
-}
-
bool DexoptTest::Dex2Oat(const std::vector<std::string>& args, std::string* error_msg) {
- Runtime* runtime = Runtime::Current();
-
std::vector<std::string> argv;
- argv.push_back(runtime->GetCompilerExecutable());
- if (runtime->IsJavaDebuggable()) {
- argv.push_back("--debuggable");
+ if (!CommonRuntimeTest::StartDex2OatCommandLine(&argv, error_msg)) {
+ return false;
}
- runtime->AddCurrentRuntimeFeaturesAsDex2OatArguments(&argv);
+ Runtime* runtime = Runtime::Current();
if (runtime->GetHiddenApiEnforcementPolicy() != hiddenapi::EnforcementPolicy::kDisabled) {
argv.push_back("--runtime-arg");
argv.push_back("-Xhidden-api-checks");
@@ -75,11 +62,6 @@ bool DexoptTest::Dex2Oat(const std::vector<std::string>& args, std::string* erro
argv.push_back("--host");
}
- argv.push_back("--boot-image=" + ImageLocation());
-
- std::vector<std::string> compiler_options = runtime->GetCompilerOptions();
- argv.insert(argv.end(), compiler_options.begin(), compiler_options.end());
-
argv.insert(argv.end(), args.begin(), args.end());
std::string command_line(android::base::Join(argv, ' '));
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index d4275a0224..7736568620 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -2065,6 +2065,9 @@ void ConcurrentCopying::ReclaimPhase() {
LOG(INFO) << "(after) num_bytes_allocated="
<< heap_->num_bytes_allocated_.load();
}
+
+ float reclaimed_bytes_ratio = static_cast<float>(freed_bytes) / num_bytes_allocated_before_gc_;
+ reclaimed_bytes_ratio_sum_ += reclaimed_bytes_ratio;
}
{
@@ -2080,11 +2083,6 @@ void ConcurrentCopying::ReclaimPhase() {
CheckEmptyMarkStack();
- int64_t num_bytes_allocated_after_gc = static_cast<int64_t>(heap_->GetBytesAllocated());
- int64_t diff = num_bytes_allocated_before_gc_ - num_bytes_allocated_after_gc;
- auto ratio = static_cast<float>(diff) / num_bytes_allocated_before_gc_;
- reclaimed_bytes_ratio_sum_ += ratio;
-
if (kVerboseMode) {
LOG(INFO) << "GC end of ReclaimPhase";
}
diff --git a/runtime/gc/collector/garbage_collector.cc b/runtime/gc/collector/garbage_collector.cc
index 8477c9de2c..46ff7dc820 100644
--- a/runtime/gc/collector/garbage_collector.cc
+++ b/runtime/gc/collector/garbage_collector.cc
@@ -90,6 +90,7 @@ void GarbageCollector::Run(GcCause gc_cause, bool clear_soft_references) {
Thread* self = Thread::Current();
uint64_t start_time = NanoTime();
uint64_t thread_cpu_start_time = ThreadCpuNanoTime();
+ GetHeap()->CalculateWeightedAllocatedBytes();
Iteration* current_iteration = GetCurrentIteration();
current_iteration->Reset(gc_cause, clear_soft_references);
// Note transaction mode is single-threaded and there's no asynchronous GC and this flag doesn't
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index f767360066..86135c1bc2 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -210,6 +210,9 @@ Heap::Heap(size_t initial_size,
low_memory_mode_(low_memory_mode),
long_pause_log_threshold_(long_pause_log_threshold),
long_gc_log_threshold_(long_gc_log_threshold),
+ process_cpu_start_time_ns_(ProcessCpuNanoTime()),
+ last_process_cpu_time_ns_(process_cpu_start_time_ns_),
+ weighted_allocated_bytes_(0u),
ignore_max_footprint_(ignore_max_footprint),
zygote_creation_lock_("zygote creation lock", kZygoteCreationLock),
zygote_space_(nullptr),
@@ -1062,6 +1065,14 @@ void Heap::RemoveSpace(space::Space* space) {
}
}
+void Heap::CalculateWeightedAllocatedBytes() {
+ uint64_t current_process_cpu_time = ProcessCpuNanoTime();
+ uint64_t bytes_allocated = GetBytesAllocated();
+ uint64_t weight = current_process_cpu_time - last_process_cpu_time_ns_;
+ weighted_allocated_bytes_ += weight * bytes_allocated;
+ last_process_cpu_time_ns_ = current_process_cpu_time;
+}
+
uint64_t Heap::GetTotalGcCpuTime() {
uint64_t sum = 0;
for (auto* collector : garbage_collectors_) {
@@ -1139,6 +1150,11 @@ void Heap::ResetGcPerformanceInfo() {
for (auto* collector : garbage_collectors_) {
collector->ResetMeasurements();
}
+
+ process_cpu_start_time_ns_ = ProcessCpuNanoTime();
+ last_process_cpu_time_ns_ = process_cpu_start_time_ns_;
+ weighted_allocated_bytes_ = 0u;
+
total_bytes_freed_ever_ = 0;
total_objects_freed_ever_ = 0;
total_wait_time_ = 0;
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index a43f3156f5..411a4469d9 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -395,8 +395,17 @@ class Heap {
REQUIRES(!Locks::heap_bitmap_lock_)
REQUIRES(Locks::mutator_lock_);
+ uint64_t GetWeightedAllocatedBytes() const {
+ return weighted_allocated_bytes_;
+ }
+
+ void CalculateWeightedAllocatedBytes();
uint64_t GetTotalGcCpuTime();
+ uint64_t GetProcessCpuStartTime() const {
+ return process_cpu_start_time_ns_;
+ }
+
// Set target ideal heap utilization ratio, implements
// dalvik.system.VMRuntime.setTargetHeapUtilization.
void SetTargetHeapUtilization(float target);
@@ -1161,6 +1170,15 @@ class Heap {
// If we get a GC longer than long GC log threshold, then we print out the GC after it finishes.
const size_t long_gc_log_threshold_;
+ // Starting time of the new process; meant to be used for measuring total process CPU time.
+ uint64_t process_cpu_start_time_ns_;
+
+ // Last time GC started; meant to be used to measure the duration between two GCs.
+ uint64_t last_process_cpu_time_ns_;
+
+ // allocated_bytes * (current_process_cpu_time - last_process_cpu_time)
+ uint64_t weighted_allocated_bytes_;
+
// If we ignore the max footprint it lets the heap grow until it hits the heap capacity, this is
// useful for benchmarking since it reduces time spent in GC to a low %.
const bool ignore_max_footprint_;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index c772bdab18..e494bd681d 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -627,16 +627,36 @@ class ImageSpace::Loader {
return MemMap::Invalid();
}
memcpy(map.Begin(), &image_header, sizeof(ImageHeader));
+
const uint64_t start = NanoTime();
+ ThreadPool* pool = Runtime::Current()->GetThreadPool();
+ Thread* const self = Thread::Current();
+ const size_t kMinBlocks = 2;
+ const bool use_parallel = pool != nullptr &&image_header.GetBlockCount() >= kMinBlocks;
for (const ImageHeader::Block& block : image_header.GetBlocks(temp_map.Begin())) {
- TimingLogger::ScopedTiming timing2("LZ4 decompress image", logger);
- if (!block.Decompress(/*out_ptr=*/map.Begin(), /*in_ptr=*/temp_map.Begin(), error_msg)) {
- if (error_msg != nullptr) {
- *error_msg = "Failed to decompress image block " + *error_msg;
+ auto function = [&](Thread*) {
+ const uint64_t start2 = NanoTime();
+ ScopedTrace trace("LZ4 decompress block");
+ if (!block.Decompress(/*out_ptr=*/map.Begin(),
+ /*in_ptr=*/temp_map.Begin(),
+ error_msg)) {
+ if (error_msg != nullptr) {
+ *error_msg = "Failed to decompress image block " + *error_msg;
+ }
}
- return MemMap::Invalid();
+ VLOG(image) << "Decompress block " << block.GetDataSize() << " -> "
+ << block.GetImageSize() << " in " << PrettyDuration(NanoTime() - start2);
+ };
+ if (use_parallel) {
+ pool->AddTask(self, new FunctionTask(std::move(function)));
+ } else {
+ function(self);
}
}
+ if (use_parallel) {
+ ScopedTrace trace("Waiting for workers");
+ pool->Wait(self, true, false);
+ }
const uint64_t time = NanoTime() - start;
// Add one 1 ns to prevent possible divide by 0.
VLOG(image) << "Decompressing image took " << PrettyDuration(time) << " ("
diff --git a/runtime/image.h b/runtime/image.h
index 76fb3b70c9..9d98431183 100644
--- a/runtime/image.h
+++ b/runtime/image.h
@@ -116,6 +116,14 @@ class PACKED(8) ImageHeader {
return storage_mode_;
}
+ uint32_t GetDataSize() const {
+ return data_size_;
+ }
+
+ uint32_t GetImageSize() const {
+ return image_size_;
+ }
+
private:
// Storage method for the image, the image may be compressed.
StorageMode storage_mode_ = kDefaultStorageMode;
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index 530371d4c4..0f655b94de 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -44,10 +44,6 @@
#include "thread_list.h"
#include "trace.h"
-#if defined(__linux__)
-#include <sys/prctl.h>
-#endif
-
#include <sys/resource.h>
namespace art {
@@ -59,37 +55,6 @@ static bool kAlwaysCollectNonDebuggableClasses =
using android::base::StringPrintf;
-static void EnableDebugger() {
-#if defined(__linux__)
- // To let a non-privileged gdbserver attach to this
- // process, we must set our dumpable flag.
- if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
- PLOG(ERROR) << "prctl(PR_SET_DUMPABLE) failed for pid " << getpid();
- }
-
- // Even if Yama is on a non-privileged native debugger should
- // be able to attach to the debuggable app.
- if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0) == -1) {
- // if Yama is off prctl(PR_SET_PTRACER) returns EINVAL - don't log in this
- // case since it's expected behaviour.
- if (errno != EINVAL) {
- PLOG(ERROR) << "prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) failed for pid " << getpid();
- }
- }
-#endif
- // We don't want core dumps, though, so set the soft limit on core dump size
- // to 0 without changing the hard limit.
- rlimit rl;
- if (getrlimit(RLIMIT_CORE, &rl) == -1) {
- PLOG(ERROR) << "getrlimit(RLIMIT_CORE) failed for pid " << getpid();
- } else {
- rl.rlim_cur = 0;
- if (setrlimit(RLIMIT_CORE, &rl) == -1) {
- PLOG(ERROR) << "setrlimit(RLIMIT_CORE) failed for pid " << getpid();
- }
- }
-}
-
class ClassSet {
public:
// The number of classes we reasonably expect to have to look at. Realistically the number is more
@@ -211,9 +176,6 @@ static uint32_t EnableDebugFeatures(uint32_t runtime_flags) {
}
Dbg::SetJdwpAllowed((runtime_flags & DEBUG_ENABLE_JDWP) != 0);
- if ((runtime_flags & DEBUG_ENABLE_JDWP) != 0) {
- EnableDebugger();
- }
runtime_flags &= ~DEBUG_ENABLE_JDWP;
const bool safe_mode = (runtime_flags & DEBUG_ENABLE_SAFEMODE) != 0;
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index ab79b9e1a0..84526f3332 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -34,6 +34,7 @@
#include <cstdio>
#include <cstdlib>
#include <limits>
+#include <thread>
#include <vector>
#include "android-base/strings.h"
@@ -278,7 +279,6 @@ Runtime::Runtime()
// Initially assume we perceive jank in case the process state is never updated.
process_state_(kProcessStateJankPerceptible),
zygote_no_threads_(false),
- process_cpu_start_time_(ProcessCpuNanoTime()),
verifier_logging_threshold_ms_(100) {
static_assert(Runtime::kCalleeSaveSize ==
static_cast<uint32_t>(CalleeSaveType::kLastCalleeSaveType), "Unexpected size");
@@ -322,20 +322,26 @@ Runtime::~Runtime() {
}
if (dump_gc_performance_on_shutdown_) {
- process_cpu_end_time_ = ProcessCpuNanoTime();
+ heap_->CalculateWeightedAllocatedBytes();
+ uint64_t process_cpu_end_time = ProcessCpuNanoTime();
ScopedLogSeverity sls(LogSeverity::INFO);
// This can't be called from the Heap destructor below because it
// could call RosAlloc::InspectAll() which needs the thread_list
// to be still alive.
heap_->DumpGcPerformanceInfo(LOG_STREAM(INFO));
- uint64_t process_cpu_time = process_cpu_end_time_ - process_cpu_start_time_;
+ uint64_t process_cpu_time = process_cpu_end_time - heap_->GetProcessCpuStartTime();
uint64_t gc_cpu_time = heap_->GetTotalGcCpuTime();
float ratio = static_cast<float>(gc_cpu_time) / process_cpu_time;
LOG_STREAM(INFO) << "GC CPU time " << PrettyDuration(gc_cpu_time)
<< " out of process CPU time " << PrettyDuration(process_cpu_time)
<< " (" << ratio << ")"
<< "\n";
+ float weighted_allocated_bytes =
+ static_cast<float>(heap_->GetWeightedAllocatedBytes()) / process_cpu_time;
+ LOG_STREAM(INFO) << "Weighted bytes allocated over CPU time: "
+ << " (" << PrettySize(weighted_allocated_bytes) << ")"
+ << "\n";
}
if (jit_ != nullptr) {
@@ -388,6 +394,11 @@ Runtime::~Runtime() {
jit_->DeleteThreadPool();
}
+ // Thread pools must be deleted before the runtime shuts down to avoid hanging.
+ if (thread_pool_ != nullptr) {
+ thread_pool_.reset();
+ }
+
// Make sure our internal threads are dead before we start tearing down things they're using.
GetRuntimeCallbacks()->StopDebugger();
delete signal_catcher_;
@@ -910,6 +921,15 @@ void Runtime::InitNonZygoteOrPostFork(
jit_->CreateThreadPool();
}
+ if (thread_pool_ == nullptr) {
+ constexpr size_t kStackSize = 64 * KB;
+ constexpr size_t kMaxRuntimeWorkers = 4u;
+ const size_t num_workers =
+ std::min(static_cast<size_t>(std::thread::hardware_concurrency()), kMaxRuntimeWorkers);
+ thread_pool_.reset(new ThreadPool("Runtime", num_workers, /*create_peers=*/false, kStackSize));
+ thread_pool_->StartWorkers(Thread::Current());
+ }
+
// Create the thread pools.
heap_->CreateThreadPool();
// Reset the gc performance data at zygote fork so that the GCs
diff --git a/runtime/runtime.h b/runtime/runtime.h
index 0ccc7b79bf..c74647e465 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -99,6 +99,7 @@ class SignalCatcher;
class StackOverflowHandler;
class SuspensionHandler;
class ThreadList;
+class ThreadPool;
class Trace;
struct TraceConfig;
class Transaction;
@@ -789,6 +790,10 @@ class Runtime {
return verifier_logging_threshold_ms_;
}
+ ThreadPool* GetThreadPool() {
+ return thread_pool_.get();
+ }
+
private:
static void InitPlatformSignalHandlers();
@@ -882,6 +887,9 @@ class Runtime {
// Shared linear alloc for now.
std::unique_ptr<LinearAlloc> linear_alloc_;
+ // Thread pool
+ std::unique_ptr<ThreadPool> thread_pool_;
+
// The number of spins that are done before thread suspension is used to forcibly inflate.
size_t max_spins_before_thin_lock_inflation_;
MonitorList* monitor_list_;
@@ -1101,9 +1109,6 @@ class Runtime {
MemMap protected_fault_page_;
- uint64_t process_cpu_start_time_;
- uint64_t process_cpu_end_time_;
-
uint32_t verifier_logging_threshold_ms_;
DISALLOW_COPY_AND_ASSIGN(Runtime);
diff --git a/runtime/thread_pool.cc b/runtime/thread_pool.cc
index 8723c99706..0f96510e86 100644
--- a/runtime/thread_pool.cc
+++ b/runtime/thread_pool.cc
@@ -123,7 +123,10 @@ void ThreadPool::RemoveAllTasks(Thread* self) {
tasks_.clear();
}
-ThreadPool::ThreadPool(const char* name, size_t num_threads, bool create_peers)
+ThreadPool::ThreadPool(const char* name,
+ size_t num_threads,
+ bool create_peers,
+ size_t worker_stack_size)
: name_(name),
task_queue_lock_("task queue lock"),
task_queue_condition_("task queue condition", task_queue_lock_),
@@ -137,15 +140,13 @@ ThreadPool::ThreadPool(const char* name, size_t num_threads, bool create_peers)
creation_barier_(num_threads + 1),
max_active_workers_(num_threads),
create_peers_(create_peers) {
- Thread* self = Thread::Current();
while (GetThreadCount() < num_threads) {
const std::string worker_name = StringPrintf("%s worker thread %zu", name_.c_str(),
GetThreadCount());
- threads_.push_back(
- new ThreadPoolWorker(this, worker_name, ThreadPoolWorker::kDefaultStackSize));
+ threads_.push_back(new ThreadPoolWorker(this, worker_name, worker_stack_size));
}
// Wait for all of the threads to attach.
- creation_barier_.Wait(self);
+ creation_barier_.Wait(Thread::Current());
}
void ThreadPool::SetMaxActiveWorkers(size_t threads) {
diff --git a/runtime/thread_pool.h b/runtime/thread_pool.h
index 98a1193e72..fee009b7c0 100644
--- a/runtime/thread_pool.h
+++ b/runtime/thread_pool.h
@@ -18,6 +18,7 @@
#define ART_RUNTIME_THREAD_POOL_H_
#include <deque>
+#include <functional>
#include <vector>
#include "barrier.h"
@@ -48,6 +49,18 @@ class SelfDeletingTask : public Task {
}
};
+class FunctionTask : public SelfDeletingTask {
+ public:
+ explicit FunctionTask(std::function<void(Thread*)>&& func) : func_(std::move(func)) {}
+
+ void Run(Thread* self) override {
+ func_(self);
+ }
+
+ private:
+ std::function<void(Thread*)> func_;
+};
+
class ThreadPoolWorker {
public:
static const size_t kDefaultStackSize = 1 * MB;
@@ -110,7 +123,10 @@ class ThreadPool {
// If create_peers is true, all worker threads will have a Java peer object. Note that if the
// pool is asked to do work on the current thread (see Wait), a peer may not be available. Wait
// will conservatively abort if create_peers and do_work are true.
- ThreadPool(const char* name, size_t num_threads, bool create_peers = false);
+ ThreadPool(const char* name,
+ size_t num_threads,
+ bool create_peers = false,
+ size_t worker_stack_size = ThreadPoolWorker::kDefaultStackSize);
virtual ~ThreadPool();
// Wait for all tasks currently on queue to get completed. If the pool has been stopped, only
diff --git a/test/118-noimage-dex2oat/run b/test/118-noimage-dex2oat/run
index d68b0a0b2c..d1b9725628 100644
--- a/test/118-noimage-dex2oat/run
+++ b/test/118-noimage-dex2oat/run
@@ -31,39 +31,26 @@ if [[ "${flags}" == *--no-relocate* ]] ; then
exit 1
fi
-if [[ $@ == *--host* ]]; then
- framework="${ANDROID_HOST_OUT}/framework"
- bpath_suffix="-hostdex"
-else
- framework="/system/framework"
- bpath_suffix=""
-fi
-bpath="${framework}/core-libart${bpath_suffix}.jar"
-bpath="${bpath}:${framework}/conscrypt${bpath_suffix}.jar"
-bpath="${bpath}:${framework}/okhttp${bpath_suffix}.jar"
-bpath="${bpath}:${framework}/bouncycastle${bpath_suffix}.jar"
-bpath_arg="--runtime-option -Xbootclasspath:${bpath}"
-
# Make sure we can run without an oat file.
echo "Run -Xnoimage-dex2oat"
-${RUN} ${flags} ${bpath_arg} --runtime-option -Xnoimage-dex2oat
+${RUN} ${flags} --runtime-option -Xnoimage-dex2oat
return_status1=$?
# Make sure we cannot run without an oat file without fallback.
echo "Run -Xnoimage-dex2oat -Xno-dex-file-fallback"
-${RUN} ${flags} ${bpath_arg} --runtime-option -Xnoimage-dex2oat \
+${RUN} ${flags} --runtime-option -Xnoimage-dex2oat \
--runtime-option -Xno-dex-file-fallback
return_status2=$?
# Make sure we can run with the oat file.
echo "Run -Ximage-dex2oat"
-${RUN} ${flags} ${bpath_arg} --runtime-option -Ximage-dex2oat
+${RUN} ${flags} --runtime-option -Ximage-dex2oat
return_status3=$?
# Make sure we can run with the default settings.
echo "Run default"
-${RUN} ${flags} ${bpath_arg}
+${RUN} ${flags}
return_status4=$?
# Make sure we don't silently ignore an early failure.
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 148aea48ae..5d07601005 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -50,9 +50,9 @@ ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += libopenjdkjvmti-target libopenjdkjvmtid
ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += $(TARGET_OUT_JAVA_LIBRARIES)/core-libart-testdex.jar
ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += $(TARGET_OUT_JAVA_LIBRARIES)/core-oj-testdex.jar
ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += $(TARGET_OUT_JAVA_LIBRARIES)/core-simple-testdex.jar
+ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += $(TARGET_OUT_JAVA_LIBRARIES)/conscrypt-testdex.jar
ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += $(TARGET_OUT_JAVA_LIBRARIES)/okhttp-testdex.jar
ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += $(TARGET_OUT_JAVA_LIBRARIES)/bouncycastle-testdex.jar
-ART_TEST_TARGET_RUN_TEST_DEPENDENCIES += $(TARGET_OUT_JAVA_LIBRARIES)/conscrypt-testdex.jar
# All tests require the host executables. The tests also depend on the core images, but on
# specific version depending on the compiler.
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index ac6002bcea..4e5152b135 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -541,23 +541,38 @@ if [ "$USE_JVM" = "y" ]; then
exit
fi
-
-if [ "$HAVE_IMAGE" = "n" ]; then
- if [ "${HOST}" = "y" ]; then
- framework="${ANDROID_HOST_OUT}/framework"
- bpath_suffix="-hostdex"
+bpath_modules="core-oj core-libart core-simple conscrypt okhttp bouncycastle"
+if [ "${HOST}" = "y" ]; then
+ framework="${ANDROID_HOST_OUT}/framework"
+ if [ "${ANDROID_HOST_OUT:0:${#ANDROID_BUILD_TOP}+1}" = "${ANDROID_BUILD_TOP}/" ]; then
+ framework_location="${ANDROID_HOST_OUT:${#ANDROID_BUILD_TOP}+1}/framework"
else
- framework="${ANDROID_ROOT}/framework"
- bpath_suffix="-testdex"
+ echo "error: ANDROID_BUILD_TOP/ is not a prefix of ANDROID_HOST_OUT"
+ echo "ANDROID_BUILD_TOP=${ANDROID_BUILD_TOP}"
+ echo "ANDROID_HOST_OUT=${ANDROID_HOST_OUT}"
+ exit
fi
- bpath="${framework}/core-libart${bpath_suffix}.jar"
- bpath="${bpath}:${framework}/core-oj${bpath_suffix}.jar"
- bpath="${bpath}:${framework}/core-simple${bpath_suffix}.jar"
- bpath="${bpath}:${framework}/conscrypt${bpath_suffix}.jar"
- bpath="${bpath}:${framework}/okhttp${bpath_suffix}.jar"
- bpath="${bpath}:${framework}/bouncycastle${bpath_suffix}.jar"
- # Pass down the bootclasspath
- FLAGS="${FLAGS} -Xbootclasspath:${bpath}"
+ bpath_suffix="-hostdex"
+else
+ framework="${ANDROID_ROOT}/framework"
+ framework_location="${ANDROID_ROOT}/framework"
+ bpath_suffix="-testdex"
+fi
+bpath=""
+bpath_locations=""
+bpath_separator=""
+for bpath_module in ${bpath_modules}; do
+ bpath+="${bpath_separator}${framework}/${bpath_module}${bpath_suffix}.jar"
+ bpath_locations+="${bpath_separator}${framework_location}/${bpath_module}${bpath_suffix}.jar"
+ bpath_separator=":"
+done
+# Pass down the bootclasspath
+FLAGS="${FLAGS} -Xbootclasspath:${bpath}"
+FLAGS="${FLAGS} -Xbootclasspath-locations:${bpath_locations}"
+COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xbootclasspath:${bpath}"
+COMPILE_FLAGS="${COMPILE_FLAGS} --runtime-arg -Xbootclasspath-locations:${bpath_locations}"
+
+if [ "$HAVE_IMAGE" = "n" ]; then
# Disable image dex2oat - this will forbid the runtime to patch or compile an image.
FLAGS="${FLAGS} -Xnoimage-dex2oat"
diff --git a/tools/bootjars.sh b/tools/bootjars.sh
index dca209d580..ad6ee6b058 100755
--- a/tools/bootjars.sh
+++ b/tools/bootjars.sh
@@ -54,7 +54,7 @@ done
if [[ $mode == target ]]; then
if [[ $core_jars_only == y ]]; then
- selected_env_var=TARGET_CORE_JARS
+ selected_env_var=TARGET_TEST_CORE_JARS
else
selected_env_var=PRODUCT_BOOT_JARS
fi
@@ -64,11 +64,31 @@ elif [[ $mode == host ]]; then
echo "Error: --host does not have non-core boot jars, --core required" >&2
exit 1
fi
- selected_env_var=HOST_CORE_JARS
+ selected_env_var=HOST_TEST_CORE_JARS
intermediates_env_var=HOST_OUT_COMMON_INTERMEDIATES
fi
-boot_jars_list=$(get_build_var "$selected_env_var")
+if [[ $core_jars_only == y ]]; then
+ # FIXME: The soong invocation we're using for getting the variables does not give us anything
+ # defined in Android.common_path.mk, otherwise we would just use HOST-/TARGET_TEST_CORE_JARS.
+
+ # The core_jars_list must match the TEST_CORE_JARS variable in the Android.common_path.mk .
+ core_jars_list="core-oj core-libart core-simple conscrypt okhttp bouncycastle"
+ core_jars_suffix=
+ if [[ $mode == target ]]; then
+ core_jars_suffix=-testdex
+ elif [[ $mode == host ]]; then
+ core_jars_suffix=-hostdex
+ fi
+ boot_jars_list=""
+ boot_separator=""
+ for boot_module in ${core_jars_list}; do
+ boot_jars_list+="${boot_separator}${boot_module}${core_jars_suffix}"
+ boot_separator=" "
+ done
+else
+ boot_jars_list=$(get_build_var "$selected_env_var")
+fi
# Print only the list of boot jars.
if [[ $print_file_path == n ]]; then
diff --git a/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeHandlerTest.java b/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeHandlerTest.java
index 9d2f014e4e..9f924b2716 100644
--- a/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeHandlerTest.java
+++ b/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeHandlerTest.java
@@ -67,7 +67,7 @@ public class CovariantReturnTypeHandlerTest extends AnnotationHandlerTestBase {
" @Annotation(returnType=Integer.class)",
" public String method() {return null;}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION,
@@ -91,7 +91,7 @@ public class CovariantReturnTypeHandlerTest extends AnnotationHandlerTestBase {
" @Annotation(returnType=Integer.class)",
" public String method() {return null;}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION,
@@ -113,7 +113,7 @@ public class CovariantReturnTypeHandlerTest extends AnnotationHandlerTestBase {
" @Annotation(returnType=Integer.class)",
" public String method() {return null;}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION,
@@ -138,7 +138,7 @@ public class CovariantReturnTypeHandlerTest extends AnnotationHandlerTestBase {
" @Annotation(returnType=Integer.class)",
" public String field;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION,
diff --git a/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeMultiHandlerTest.java b/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeMultiHandlerTest.java
index 1202564948..25f284455b 100644
--- a/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeMultiHandlerTest.java
+++ b/tools/class2greylist/test/src/com/android/class2greylist/CovariantReturnTypeMultiHandlerTest.java
@@ -74,7 +74,7 @@ public class CovariantReturnTypeMultiHandlerTest extends AnnotationHandlerTestBa
" @Annotation(returnType=Long.class)",
" public String method() {return null;}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of("Lannotation/Annotation$Multi;",
@@ -104,7 +104,7 @@ public class CovariantReturnTypeMultiHandlerTest extends AnnotationHandlerTestBa
" @Annotation(returnType=Long.class)",
" public String method() {return null;}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of("Lannotation/Annotation$Multi;",
diff --git a/tools/class2greylist/test/src/com/android/class2greylist/UnsupportedAppUsageAnnotationHandlerTest.java b/tools/class2greylist/test/src/com/android/class2greylist/UnsupportedAppUsageAnnotationHandlerTest.java
index cdf01afe7c..dc767fe3f5 100644
--- a/tools/class2greylist/test/src/com/android/class2greylist/UnsupportedAppUsageAnnotationHandlerTest.java
+++ b/tools/class2greylist/test/src/com/android/class2greylist/UnsupportedAppUsageAnnotationHandlerTest.java
@@ -82,7 +82,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno",
" public void method() {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -103,7 +103,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno",
" public Class() {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -124,7 +124,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno",
" public int i;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -145,7 +145,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(expectedSignature=\"La/b/Class;->method()V\")",
" public void method() {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -166,7 +166,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(expectedSignature=\"La/b/Class;->nomethod()V\")",
" public void method() {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -186,7 +186,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" public void method() {}",
" }",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class$Inner"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -205,7 +205,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
"public class Class {",
" public void method() {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -224,7 +224,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(expectedSignature=\"La/b/Class;->method(Ljava/lang/String;)V\")",
" public void method(T arg) {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP))
@@ -252,7 +252,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(expectedSignature=\"La/b/Class;->method(Ljava/lang/String;)V\")",
" public void method(T arg) {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP));
@@ -284,7 +284,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(expectedSignature=\"La/b/Class;->method(Ljava/lang/String;)V\")",
" public void method(T arg) {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP));
@@ -320,7 +320,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
"package a.b;",
"public class Class extends Base implements Interface {",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP));
@@ -354,7 +354,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno",
" public void method(T arg) {}",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Set<String> publicApis = Sets.newHashSet(
"La/b/Base;->method(Ljava/lang/Object;)V",
@@ -385,7 +385,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(expectedSignature=\"La/b/Class;->field:I\")",
" public volatile int field;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(
@@ -407,7 +407,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(expectedSignature=\"La/b/Class;->wrong:I\")",
" public volatile int field;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(x -> true, NULL_SDK_MAP));
@@ -424,7 +424,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(maxTargetSdk=1)",
" public int field;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(
@@ -444,7 +444,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno",
" public int field;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(
@@ -464,7 +464,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno(maxTargetSdk=2)",
" public int field;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
Map<String, AnnotationHandler> handlerMap =
ImmutableMap.of(ANNOTATION, createGreylistHandler(
@@ -493,7 +493,7 @@ public class UnsupportedAppUsageAnnotationHandlerTest extends AnnotationHandlerT
" @Anno2(maxTargetSdk=2, trackingBug=123456789)",
" public int field;",
"}"));
- assertThat(mJavac.compile()).isTrue();
+ mJavac.compile();
new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), mStatus,
ImmutableMap.of("Lannotation/Anno2;", createGreylistHandler(x -> true,
ImmutableMap.of(2, "flag2")))
diff --git a/tools/class2greylist/test/src/com/android/javac/Javac.java b/tools/class2greylist/test/src/com/android/javac/Javac.java
index 202f4121fc..94e4e49ea8 100644
--- a/tools/class2greylist/test/src/com/android/javac/Javac.java
+++ b/tools/class2greylist/test/src/com/android/javac/Javac.java
@@ -18,6 +18,7 @@ package com.android.javac;
import com.google.common.io.Files;
+import java.util.stream.Collectors;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
@@ -76,15 +77,24 @@ public class Javac {
return this;
}
- public boolean compile() {
+ public void compile() {
+ DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
JavaCompiler.CompilationTask task = mJavac.getTask(
null,
mFileMan,
- null,
+ diagnosticCollector,
null,
null,
mCompilationUnits);
- return task.call();
+ boolean result = task.call();
+ if (!result) {
+ throw new IllegalStateException(
+ "Compilation failed:" +
+ diagnosticCollector.getDiagnostics()
+ .stream()
+ .map(Object::toString)
+ .collect(Collectors.joining("\n")));
+ }
}
public InputStream getClassFile(String classname) throws IOException {
diff --git a/tools/libcore_failures.txt b/tools/libcore_failures.txt
index a5fa332050..f97dd4fc7f 100644
--- a/tools/libcore_failures.txt
+++ b/tools/libcore_failures.txt
@@ -157,7 +157,6 @@
{
description: "Missing resource in classpath",
result: EXEC_FAILED,
- modes: [device],
names: ["libcore.java.util.prefs.OldAbstractPreferencesTest#testClear",
"libcore.java.util.prefs.OldAbstractPreferencesTest#testExportNode",
"libcore.java.util.prefs.OldAbstractPreferencesTest#testExportSubtree",
@@ -187,7 +186,8 @@
"org.apache.harmony.tests.java.util.prefs.AbstractPreferencesTest#testExportSubtree",
"org.apache.harmony.tests.java.util.prefs.AbstractPreferencesTest#testFlush",
"org.apache.harmony.tests.java.util.prefs.AbstractPreferencesTest#testSync",
- "org.apache.harmony.tests.java.util.prefs.FilePreferencesImplTest#testPutGet"]
+ "org.apache.harmony.tests.java.util.prefs.FilePreferencesImplTest#testPutGet"],
+ bug: 120526172
},
{
description: "Only work with --mode=activity",