summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/Android.bp36
-rw-r--r--build/Android.gtest.mk2
-rw-r--r--compiler/common_compiler_test.cc58
-rw-r--r--compiler/common_compiler_test.h3
-rw-r--r--compiler/compiler.h6
-rw-r--r--compiler/dex/dex_to_dex_decompiler_test.cc2
-rw-r--r--compiler/driver/compiler_driver.cc134
-rw-r--r--compiler/driver/compiler_driver.h55
-rw-r--r--compiler/driver/compiler_driver_test.cc4
-rw-r--r--compiler/driver/compiler_options.cc15
-rw-r--r--compiler/driver/compiler_options.h24
-rw-r--r--compiler/optimizing/inliner.cc27
-rw-r--r--compiler/optimizing/instruction_builder.cc2
-rw-r--r--compiler/optimizing/sharpening.cc28
-rw-r--r--compiler/optimizing/sharpening.h1
-rw-r--r--compiler/verifier_deps_test.cc2
-rw-r--r--dex2oat/dex2oat.cc86
-rw-r--r--dex2oat/dex2oat_options.cc8
-rw-r--r--dex2oat/dex2oat_options.def2
-rw-r--r--dex2oat/dex2oat_options.h1
-rw-r--r--dex2oat/linker/image_test.h55
-rw-r--r--dex2oat/linker/image_writer.cc39
-rw-r--r--dex2oat/linker/oat_writer.cc36
-rw-r--r--dex2oat/linker/oat_writer.h26
-rw-r--r--dex2oat/linker/oat_writer_test.cc4
-rw-r--r--libdexfile/dex/dex_file-inl.h4
-rw-r--r--libdexfile/dex/dex_file.h2
-rw-r--r--runtime/Android.bp10
-rw-r--r--runtime/base/mutex-inl.h4
-rw-r--r--runtime/base/mutex.h5
-rw-r--r--runtime/class_linker.cc16
-rw-r--r--runtime/gc/collector/concurrent_copying.cc6
-rw-r--r--runtime/gc/heap.cc1
-rw-r--r--runtime/hprof/hprof.cc1
-rw-r--r--runtime/interpreter/unstarted_runtime.cc16
-rw-r--r--runtime/jit/profiling_info_test.cc1
-rw-r--r--runtime/mirror/class.cc16
-rw-r--r--runtime/mirror/object-inl.h98
-rw-r--r--runtime/mirror/object-readbarrier-inl.h58
-rw-r--r--runtime/mirror/object.h60
-rw-r--r--runtime/mirror/var_handle.cc47
-rw-r--r--runtime/native/sun_misc_Unsafe.cc8
-rw-r--r--runtime/read_barrier-inl.h14
-rw-r--r--runtime/thread.cc2
-rw-r--r--test/003-omnibus-opcodes/build24
-rwxr-xr-xtest/004-JniTest/build40
-rw-r--r--test/004-ReferenceMap/build29
-rw-r--r--test/004-ReferenceMap/classes.dexbin0 -> 1108 bytes
-rw-r--r--test/004-StackWalk/build28
-rw-r--r--test/004-StackWalk/classes.dexbin0 -> 3912 bytes
-rw-r--r--test/005-annotations/build34
-rw-r--r--test/056-const-string-jumbo/build8
-rw-r--r--[-rwxr-xr-x]test/066-mismatched-super/build (renamed from test/442-checker-constant-folding/build)7
-rw-r--r--test/089-many-methods/build11
-rwxr-xr-xtest/089-many-methods/check6
-rw-r--r--test/089-many-methods/expected.txt7
-rwxr-xr-xtest/091-override-package-private-method/build25
-rw-r--r--test/111-unresolvable-exception/build27
-rw-r--r--test/113-multidex/build37
-rw-r--r--test/113-multidex/src-multidex/Main.java (renamed from test/113-multidex/src/Main.java)0
-rw-r--r--test/124-missing-classes/build28
-rw-r--r--test/126-miranda-multidex/build39
-rwxr-xr-xtest/127-checker-secondarydex/build31
-rwxr-xr-xtest/138-duplicate-classes-check2/build32
-rw-r--r--test/1948-obsolete-const-method-handle/build4
-rw-r--r--test/303-verification-stress/build9
-rw-r--r--test/638-no-line-number/build5
-rw-r--r--test/638-no-line-number/expected.txt2
-rwxr-xr-xtest/712-varhandle-invocations/build6
-rw-r--r--test/715-clinit-implicit-parameter-annotations/build4
-rw-r--r--test/804-class-extends-itself/build (renamed from test/022-interface/build)14
-rwxr-xr-xtest/952-invoke-custom/build72
-rw-r--r--test/952-invoke-custom/util-src/annotations/BootstrapMethod.java (renamed from test/952-invoke-custom/src/annotations/BootstrapMethod.java)0
-rw-r--r--test/952-invoke-custom/util-src/annotations/CalledByIndy.java (renamed from test/952-invoke-custom/src/annotations/CalledByIndy.java)0
-rw-r--r--test/952-invoke-custom/util-src/annotations/Constant.java (renamed from test/952-invoke-custom/src/annotations/Constant.java)0
-rw-r--r--test/952-invoke-custom/util-src/transformer/IndyTransformer.java (renamed from test/952-invoke-custom/src/transformer/IndyTransformer.java)7
-rwxr-xr-xtest/961-default-iface-resolution-gen/build3
-rwxr-xr-xtest/964-default-iface-init-gen/build3
-rwxr-xr-xtest/979-const-method-handle/build69
-rw-r--r--test/Android.run-test.mk6
-rwxr-xr-xtest/etc/default-build139
-rwxr-xr-xtest/run-test13
-rwxr-xr-xtools/desugar.sh95
83 files changed, 845 insertions, 1044 deletions
diff --git a/build/Android.bp b/build/Android.bp
index 3a1d5839f5..b7d2cbc070 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -17,6 +17,27 @@ bootstrap_go_package {
pluginFor: ["soong_build"],
}
+art_clang_tidy_errors = [
+ // Protect scoped things like MutexLock.
+ "bugprone-unused-raii",
+]
+// Should be: strings.Join(art_clang_tidy_errors, ",").
+art_clang_tidy_errors_str = "bugprone-unused-raii"
+
+art_clang_tidy_disabled = [
+ "-google-default-arguments",
+ // We have local stores that are only used for debug checks.
+ "-clang-analyzer-deadcode.DeadStores",
+ // We are OK with some static globals and that they can, in theory, throw.
+ "-cert-err58-cpp",
+ // We have lots of C-style variadic functions, and are OK with them. JNI ensures
+ // that working around this warning would be extra-painful.
+ "-cert-dcl50-cpp",
+ // No exceptions.
+ "-misc-noexcept-move-constructor",
+ "-performance-noexcept-move-constructor",
+]
+
art_global_defaults {
// Additional flags are computed by art.go
@@ -130,18 +151,7 @@ art_global_defaults {
"external/vixl/src",
],
- tidy_checks: [
- "-google-default-arguments",
- // We have local stores that are only used for debug checks.
- "-clang-analyzer-deadcode.DeadStores",
- // We are OK with some static globals and that they can, in theory, throw.
- "-cert-err58-cpp",
- // We have lots of C-style variadic functions, and are OK with them. JNI ensures
- // that working around this warning would be extra-painful.
- "-cert-dcl50-cpp",
- // No exceptions.
- "-misc-noexcept-move-constructor",
- ],
+ tidy_checks: art_clang_tidy_errors + art_clang_tidy_disabled,
tidy_flags: [
// The static analyzer treats DCHECK as always enabled; we sometimes get
@@ -151,6 +161,8 @@ art_global_defaults {
// void foo() { CHECK(kIsFooEnabled); /* do foo... */ }
// not being marked noreturn if kIsFooEnabled is false.
"-extra-arg=-Wno-missing-noreturn",
+ // Use art_clang_tidy_errors for build errors.
+ "-warnings-as-errors=" + art_clang_tidy_errors_str,
],
}
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 9f42727a2f..7d1115eec0 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -668,7 +668,7 @@ define define-test-art-gtest-combination
dependencies := $$(ART_TEST_$(2)_GTEST$(3)_RULES)
.PHONY: $$(rule_name)
-$$(rule_name): $$(dependencies) dx d8-compat-dx desugar
+$$(rule_name): $$(dependencies) d8 d8-compat-dx
$(hide) $$(call ART_TEST_PREREQ_FINISHED,$$@)
# Clear locally defined variables.
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index c37d4523c4..52c767f935 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -31,6 +31,7 @@
#include "dex/verification_results.h"
#include "driver/compiler_driver.h"
#include "driver/compiler_options.h"
+#include "jni/java_vm_ext.h"
#include "interpreter/interpreter.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
@@ -39,6 +40,7 @@
#include "oat_quick_method_header.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"
+#include "utils/atomic_dex_ref_map-inl.h"
namespace art {
@@ -134,8 +136,7 @@ void CommonCompilerTest::MakeExecutable(ObjPtr<mirror::ClassLoader> class_loader
}
}
-// Get the set of image classes given to the compiler-driver in SetUp. Note: the compiler
-// driver assumes ownership of the set, so the test should properly release the set.
+// Get the set of image classes given to the compiler options in SetUp.
std::unique_ptr<HashSet<std::string>> CommonCompilerTest::GetImageClasses() {
// Empty set: by default no classes are retained in the image.
return std::make_unique<HashSet<std::string>>();
@@ -173,12 +174,13 @@ void CommonCompilerTest::CreateCompilerDriver(Compiler::Kind kind,
size_t number_of_threads) {
compiler_options_->boot_image_ = true;
compiler_options_->SetCompilerFilter(GetCompilerFilter());
+ compiler_options_->image_classes_.swap(*GetImageClasses());
compiler_driver_.reset(new CompilerDriver(compiler_options_.get(),
verification_results_.get(),
kind,
isa,
instruction_set_features_.get(),
- GetImageClasses(),
+ &compiler_options_->image_classes_,
number_of_threads,
/* swap_fd */ -1,
GetProfileCompilationInfo()));
@@ -235,9 +237,49 @@ void CommonCompilerTest::CompileClass(mirror::ClassLoader* class_loader, const c
void CommonCompilerTest::CompileMethod(ArtMethod* method) {
CHECK(method != nullptr);
- TimingLogger timings("CommonTest::CompileMethod", false, false);
+ TimingLogger timings("CommonCompilerTest::CompileMethod", false, false);
TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
- compiler_driver_->CompileOne(Thread::Current(), method, &timings);
+ {
+ Thread* self = Thread::Current();
+ jobject class_loader = self->GetJniEnv()->GetVm()->AddGlobalRef(self, method->GetClassLoader());
+
+ DCHECK(!Runtime::Current()->IsStarted());
+ const DexFile* dex_file = method->GetDexFile();
+ uint16_t class_def_idx = method->GetClassDefIndex();
+ uint32_t method_idx = method->GetDexMethodIndex();
+ uint32_t access_flags = method->GetAccessFlags();
+ InvokeType invoke_type = method->GetInvokeType();
+ StackHandleScope<2> hs(self);
+ Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
+ Handle<mirror::ClassLoader> h_class_loader = hs.NewHandle(
+ self->DecodeJObject(class_loader)->AsClassLoader());
+ const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
+
+ std::vector<const DexFile*> dex_files;
+ dex_files.push_back(dex_file);
+
+ // Go to native so that we don't block GC during compilation.
+ ScopedThreadSuspension sts(self, kNative);
+
+ compiler_driver_->InitializeThreadPools();
+
+ compiler_driver_->PreCompile(class_loader, dex_files, &timings);
+
+ compiler_driver_->CompileOne(self,
+ class_loader,
+ *dex_file,
+ class_def_idx,
+ method_idx,
+ access_flags,
+ invoke_type,
+ code_item,
+ dex_cache,
+ h_class_loader);
+
+ compiler_driver_->FreeThreadPools();
+
+ self->GetJniEnv()->DeleteGlobalRef(class_loader);
+ }
TimingLogger::ScopedTiming t2("MakeExecutable", &timings);
MakeExecutable(method);
}
@@ -291,4 +333,10 @@ void CommonCompilerTest::UnreserveImageSpace() {
image_reservation_.reset();
}
+void CommonCompilerTest::SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files) {
+ compiler_options_->dex_files_for_oat_file_ = dex_files;
+ compiler_driver_->compiled_classes_.AddDexFiles(dex_files);
+ compiler_driver_->dex_to_dex_compiler_.SetDexFiles(dex_files);
+}
+
} // namespace art
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index 46b59a35be..f070bbbeb8 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -33,6 +33,7 @@ class ClassLoader;
class CompilerDriver;
class CompilerOptions;
class CumulativeLogger;
+class DexFile;
class ProfileCompilationInfo;
class VerificationResults;
@@ -93,6 +94,8 @@ class CommonCompilerTest : public CommonRuntimeTest {
void UnreserveImageSpace();
+ void SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files);
+
Compiler::Kind compiler_kind_ = Compiler::kOptimizing;
std::unique_ptr<CompilerOptions> compiler_options_;
std::unique_ptr<VerificationResults> verification_results_;
diff --git a/compiler/compiler.h b/compiler/compiler.h
index f2ec3a9fa3..ef3d87f02b 100644
--- a/compiler/compiler.h
+++ b/compiler/compiler.h
@@ -39,12 +39,6 @@ template<class T> class Handle;
class OatWriter;
class Thread;
-enum class CopyOption {
- kNever,
- kAlways,
- kOnlyIfCompressed
-};
-
class Compiler {
public:
enum Kind {
diff --git a/compiler/dex/dex_to_dex_decompiler_test.cc b/compiler/dex/dex_to_dex_decompiler_test.cc
index 76250d202c..4f83d605a3 100644
--- a/compiler/dex/dex_to_dex_decompiler_test.cc
+++ b/compiler/dex/dex_to_dex_decompiler_test.cc
@@ -47,7 +47,7 @@ class DexToDexDecompilerTest : public CommonCompilerTest {
// the results for all the dex files, not just the results for the current dex file.
down_cast<QuickCompilerCallbacks*>(Runtime::Current()->GetCompilerCallbacks())->SetVerifierDeps(
new verifier::VerifierDeps(GetDexFiles(class_loader)));
- compiler_driver_->SetDexFilesForOatFile(GetDexFiles(class_loader));
+ SetDexFilesForOatFile(GetDexFiles(class_loader));
compiler_driver_->CompileAll(class_loader, GetDexFiles(class_loader), &timings);
}
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index bd2b1070fc..66a8a57b36 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -67,7 +67,6 @@
#include "mirror/object-refvisitor-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/throwable.h"
-#include "nativehelper/ScopedLocalRef.h"
#include "object_lock.h"
#include "profile/profile_compilation_info.h"
#include "runtime.h"
@@ -264,7 +263,7 @@ CompilerDriver::CompilerDriver(
Compiler::Kind compiler_kind,
InstructionSet instruction_set,
const InstructionSetFeatures* instruction_set_features,
- std::unique_ptr<HashSet<std::string>>&& image_classes,
+ HashSet<std::string>* image_classes,
size_t thread_count,
int swap_fd,
const ProfileCompilationInfo* profile_compilation_info)
@@ -293,7 +292,7 @@ CompilerDriver::CompilerDriver(
compiler_->Init();
if (GetCompilerOptions().IsBootImage()) {
- CHECK(image_classes_.get() != nullptr) << "Expected image classes for boot image";
+ CHECK(image_classes_ != nullptr) << "Expected image classes for boot image";
}
compiled_method_storage_.SetDedupeEnabled(compiler_options_->DeduplicateCode());
@@ -351,12 +350,6 @@ void CompilerDriver::CompileAll(jobject class_loader,
InitializeThreadPools();
- VLOG(compiler) << "Before precompile " << GetMemoryUsageString(false);
- // Precompile:
- // 1) Load image classes
- // 2) Resolve all classes
- // 3) Attempt to verify all classes
- // 4) Attempt to initialize image classes, and trivially initialized classes
PreCompile(class_loader, dex_files, timings);
if (GetCompilerOptions().IsBootImage()) {
// We don't need to setup the intrinsics for non boot image compilation, as
@@ -673,46 +666,24 @@ static void CompileMethodQuick(
quick_fn);
}
-void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings) {
- DCHECK(!Runtime::Current()->IsStarted());
- jobject jclass_loader;
- const DexFile* dex_file;
- uint16_t class_def_idx;
- uint32_t method_idx = method->GetDexMethodIndex();
- uint32_t access_flags = method->GetAccessFlags();
- InvokeType invoke_type = method->GetInvokeType();
- StackHandleScope<2> hs(self);
- Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
- Handle<mirror::ClassLoader> class_loader(
- hs.NewHandle(method->GetDeclaringClass()->GetClassLoader()));
- {
- ScopedObjectAccessUnchecked soa(self);
- ScopedLocalRef<jobject> local_class_loader(
- soa.Env(), soa.AddLocalReference<jobject>(class_loader.Get()));
- jclass_loader = soa.Env()->NewGlobalRef(local_class_loader.get());
- // Find the dex_file
- dex_file = method->GetDexFile();
- class_def_idx = method->GetClassDefIndex();
- }
- const DexFile::CodeItem* code_item = dex_file->GetCodeItem(method->GetCodeItemOffset());
-
- // Go to native so that we don't block GC during compilation.
- ScopedThreadSuspension sts(self, kNative);
-
- std::vector<const DexFile*> dex_files;
- dex_files.push_back(dex_file);
-
- InitializeThreadPools();
-
- PreCompile(jclass_loader, dex_files, timings);
-
+// Compile a single Method. (For testing only.)
+void CompilerDriver::CompileOne(Thread* self,
+ jobject class_loader,
+ const DexFile& dex_file,
+ uint16_t class_def_idx,
+ uint32_t method_idx,
+ uint32_t access_flags,
+ InvokeType invoke_type,
+ const DexFile::CodeItem* code_item,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> h_class_loader) {
// Can we run DEX-to-DEX compiler on this class ?
optimizer::DexToDexCompiler::CompilationLevel dex_to_dex_compilation_level =
GetDexToDexCompilationLevel(self,
*this,
- jclass_loader,
- *dex_file,
- dex_file->GetClassDef(class_def_idx));
+ class_loader,
+ dex_file,
+ dex_file.GetClassDef(class_def_idx));
CompileMethodQuick(self,
this,
@@ -721,8 +692,8 @@ void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* t
invoke_type,
class_def_idx,
method_idx,
- class_loader,
- *dex_file,
+ h_class_loader,
+ dex_file,
dex_to_dex_compilation_level,
true,
dex_cache);
@@ -737,17 +708,13 @@ void CompilerDriver::CompileOne(Thread* self, ArtMethod* method, TimingLogger* t
invoke_type,
class_def_idx,
method_idx,
- class_loader,
- *dex_file,
+ h_class_loader,
+ dex_file,
dex_to_dex_compilation_level,
true,
dex_cache);
dex_to_dex_compiler_.ClearState();
}
-
- FreeThreadPools();
-
- self->GetJniEnv()->DeleteGlobalRef(jclass_loader);
}
void CompilerDriver::Resolve(jobject class_loader,
@@ -838,7 +805,7 @@ static void InitializeTypeCheckBitstrings(CompilerDriver* driver,
// primitive) classes. We may reconsider this in future if it's deemed to be beneficial.
// And we cannot use it for classes outside the boot image as we do not know the runtime
// value of their bitstring when compiling (it may not even get assigned at runtime).
- if (descriptor[0] == 'L' && driver->IsImageClass(descriptor)) {
+ if (descriptor[0] == 'L' && driver->GetCompilerOptions().IsImageClass(descriptor)) {
ObjPtr<mirror::Class> klass =
class_linker->LookupResolvedType(type_index,
dex_cache.Get(),
@@ -919,6 +886,20 @@ void CompilerDriver::PreCompile(jobject class_loader,
TimingLogger* timings) {
CheckThreadPools();
+ VLOG(compiler) << "Before precompile " << GetMemoryUsageString(false);
+
+ compiled_classes_.AddDexFiles(GetCompilerOptions().GetDexFilesForOatFile());
+ dex_to_dex_compiler_.SetDexFiles(GetCompilerOptions().GetDexFilesForOatFile());
+
+ // Precompile:
+ // 1) Load image classes.
+ // 2) Resolve all classes.
+ // 3) For deterministic boot image, resolve strings for const-string instructions.
+ // 4) Attempt to verify all classes.
+ // 5) Attempt to initialize image classes, and trivially initialized classes.
+ // 6) Update the set of image classes.
+ // 7) For deterministic boot image, initialize bitstrings for type checking.
+
LoadImageClasses(timings);
VLOG(compiler) << "LoadImageClasses: " << GetMemoryUsageString(false);
@@ -988,16 +969,6 @@ void CompilerDriver::PreCompile(jobject class_loader,
}
}
-bool CompilerDriver::IsImageClass(const char* descriptor) const {
- if (image_classes_ != nullptr) {
- // If we have a set of image classes, use those.
- return image_classes_->find(StringPiece(descriptor)) != image_classes_->end();
- }
- // No set of image classes, assume we include all the classes.
- // NOTE: Currently only reachable from InitImageMethodVisitor for the app image case.
- return !GetCompilerOptions().IsBootImage();
-}
-
bool CompilerDriver::IsClassToCompile(const char* descriptor) const {
if (classes_to_compile_ == nullptr) {
return true;
@@ -1116,7 +1087,7 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) {
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- CHECK(image_classes_.get() != nullptr);
+ CHECK(image_classes_ != nullptr);
for (auto it = image_classes_->begin(), end = image_classes_->end(); it != end;) {
const std::string& descriptor(*it);
StackHandleScope<1> hs(self);
@@ -1174,7 +1145,7 @@ void CompilerDriver::LoadImageClasses(TimingLogger* timings) {
// We walk the roots looking for classes so that we'll pick up the
// above classes plus any classes them depend on such super
// classes, interfaces, and the required ClassLinker roots.
- RecordImageClassesVisitor visitor(image_classes_.get());
+ RecordImageClassesVisitor visitor(image_classes_);
class_linker->VisitClasses(&visitor);
CHECK(!image_classes_->empty());
@@ -1358,7 +1329,7 @@ void CompilerDriver::UpdateImageClasses(TimingLogger* timings) {
VariableSizedHandleScope hs(Thread::Current());
std::string error_msg;
std::unique_ptr<ClinitImageUpdate> update(ClinitImageUpdate::Create(hs,
- image_classes_.get(),
+ image_classes_,
Thread::Current(),
runtime->GetClassLinker()));
@@ -1382,7 +1353,7 @@ bool CompilerDriver::CanAssumeClassIsLoaded(mirror::Class* klass) {
}
std::string temp;
const char* descriptor = klass->GetDescriptor(&temp);
- return IsImageClass(descriptor);
+ return GetCompilerOptions().IsImageClass(descriptor);
}
bool CompilerDriver::CanAccessTypeWithoutChecks(ObjPtr<mirror::Class> referrer_class,
@@ -1981,7 +1952,8 @@ void CompilerDriver::Verify(jobject jclass_loader,
// Create per-thread VerifierDeps to avoid contention on the main one.
// We will merge them after verification.
for (ThreadPoolWorker* worker : parallel_thread_pool_->GetWorkers()) {
- worker->GetThread()->SetVerifierDeps(new verifier::VerifierDeps(dex_files_for_oat_file_));
+ worker->GetThread()->SetVerifierDeps(
+ new verifier::VerifierDeps(GetCompilerOptions().GetDexFilesForOatFile()));
}
}
@@ -2006,7 +1978,7 @@ void CompilerDriver::Verify(jobject jclass_loader,
for (ThreadPoolWorker* worker : parallel_thread_pool_->GetWorkers()) {
verifier::VerifierDeps* thread_deps = worker->GetThread()->GetVerifierDeps();
worker->GetThread()->SetVerifierDeps(nullptr);
- verifier_deps->MergeWith(*thread_deps, dex_files_for_oat_file_);
+ verifier_deps->MergeWith(*thread_deps, GetCompilerOptions().GetDexFilesForOatFile());
delete thread_deps;
}
Thread::Current()->SetVerifierDeps(nullptr);
@@ -2292,7 +2264,7 @@ class InitializeClassVisitor : public CompilationVisitor {
(is_app_image || is_boot_image) &&
is_superclass_initialized &&
!too_many_encoded_fields &&
- manager_->GetCompiler()->IsImageClass(descriptor)) {
+ manager_->GetCompiler()->GetCompilerOptions().IsImageClass(descriptor)) {
bool can_init_static_fields = false;
if (is_boot_image) {
// We need to initialize static fields, we only do this for image classes that aren't
@@ -2879,7 +2851,7 @@ void CompilerDriver::RecordClassStatus(const ClassReference& ref, ClassStatus st
if (kIsDebugBuild) {
// Check to make sure it's not a dex file for an oat file we are compiling since these
// should always succeed. These do not include classes in for used libraries.
- for (const DexFile* dex_file : GetDexFilesForOatFile()) {
+ for (const DexFile* dex_file : GetCompilerOptions().GetDexFilesForOatFile()) {
CHECK_NE(ref.dex_file, dex_file) << ref.dex_file->GetLocation();
}
}
@@ -2978,18 +2950,6 @@ std::string CompilerDriver::GetMemoryUsageString(bool extended) const {
return oss.str();
}
-bool CompilerDriver::MayInlineInternal(const DexFile* inlined_from,
- const DexFile* inlined_into) const {
- // We're not allowed to inline across dex files if we're the no-inline-from dex file.
- if (inlined_from != inlined_into &&
- compiler_options_->GetNoInlineFromDexFile() != nullptr &&
- ContainsElement(*compiler_options_->GetNoInlineFromDexFile(), inlined_from)) {
- return false;
- }
-
- return true;
-}
-
void CompilerDriver::InitializeThreadPools() {
size_t parallel_count = parallel_thread_count_ > 0 ? parallel_thread_count_ - 1 : 0;
parallel_thread_pool_.reset(
@@ -3002,12 +2962,6 @@ void CompilerDriver::FreeThreadPools() {
single_thread_pool_.reset();
}
-void CompilerDriver::SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files) {
- dex_files_for_oat_file_ = dex_files;
- compiled_classes_.AddDexFiles(dex_files);
- dex_to_dex_compiler_.SetDexFiles(dex_files);
-}
-
void CompilerDriver::SetClasspathDexFiles(const std::vector<const DexFile*>& dex_files) {
classpath_classes_.AddDexFiles(dex_files);
}
diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h
index ff70d96272..54e1f3747f 100644
--- a/compiler/driver/compiler_driver.h
+++ b/compiler/driver/compiler_driver.h
@@ -99,32 +99,33 @@ class CompilerDriver {
Compiler::Kind compiler_kind,
InstructionSet instruction_set,
const InstructionSetFeatures* instruction_set_features,
- std::unique_ptr<HashSet<std::string>>&& image_classes,
+ HashSet<std::string>* image_classes,
size_t thread_count,
int swap_fd,
const ProfileCompilationInfo* profile_compilation_info);
~CompilerDriver();
- // Set dex files associated with the oat file being compiled.
- void SetDexFilesForOatFile(const std::vector<const DexFile*>& dex_files);
-
// Set dex files classpath.
void SetClasspathDexFiles(const std::vector<const DexFile*>& dex_files);
- // Get dex files associated with the the oat file being compiled.
- ArrayRef<const DexFile* const> GetDexFilesForOatFile() const {
- return ArrayRef<const DexFile* const>(dex_files_for_oat_file_);
- }
-
void CompileAll(jobject class_loader,
const std::vector<const DexFile*>& dex_files,
TimingLogger* timings)
REQUIRES(!Locks::mutator_lock_);
- // Compile a single Method.
- void CompileOne(Thread* self, ArtMethod* method, TimingLogger* timings)
- REQUIRES_SHARED(Locks::mutator_lock_);
+ // Compile a single Method. (For testing only.)
+ void CompileOne(Thread* self,
+ jobject class_loader,
+ const DexFile& dex_file,
+ uint16_t class_def_idx,
+ uint32_t method_idx,
+ uint32_t access_flags,
+ InvokeType invoke_type,
+ const DexFile::CodeItem* code_item,
+ Handle<mirror::DexCache> dex_cache,
+ Handle<mirror::ClassLoader> h_class_loader)
+ REQUIRES(!Locks::mutator_lock_);
VerificationResults* GetVerificationResults() const;
@@ -144,10 +145,6 @@ class CompilerDriver {
return compiler_.get();
}
- const HashSet<std::string>* GetImageClasses() const {
- return image_classes_.get();
- }
-
// Generate the trampolines that are invoked by unresolved direct methods.
std::unique_ptr<const std::vector<uint8_t>> CreateJniDlsymLookup() const;
std::unique_ptr<const std::vector<uint8_t>> CreateQuickGenericJniTrampoline() const;
@@ -308,9 +305,6 @@ class CompilerDriver {
return compiled_method_storage_.DedupeEnabled();
}
- // Checks if class specified by type_idx is one of the image_classes_
- bool IsImageClass(const char* descriptor) const;
-
// Checks whether the provided class should be compiled, i.e., is in classes_to_compile_.
bool IsClassToCompile(const char* descriptor) const;
@@ -352,13 +346,6 @@ class CompilerDriver {
bool CanAssumeClassIsLoaded(mirror::Class* klass)
REQUIRES_SHARED(Locks::mutator_lock_);
- bool MayInline(const DexFile* inlined_from, const DexFile* inlined_into) const {
- if (!kIsTargetBuild) {
- return MayInlineInternal(inlined_from, inlined_into);
- }
- return true;
- }
-
const ProfileCompilationInfo* GetProfileCompilationInfo() const {
return profile_compilation_info_;
}
@@ -452,8 +439,6 @@ class CompilerDriver {
const std::vector<const DexFile*>& dex_files,
TimingLogger* timings);
- bool MayInlineInternal(const DexFile* inlined_from, const DexFile* inlined_into) const;
-
void InitializeThreadPools();
void FreeThreadPools();
void CheckThreadPools();
@@ -491,9 +476,11 @@ class CompilerDriver {
// in the .oat_patches ELF section if requested in the compiler options.
Atomic<size_t> non_relative_linker_patch_count_;
- // If image_ is true, specifies the classes that will be included in the image.
- // Note if image_classes_ is null, all classes are included in the image.
- std::unique_ptr<HashSet<std::string>> image_classes_;
+ // Image classes to be updated by PreCompile().
+ // TODO: Remove this member which is a non-const pointer to the CompilerOptions' data.
+ // Pass this explicitly to the PreCompile() which should be called directly from
+ // Dex2Oat rather than implicitly by CompileAll().
+ HashSet<std::string>* image_classes_;
// Specifies the classes that will be compiled. Note that if classes_to_compile_ is null,
// all classes are eligible for compilation (duplication filters etc. will still apply).
@@ -505,8 +492,8 @@ class CompilerDriver {
bool had_hard_verifier_failure_;
// A thread pool that can (potentially) run tasks in parallel.
- std::unique_ptr<ThreadPool> parallel_thread_pool_;
size_t parallel_thread_count_;
+ std::unique_ptr<ThreadPool> parallel_thread_pool_;
// A thread pool that guarantees running single-threaded on the main thread.
std::unique_ptr<ThreadPool> single_thread_pool_;
@@ -521,9 +508,6 @@ class CompilerDriver {
bool support_boot_image_fixup_;
- // List of dex files associates with the oat file.
- std::vector<const DexFile*> dex_files_for_oat_file_;
-
CompiledMethodStorage compiled_method_storage_;
// Info for profile guided compilation.
@@ -534,6 +518,7 @@ class CompilerDriver {
// Compiler for dex to dex (quickening).
optimizer::DexToDexCompiler dex_to_dex_compiler_;
+ friend class CommonCompilerTest;
friend class CompileClassVisitor;
friend class DexToDexDecompilerTest;
friend class verifier::VerifierDepsTest;
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 491e61f9b5..2eeb4399db 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -46,7 +46,7 @@ class CompilerDriverTest : public CommonCompilerTest {
TimingLogger timings("CompilerDriverTest::CompileAll", false, false);
TimingLogger::ScopedTiming t(__FUNCTION__, &timings);
dex_files_ = GetDexFiles(class_loader);
- compiler_driver_->SetDexFilesForOatFile(dex_files_);;
+ SetDexFilesForOatFile(dex_files_);
compiler_driver_->CompileAll(class_loader, dex_files_, &timings);
t.NewTiming("MakeAllExecutable");
MakeAllExecutable(class_loader);
@@ -331,7 +331,7 @@ TEST_F(CompilerDriverVerifyTest, RetryVerifcationStatusCheckVerified) {
ASSERT_GT(dex_files.size(), 0u);
dex_file = dex_files.front();
}
- compiler_driver_->SetDexFilesForOatFile(dex_files);
+ SetDexFilesForOatFile(dex_files);
callbacks_->SetDoesClassUnloading(true, compiler_driver_.get());
ClassReference ref(dex_file, 0u);
// Test that the status is read from the compiler driver as expected.
diff --git a/compiler/driver/compiler_options.cc b/compiler/driver/compiler_options.cc
index 933be4f004..cc1af3e108 100644
--- a/compiler/driver/compiler_options.cc
+++ b/compiler/driver/compiler_options.cc
@@ -37,7 +37,9 @@ CompilerOptions::CompilerOptions()
tiny_method_threshold_(kDefaultTinyMethodThreshold),
num_dex_methods_threshold_(kDefaultNumDexMethodsThreshold),
inline_max_code_units_(kUnsetInlineMaxCodeUnits),
- no_inline_from_(nullptr),
+ no_inline_from_(),
+ dex_files_for_oat_file_(),
+ image_classes_(),
boot_image_(false),
core_image_(false),
app_image_(false),
@@ -67,8 +69,8 @@ CompilerOptions::CompilerOptions()
}
CompilerOptions::~CompilerOptions() {
- // The destructor looks empty but it destroys a PassManagerOptions object. We keep it here
- // because we don't want to include the PassManagerOptions definition from the header file.
+ // Everything done by member destructors.
+ // The definitions of classes forward-declared in the header have now been #included.
}
namespace {
@@ -129,4 +131,11 @@ bool CompilerOptions::ParseCompilerOptions(const std::vector<std::string>& optio
#pragma GCC diagnostic pop
+bool CompilerOptions::IsImageClass(const char* descriptor) const {
+ // Historical note: We used to hold the set indirectly and there was a distinction between an
+ // empty set and a null, null meaning to include all classes. However, the distiction has been
+ // removed; if we don't have a profile, we treat it as an empty set of classes. b/77340429
+ return image_classes_.find(StringPiece(descriptor)) != image_classes_.end();
+}
+
} // namespace art
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h
index cee989b315..908ff3302c 100644
--- a/compiler/driver/compiler_options.h
+++ b/compiler/driver/compiler_options.h
@@ -22,6 +22,7 @@
#include <vector>
#include "base/globals.h"
+#include "base/hash_set.h"
#include "base/macros.h"
#include "base/utils.h"
#include "compiler_filter.h"
@@ -230,10 +231,20 @@ class CompilerOptions FINAL {
return abort_on_soft_verifier_failure_;
}
- const std::vector<const DexFile*>* GetNoInlineFromDexFile() const {
+ const std::vector<const DexFile*>& GetNoInlineFromDexFile() const {
return no_inline_from_;
}
+ const std::vector<const DexFile*>& GetDexFilesForOatFile() const {
+ return dex_files_for_oat_file_;
+ }
+
+ const HashSet<std::string>& GetImageClasses() const {
+ return image_classes_;
+ }
+
+ bool IsImageClass(const char* descriptor) const;
+
bool ParseCompilerOptions(const std::vector<std::string>& options,
bool ignore_unrecognized,
std::string* error_msg);
@@ -301,10 +312,17 @@ class CompilerOptions FINAL {
size_t num_dex_methods_threshold_;
size_t inline_max_code_units_;
- // Dex files from which we should not inline code.
+ // Dex files from which we should not inline code. Does not own the dex files.
// This is usually a very short list (i.e. a single dex file), so we
// prefer vector<> over a lookup-oriented container, such as set<>.
- const std::vector<const DexFile*>* no_inline_from_;
+ std::vector<const DexFile*> no_inline_from_;
+
+ // List of dex files associated with the oat file, empty for JIT.
+ std::vector<const DexFile*> dex_files_for_oat_file_;
+
+ // Image classes, specifies the classes that will be included in the image if creating an image.
+ // Must not be empty for real boot image, only for tests pretending to compile boot image.
+ HashSet<std::string> image_classes_;
bool boot_image_;
bool core_image_;
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 7dd756e13a..72d53d28cf 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -126,7 +126,7 @@ void HInliner::UpdateInliningBudget() {
}
bool HInliner::Run() {
- if (compiler_driver_->GetCompilerOptions().GetInlineMaxCodeUnits() == 0) {
+ if (codegen_->GetCompilerOptions().GetInlineMaxCodeUnits() == 0) {
// Inlining effectively disabled.
return false;
} else if (graph_->IsDebuggable()) {
@@ -731,7 +731,7 @@ HInliner::InlineCacheType HInliner::ExtractClassesFromOfflineProfile(
offline_profile.dex_references.size());
for (size_t i = 0; i < offline_profile.dex_references.size(); i++) {
bool found = false;
- for (const DexFile* dex_file : compiler_driver_->GetDexFilesForOatFile()) {
+ for (const DexFile* dex_file : codegen_->GetCompilerOptions().GetDexFilesForOatFile()) {
if (offline_profile.dex_references[i].MatchesDex(dex_file)) {
dex_profile_index_to_dex_cache[i] =
caller_compilation_unit_.GetClassLinker()->FindDexCache(self, *dex_file);
@@ -1418,6 +1418,22 @@ size_t HInliner::CountRecursiveCallsOf(ArtMethod* method) const {
return count;
}
+static inline bool MayInline(const CompilerOptions& compiler_options,
+ const DexFile& inlined_from,
+ const DexFile& inlined_into) {
+ if (kIsTargetBuild) {
+ return true;
+ }
+
+ // We're not allowed to inline across dex files if we're the no-inline-from dex file.
+ if (!IsSameDexFile(inlined_from, inlined_into) &&
+ ContainsElement(compiler_options.GetNoInlineFromDexFile(), &inlined_from)) {
+ return false;
+ }
+
+ return true;
+}
+
bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction,
ArtMethod* method,
ReferenceTypeInfo receiver_type,
@@ -1439,8 +1455,9 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction,
// Check whether we're allowed to inline. The outermost compilation unit is the relevant
// dex file here (though the transitivity of an inline chain would allow checking the calller).
- if (!compiler_driver_->MayInline(method->GetDexFile(),
- outer_compilation_unit_.GetDexFile())) {
+ if (!MayInline(codegen_->GetCompilerOptions(),
+ *method->GetDexFile(),
+ *outer_compilation_unit_.GetDexFile())) {
if (TryPatternSubstitution(invoke_instruction, method, return_replacement)) {
LOG_SUCCESS() << "Successfully replaced pattern of invoke "
<< method->PrettyMethod();
@@ -1465,7 +1482,7 @@ bool HInliner::TryBuildAndInline(HInvoke* invoke_instruction,
return false;
}
- size_t inline_max_code_units = compiler_driver_->GetCompilerOptions().GetInlineMaxCodeUnits();
+ size_t inline_max_code_units = codegen_->GetCompilerOptions().GetInlineMaxCodeUnits();
if (accessor.InsnsSizeInCodeUnits() > inline_max_code_units) {
LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedCodeItem)
<< "Method " << method->PrettyMethod()
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc
index 8a347dfea7..7cda6e9da3 100644
--- a/compiler/optimizing/instruction_builder.cc
+++ b/compiler/optimizing/instruction_builder.cc
@@ -1879,7 +1879,7 @@ void HInstructionBuilder::BuildTypeCheck(const Instruction& instruction,
Handle<mirror::Class> klass = ResolveClass(soa, type_index);
bool needs_access_check = LoadClassNeedsAccessCheck(klass);
TypeCheckKind check_kind = HSharpening::ComputeTypeCheckKind(
- klass.Get(), code_generator_, compiler_driver_, needs_access_check);
+ klass.Get(), code_generator_, needs_access_check);
HInstruction* class_or_null = nullptr;
HIntConstant* bitstring_path_to_root = nullptr;
diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc
index 6541043046..1e29c21313 100644
--- a/compiler/optimizing/sharpening.cc
+++ b/compiler/optimizing/sharpening.cc
@@ -71,7 +71,8 @@ static bool AOTCanEmbedMethod(ArtMethod* method, const CompilerOptions& options)
}
static bool BootImageAOTCanEmbedMethod(ArtMethod* method, CompilerDriver* compiler_driver) {
- DCHECK(compiler_driver->GetCompilerOptions().IsBootImage());
+ const CompilerOptions& compiler_options = compiler_driver->GetCompilerOptions();
+ DCHECK(compiler_options.IsBootImage());
if (!compiler_driver->GetSupportBootImageFixup()) {
return false;
}
@@ -79,7 +80,7 @@ static bool BootImageAOTCanEmbedMethod(ArtMethod* method, CompilerDriver* compil
ObjPtr<mirror::Class> klass = method->GetDeclaringClass();
DCHECK(klass != nullptr);
const DexFile& dex_file = klass->GetDexFile();
- return compiler_driver->IsImageClass(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
+ return compiler_options.IsImageClass(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
}
void HSharpening::SharpenInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke,
@@ -177,26 +178,27 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(
bool is_in_boot_image = false;
HLoadClass::LoadKind desired_load_kind = HLoadClass::LoadKind::kInvalid;
Runtime* runtime = Runtime::Current();
- if (codegen->GetCompilerOptions().IsBootImage()) {
+ const CompilerOptions& compiler_options = codegen->GetCompilerOptions();
+ if (compiler_options.IsBootImage()) {
// Compiling boot image. Check if the class is a boot image class.
DCHECK(!runtime->UseJitCompilation());
if (!compiler_driver->GetSupportBootImageFixup()) {
// compiler_driver_test. Do not sharpen.
desired_load_kind = HLoadClass::LoadKind::kRuntimeCall;
} else if ((klass != nullptr) &&
- compiler_driver->IsImageClass(dex_file.StringByTypeIdx(type_index))) {
+ compiler_options.IsImageClass(dex_file.StringByTypeIdx(type_index))) {
is_in_boot_image = true;
desired_load_kind = HLoadClass::LoadKind::kBootImageLinkTimePcRelative;
} else {
// Not a boot image class.
- DCHECK(ContainsElement(compiler_driver->GetDexFilesForOatFile(), &dex_file));
+ DCHECK(ContainsElement(compiler_options.GetDexFilesForOatFile(), &dex_file));
desired_load_kind = HLoadClass::LoadKind::kBssEntry;
}
} else {
is_in_boot_image = (klass != nullptr) &&
runtime->GetHeap()->ObjectIsInBootImageSpace(klass.Get());
if (runtime->UseJitCompilation()) {
- DCHECK(!codegen->GetCompilerOptions().GetCompilePic());
+ DCHECK(!compiler_options.GetCompilePic());
if (is_in_boot_image) {
// TODO: Use direct pointers for all non-moving spaces, not just boot image. Bug: 29530787
desired_load_kind = HLoadClass::LoadKind::kBootImageAddress;
@@ -241,9 +243,7 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind(
return load_kind;
}
-static inline bool CanUseTypeCheckBitstring(ObjPtr<mirror::Class> klass,
- CodeGenerator* codegen,
- CompilerDriver* compiler_driver)
+static inline bool CanUseTypeCheckBitstring(ObjPtr<mirror::Class> klass, CodeGenerator* codegen)
REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(!klass->IsProxyClass());
DCHECK(!klass->IsArrayClass());
@@ -252,7 +252,7 @@ static inline bool CanUseTypeCheckBitstring(ObjPtr<mirror::Class> klass,
// If we're JITting, try to assign a type check bitstring (fall through).
} else if (codegen->GetCompilerOptions().IsBootImage()) {
const char* descriptor = klass->GetDexFile().StringByTypeIdx(klass->GetDexTypeIndex());
- if (!compiler_driver->IsImageClass(descriptor)) {
+ if (!codegen->GetCompilerOptions().IsImageClass(descriptor)) {
return false;
}
// If the target is a boot image class, try to assign a type check bitstring (fall through).
@@ -281,7 +281,6 @@ static inline bool CanUseTypeCheckBitstring(ObjPtr<mirror::Class> klass,
TypeCheckKind HSharpening::ComputeTypeCheckKind(ObjPtr<mirror::Class> klass,
CodeGenerator* codegen,
- CompilerDriver* compiler_driver,
bool needs_access_check) {
if (klass == nullptr) {
return TypeCheckKind::kUnresolvedCheck;
@@ -299,7 +298,7 @@ TypeCheckKind HSharpening::ComputeTypeCheckKind(ObjPtr<mirror::Class> klass,
return TypeCheckKind::kExactCheck;
} else if (kBitstringSubtypeCheckEnabled &&
!needs_access_check &&
- CanUseTypeCheckBitstring(klass, codegen, compiler_driver)) {
+ CanUseTypeCheckBitstring(klass, codegen)) {
// TODO: We should not need the `!needs_access_check` check but getting rid of that
// requires rewriting some optimizations in instruction simplifier.
return TypeCheckKind::kBitstringCheck;
@@ -332,14 +331,15 @@ void HSharpening::ProcessLoadString(
: hs.NewHandle(class_linker->FindDexCache(soa.Self(), dex_file));
ObjPtr<mirror::String> string = nullptr;
- if (codegen->GetCompilerOptions().IsBootImage()) {
+ const CompilerOptions& compiler_options = codegen->GetCompilerOptions();
+ if (compiler_options.IsBootImage()) {
// Compiling boot image. Resolve the string and allocate it if needed, to ensure
// the string will be added to the boot image.
DCHECK(!runtime->UseJitCompilation());
string = class_linker->ResolveString(string_index, dex_cache);
CHECK(string != nullptr);
if (compiler_driver->GetSupportBootImageFixup()) {
- DCHECK(ContainsElement(compiler_driver->GetDexFilesForOatFile(), &dex_file));
+ DCHECK(ContainsElement(compiler_options.GetDexFilesForOatFile(), &dex_file));
desired_load_kind = HLoadString::LoadKind::kBootImageLinkTimePcRelative;
} else {
// compiler_driver_test. Do not sharpen.
diff --git a/compiler/optimizing/sharpening.h b/compiler/optimizing/sharpening.h
index 9ccbcaf220..e77732814b 100644
--- a/compiler/optimizing/sharpening.h
+++ b/compiler/optimizing/sharpening.h
@@ -59,7 +59,6 @@ class HSharpening : public HOptimization {
// Used by the builder.
static TypeCheckKind ComputeTypeCheckKind(ObjPtr<mirror::Class> klass,
CodeGenerator* codegen,
- CompilerDriver* compiler_driver,
bool needs_access_check)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/compiler/verifier_deps_test.cc b/compiler/verifier_deps_test.cc
index 3fe2ec0ac0..c223549710 100644
--- a/compiler/verifier_deps_test.cc
+++ b/compiler/verifier_deps_test.cc
@@ -129,7 +129,7 @@ class VerifierDepsTest : public CommonCompilerTest {
for (const DexFile* dex_file : dex_files_) {
compiler_driver_->GetVerificationResults()->AddDexFile(dex_file);
}
- compiler_driver_->SetDexFilesForOatFile(dex_files_);
+ SetDexFilesForOatFile(dex_files_);
}
void LoadDexFile(ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) {
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 6cd947c8cf..be3f922340 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -642,7 +642,6 @@ class Dex2Oat FINAL {
driver_(nullptr),
opened_dex_files_maps_(),
opened_dex_files_(),
- no_inline_from_dex_files_(),
avoid_storing_invocation_(false),
swap_fd_(kInvalidFd),
app_image_fd_(kInvalidFd),
@@ -697,7 +696,7 @@ class Dex2Oat FINAL {
}
bool VerifyProfileData() {
- return profile_compilation_info_->VerifyProfileData(dex_files_);
+ return profile_compilation_info_->VerifyProfileData(compiler_options_->dex_files_for_oat_file_);
}
void ParseInstructionSetVariant(const std::string& option, ParserOptions* parser_options) {
@@ -1489,22 +1488,21 @@ class Dex2Oat FINAL {
if (!IsImage()) {
return;
}
- // If we don't have a profile, treat it as an empty set of classes. b/77340429
- if (image_classes_ == nullptr) {
- // May be non-null when --image-classes is passed in, in that case avoid clearing the list.
- image_classes_.reset(new HashSet<std::string>());
- }
if (profile_compilation_info_ != nullptr) {
+ // TODO: The following comment looks outdated or misplaced.
// Filter out class path classes since we don't want to include these in the image.
- image_classes_.reset(
- new HashSet<std::string>(profile_compilation_info_->GetClassDescriptors(dex_files_)));
- VLOG(compiler) << "Loaded " << image_classes_->size()
+ HashSet<std::string> image_classes = profile_compilation_info_->GetClassDescriptors(
+ compiler_options_->dex_files_for_oat_file_);
+ VLOG(compiler) << "Loaded " << image_classes.size()
<< " image class descriptors from profile";
if (VLOG_IS_ON(compiler)) {
- for (const std::string& s : *image_classes_) {
+ for (const std::string& s : image_classes) {
LOG(INFO) << "Image class " << s;
}
}
+ // Note: If we have a profile, classes previously loaded for the --image-classes
+ // option are overwritten here.
+ compiler_options_->image_classes_.swap(image_classes);
}
}
@@ -1655,10 +1653,11 @@ class Dex2Oat FINAL {
}
}
- dex_files_ = MakeNonOwningPointerVector(opened_dex_files_);
+ compiler_options_->dex_files_for_oat_file_ = MakeNonOwningPointerVector(opened_dex_files_);
+ const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
// If we need to downgrade the compiler-filter for size reasons.
- if (!IsBootImage() && IsVeryLarge(dex_files_)) {
+ if (!IsBootImage() && IsVeryLarge(dex_files)) {
// Disable app image to make sure dex2oat unloading is enabled.
compiler_options_->DisableAppImage();
@@ -1691,7 +1690,7 @@ class Dex2Oat FINAL {
CHECK(driver_ == nullptr);
// If we use a swap file, ensure we are above the threshold to make it necessary.
if (swap_fd_ != -1) {
- if (!UseSwap(IsBootImage(), dex_files_)) {
+ if (!UseSwap(IsBootImage(), dex_files)) {
close(swap_fd_);
swap_fd_ = -1;
VLOG(compiler) << "Decided to run without swap.";
@@ -1734,7 +1733,7 @@ class Dex2Oat FINAL {
// Verification results are only required for modes that have any compilation. Avoid
// adding the dex files if possible to prevent allocating large arrays.
if (verification_results_ != nullptr) {
- for (const auto& dex_file : dex_files_) {
+ for (const auto& dex_file : dex_files) {
// Pre-register dex files so that we can access verification results without locks during
// compilation and verification.
verification_results_->AddDexFile(dex_file);
@@ -1752,7 +1751,7 @@ class Dex2Oat FINAL {
// Doesn't return the class loader since it's not meant to be used for image compilation.
void CompileDexFilesIndividually() {
CHECK(!IsImage()) << "Not supported with image";
- for (const DexFile* dex_file : dex_files_) {
+ for (const DexFile* dex_file : compiler_options_->dex_files_for_oat_file_) {
std::vector<const DexFile*> dex_files(1u, dex_file);
VLOG(compiler) << "Compiling " << dex_file->GetLocation();
jobject class_loader = CompileDexFiles(dex_files);
@@ -1783,7 +1782,7 @@ class Dex2Oat FINAL {
// mode (to reduce RAM used by the compiler).
return !IsImage() &&
!update_input_vdex_ &&
- dex_files_.size() > 1 &&
+ compiler_options_->dex_files_for_oat_file_.size() > 1 &&
!CompilerFilter::IsAotCompilationEnabled(compiler_options_->GetCompilerFilter());
}
@@ -1810,10 +1809,12 @@ class Dex2Oat FINAL {
class_path_files = class_loader_context_->FlattenOpenedDexFiles();
}
- std::vector<const std::vector<const DexFile*>*> dex_file_vectors = {
+ const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
+ std::vector<const DexFile*> no_inline_from_dex_files;
+ const std::vector<const DexFile*>* dex_file_vectors[] = {
&class_linker->GetBootClassPath(),
&class_path_files,
- &dex_files_
+ &dex_files
};
for (const std::vector<const DexFile*>* dex_file_vector : dex_file_vectors) {
for (const DexFile* dex_file : *dex_file_vector) {
@@ -1832,14 +1833,14 @@ class Dex2Oat FINAL {
if (android::base::StartsWith(dex_location, filter.c_str())) {
VLOG(compiler) << "Disabling inlining from " << dex_file->GetLocation();
- no_inline_from_dex_files_.push_back(dex_file);
+ no_inline_from_dex_files.push_back(dex_file);
break;
}
}
}
}
- if (!no_inline_from_dex_files_.empty()) {
- compiler_options_->no_inline_from_ = &no_inline_from_dex_files_;
+ if (!no_inline_from_dex_files.empty()) {
+ compiler_options_->no_inline_from_.swap(no_inline_from_dex_files);
}
}
@@ -1848,11 +1849,10 @@ class Dex2Oat FINAL {
compiler_kind_,
instruction_set_,
instruction_set_features_.get(),
- std::move(image_classes_),
+ &compiler_options_->image_classes_,
thread_count_,
swap_fd_,
profile_compilation_info_.get()));
- driver_->SetDexFilesForOatFile(dex_files_);
if (!IsBootImage()) {
driver_->SetClasspathDexFiles(class_loader_context_->FlattenOpenedDexFiles());
}
@@ -1868,9 +1868,10 @@ class Dex2Oat FINAL {
}
// Setup vdex for compilation.
+ const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
if (!DoEagerUnquickeningOfVdex() && input_vdex_file_ != nullptr) {
callbacks_->SetVerifierDeps(
- new verifier::VerifierDeps(dex_files_, input_vdex_file_->GetVerifierDepsData()));
+ new verifier::VerifierDeps(dex_files, input_vdex_file_->GetVerifierDepsData()));
// TODO: we unquicken unconditionally, as we don't know
// if the boot image has changed. How exactly we'll know is under
@@ -1880,11 +1881,11 @@ class Dex2Oat FINAL {
// We do not decompile a RETURN_VOID_NO_BARRIER into a RETURN_VOID, as the quickening
// optimization does not depend on the boot image (the optimization relies on not
// having final fields in a class, which does not change for an app).
- input_vdex_file_->Unquicken(dex_files_, /* decompile_return_instruction */ false);
+ input_vdex_file_->Unquicken(dex_files, /* decompile_return_instruction */ false);
} else {
// Create the main VerifierDeps, here instead of in the compiler since we want to aggregate
// the results for all the dex files, not just the results for the current dex file.
- callbacks_->SetVerifierDeps(new verifier::VerifierDeps(dex_files_));
+ callbacks_->SetVerifierDeps(new verifier::VerifierDeps(dex_files));
}
// Invoke the compilation.
if (compile_individually) {
@@ -1892,7 +1893,7 @@ class Dex2Oat FINAL {
// Return a null classloader since we already freed released it.
return nullptr;
}
- return CompileDexFiles(dex_files_);
+ return CompileDexFiles(dex_files);
}
// Create the class loader, use it to compile, and return.
@@ -1901,7 +1902,8 @@ class Dex2Oat FINAL {
jobject class_loader = nullptr;
if (!IsBootImage()) {
- class_loader = class_loader_context_->CreateClassLoader(dex_files_);
+ class_loader =
+ class_loader_context_->CreateClassLoader(compiler_options_->dex_files_for_oat_file_);
callbacks_->SetDexFiles(&dex_files);
}
@@ -2371,7 +2373,7 @@ class Dex2Oat FINAL {
return dex_files_size >= min_dex_file_cumulative_size_for_swap_;
}
- bool IsVeryLarge(std::vector<const DexFile*>& dex_files) {
+ bool IsVeryLarge(const std::vector<const DexFile*>& dex_files) {
size_t dex_files_size = 0;
for (const auto* dex_file : dex_files) {
dex_files_size += dex_file->GetHeader().file_size_;
@@ -2381,14 +2383,14 @@ class Dex2Oat FINAL {
bool PrepareImageClasses() {
// If --image-classes was specified, calculate the full list of classes to include in the image.
+ DCHECK(compiler_options_->image_classes_.empty());
if (image_classes_filename_ != nullptr) {
- image_classes_ =
+ std::unique_ptr<HashSet<std::string>> image_classes =
ReadClasses(image_classes_zip_filename_, image_classes_filename_, "image");
- if (image_classes_ == nullptr) {
+ if (image_classes == nullptr) {
return false;
}
- } else if (IsBootImage()) {
- image_classes_.reset(new HashSet<std::string>);
+ compiler_options_->image_classes_.swap(*image_classes);
}
return true;
}
@@ -2502,8 +2504,9 @@ class Dex2Oat FINAL {
}
void SaveDexInput() {
- for (size_t i = 0; i < dex_files_.size(); ++i) {
- const DexFile* dex_file = dex_files_[i];
+ const std::vector<const DexFile*>& dex_files = compiler_options_->dex_files_for_oat_file_;
+ for (size_t i = 0, size = dex_files.size(); i != size; ++i) {
+ const DexFile* dex_file = dex_files[i];
std::string tmp_file_name(StringPrintf("/data/local/tmp/dex2oat.%d.%zd.dex",
getpid(), i));
std::unique_ptr<File> tmp_file(OS::CreateEmptyFile(tmp_file_name.c_str()));
@@ -2704,8 +2707,7 @@ class Dex2Oat FINAL {
LOG(ERROR) << "Failed to open input file " << input_filename;
return nullptr;
}
- std::unique_ptr<T> result(
- ReadCommentedInputStream<T>(*input_file, process));
+ std::unique_ptr<T> result = ReadCommentedInputStream<T>(*input_file, process);
input_file->close();
return result;
}
@@ -2851,14 +2853,11 @@ class Dex2Oat FINAL {
ImageHeader::StorageMode image_storage_mode_;
const char* passes_to_run_filename_;
const char* dirty_image_objects_filename_;
- std::unique_ptr<HashSet<std::string>> image_classes_;
std::unique_ptr<HashSet<std::string>> dirty_image_objects_;
std::unique_ptr<std::vector<std::string>> passes_to_run_;
bool multi_image_;
bool is_host_;
std::string android_root_;
- // Dex files we are compiling, does not include the class path dex files.
- std::vector<const DexFile*> dex_files_;
std::string no_inline_from_string_;
CompactDexLevel compact_dex_level_ = kDefaultCompactDexLevel;
@@ -2872,9 +2871,6 @@ class Dex2Oat FINAL {
std::vector<std::unique_ptr<MemMap>> opened_dex_files_maps_;
std::vector<std::unique_ptr<const DexFile>> opened_dex_files_;
- // Note that this might contain pointers owned by class_loader_context_.
- std::vector<const DexFile*> no_inline_from_dex_files_;
-
bool avoid_storing_invocation_;
std::string swap_file_name_;
int swap_fd_;
@@ -2904,7 +2900,7 @@ class Dex2Oat FINAL {
// By default, copy the dex to the vdex file only if dex files are
// compressed in APK.
- CopyOption copy_dex_files_ = CopyOption::kOnlyIfCompressed;
+ linker::CopyOption copy_dex_files_ = linker::CopyOption::kOnlyIfCompressed;
// The reason for invoking the compiler.
std::string compilation_reason_;
diff --git a/dex2oat/dex2oat_options.cc b/dex2oat/dex2oat_options.cc
index dbb00c22e9..bf9edf7384 100644
--- a/dex2oat/dex2oat_options.cc
+++ b/dex2oat/dex2oat_options.cc
@@ -222,10 +222,10 @@ static Parser CreateArgumentParser() {
.Define("--force-determinism")
.IntoKey(M::ForceDeterminism)
.Define("--copy-dex-files=_")
- .WithType<CopyOption>()
- .WithValueMap({{"true", CopyOption::kOnlyIfCompressed},
- {"false", CopyOption::kNever},
- {"always", CopyOption::kAlways}})
+ .WithType<linker::CopyOption>()
+ .WithValueMap({{"true", linker::CopyOption::kOnlyIfCompressed},
+ {"false", linker::CopyOption::kNever},
+ {"always", linker::CopyOption::kAlways}})
.IntoKey(M::CopyDexFiles)
.Define("--classpath-dir=_")
.WithType<std::string>()
diff --git a/dex2oat/dex2oat_options.def b/dex2oat/dex2oat_options.def
index 7be8e56501..fe5c4e69a7 100644
--- a/dex2oat/dex2oat_options.def
+++ b/dex2oat/dex2oat_options.def
@@ -70,7 +70,7 @@ DEX2OAT_OPTIONS_KEY (Unit, Host)
DEX2OAT_OPTIONS_KEY (Unit, DumpTiming)
DEX2OAT_OPTIONS_KEY (Unit, DumpPasses)
DEX2OAT_OPTIONS_KEY (Unit, DumpStats)
-DEX2OAT_OPTIONS_KEY (CopyOption, CopyDexFiles)
+DEX2OAT_OPTIONS_KEY (linker::CopyOption, CopyDexFiles)
DEX2OAT_OPTIONS_KEY (Unit, AvoidStoringInvocation)
DEX2OAT_OPTIONS_KEY (std::string, SwapFile)
DEX2OAT_OPTIONS_KEY (int, SwapFileFd)
diff --git a/dex2oat/dex2oat_options.h b/dex2oat/dex2oat_options.h
index cc124c1afa..27d3d25f2a 100644
--- a/dex2oat/dex2oat_options.h
+++ b/dex2oat/dex2oat_options.h
@@ -28,6 +28,7 @@
#include "dex/compact_dex_level.h"
#include "driver/compiler_options_map.h"
#include "image.h"
+#include "linker/oat_writer.h"
namespace art {
diff --git a/dex2oat/linker/image_test.h b/dex2oat/linker/image_test.h
index 12ecd3a4fc..66b37fb08d 100644
--- a/dex2oat/linker/image_test.h
+++ b/dex2oat/linker/image_test.h
@@ -63,9 +63,6 @@ struct CompilationHelper {
std::vector<ScratchFile> vdex_files;
std::string image_dir;
- void Compile(CompilerDriver* driver,
- ImageHeader::StorageMode storage_mode);
-
std::vector<size_t> GetImageObjectSectionSizes();
~CompilationHelper();
@@ -81,7 +78,7 @@ class ImageTest : public CommonCompilerTest {
void TestWriteRead(ImageHeader::StorageMode storage_mode);
void Compile(ImageHeader::StorageMode storage_mode,
- CompilationHelper& out_helper,
+ /*out*/ CompilationHelper& out_helper,
const std::string& extra_dex = "",
const std::initializer_list<std::string>& image_classes = {});
@@ -111,6 +108,8 @@ class ImageTest : public CommonCompilerTest {
}
private:
+ void DoCompile(ImageHeader::StorageMode storage_mode, /*out*/ CompilationHelper& out_helper);
+
HashSet<std::string> image_classes_;
};
@@ -141,12 +140,13 @@ inline std::vector<size_t> CompilationHelper::GetImageObjectSectionSizes() {
return ret;
}
-inline void CompilationHelper::Compile(CompilerDriver* driver,
- ImageHeader::StorageMode storage_mode) {
+inline void ImageTest::DoCompile(ImageHeader::StorageMode storage_mode,
+ /*out*/ CompilationHelper& out_helper) {
+ CompilerDriver* driver = compiler_driver_.get();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
std::vector<const DexFile*> class_path = class_linker->GetBootClassPath();
- for (const std::unique_ptr<const DexFile>& dex_file : extra_dex_files) {
+ for (const std::unique_ptr<const DexFile>& dex_file : out_helper.extra_dex_files) {
{
ScopedObjectAccess soa(Thread::Current());
// Inject in boot class path so that the compiler driver can see it.
@@ -157,7 +157,7 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
// Enable write for dex2dex.
for (const DexFile* dex_file : class_path) {
- dex_file_locations.push_back(dex_file->GetLocation());
+ out_helper.dex_file_locations.push_back(dex_file->GetLocation());
if (dex_file->IsReadOnly()) {
dex_file->EnableWrite();
}
@@ -168,31 +168,31 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
for (int i = 0; i < static_cast<int>(class_path.size()); ++i) {
std::string cur_location =
android::base::StringPrintf("%s-%d.art", location.GetFilename().c_str(), i);
- image_locations.push_back(ScratchFile(cur_location));
+ out_helper.image_locations.push_back(ScratchFile(cur_location));
}
}
std::vector<std::string> image_filenames;
- for (ScratchFile& file : image_locations) {
+ for (ScratchFile& file : out_helper.image_locations) {
std::string image_filename(GetSystemImageFilename(file.GetFilename().c_str(), kRuntimeISA));
image_filenames.push_back(image_filename);
size_t pos = image_filename.rfind('/');
CHECK_NE(pos, std::string::npos) << image_filename;
- if (image_dir.empty()) {
- image_dir = image_filename.substr(0, pos);
- int mkdir_result = mkdir(image_dir.c_str(), 0700);
- CHECK_EQ(0, mkdir_result) << image_dir;
+ if (out_helper.image_dir.empty()) {
+ out_helper.image_dir = image_filename.substr(0, pos);
+ int mkdir_result = mkdir(out_helper.image_dir.c_str(), 0700);
+ CHECK_EQ(0, mkdir_result) << out_helper.image_dir;
}
- image_files.push_back(ScratchFile(OS::CreateEmptyFile(image_filename.c_str())));
+ out_helper.image_files.push_back(ScratchFile(OS::CreateEmptyFile(image_filename.c_str())));
}
std::vector<std::string> oat_filenames;
std::vector<std::string> vdex_filenames;
for (const std::string& image_filename : image_filenames) {
std::string oat_filename = ReplaceFileExtension(image_filename, "oat");
- oat_files.push_back(ScratchFile(OS::CreateEmptyFile(oat_filename.c_str())));
+ out_helper.oat_files.push_back(ScratchFile(OS::CreateEmptyFile(oat_filename.c_str())));
oat_filenames.push_back(oat_filename);
std::string vdex_filename = ReplaceFileExtension(image_filename, "vdex");
- vdex_files.push_back(ScratchFile(OS::CreateEmptyFile(vdex_filename.c_str())));
+ out_helper.vdex_files.push_back(ScratchFile(OS::CreateEmptyFile(vdex_filename.c_str())));
vdex_filenames.push_back(vdex_filename);
}
@@ -224,7 +224,7 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
jobject class_loader = nullptr;
TimingLogger timings("ImageTest::WriteRead", false, false);
TimingLogger::ScopedTiming t("CompileAll", &timings);
- driver->SetDexFilesForOatFile(class_path);
+ SetDexFilesForOatFile(class_path);
driver->CompileAll(class_loader, class_path, &timings);
t.NewTiming("WriteElf");
@@ -241,7 +241,7 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
std::vector<std::unique_ptr<ElfWriter>> elf_writers;
std::vector<std::unique_ptr<OatWriter>> oat_writers;
- for (ScratchFile& oat_file : oat_files) {
+ for (ScratchFile& oat_file : out_helper.oat_files) {
elf_writers.emplace_back(CreateElfWriterQuick(driver->GetInstructionSet(),
driver->GetInstructionSetFeatures(),
&driver->GetCompilerOptions(),
@@ -270,7 +270,7 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
std::vector<std::unique_ptr<MemMap>> cur_opened_dex_files_maps;
std::vector<std::unique_ptr<const DexFile>> cur_opened_dex_files;
bool dex_files_ok = oat_writers[i]->WriteAndOpenDexFiles(
- vdex_files[i].GetFile(),
+ out_helper.vdex_files[i].GetFile(),
rodata.back(),
driver->GetInstructionSet(),
driver->GetInstructionSetFeatures(),
@@ -297,8 +297,8 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
bool image_space_ok = writer->PrepareImageAddressSpace(&timings);
ASSERT_TRUE(image_space_ok);
- DCHECK_EQ(vdex_files.size(), oat_files.size());
- for (size_t i = 0, size = oat_files.size(); i != size; ++i) {
+ DCHECK_EQ(out_helper.vdex_files.size(), out_helper.oat_files.size());
+ for (size_t i = 0, size = out_helper.oat_files.size(); i != size; ++i) {
MultiOatRelativePatcher patcher(driver->GetInstructionSet(),
driver->GetInstructionSetFeatures(),
driver->GetCompiledMethodStorage());
@@ -309,7 +309,7 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
std::unique_ptr<BufferedOutputStream> vdex_out =
std::make_unique<BufferedOutputStream>(
- std::make_unique<FileOutputStream>(vdex_files[i].GetFile()));
+ std::make_unique<FileOutputStream>(out_helper.vdex_files[i].GetFile()));
oat_writer->WriteVerifierDeps(vdex_out.get(), nullptr);
oat_writer->WriteQuickeningInfo(vdex_out.get());
oat_writer->WriteChecksumsAndVdexHeader(vdex_out.get());
@@ -366,8 +366,7 @@ inline void CompilationHelper::Compile(CompilerDriver* driver,
const char* oat_filename = oat_filenames[i].c_str();
std::unique_ptr<File> oat_file(OS::OpenFileReadWrite(oat_filename));
ASSERT_TRUE(oat_file != nullptr);
- bool success_fixup = ElfWriter::Fixup(oat_file.get(),
- writer->GetOatDataBegin(i));
+ bool success_fixup = ElfWriter::Fixup(oat_file.get(), writer->GetOatDataBegin(i));
ASSERT_TRUE(success_fixup);
ASSERT_EQ(oat_file->FlushCloseOrErase(), 0) << "Could not flush and close oat file "
<< oat_filename;
@@ -389,7 +388,7 @@ inline void ImageTest::Compile(ImageHeader::StorageMode storage_mode,
if (!extra_dex.empty()) {
helper.extra_dex_files = OpenTestDexFiles(extra_dex.c_str());
}
- helper.Compile(compiler_driver_.get(), storage_mode);
+ DoCompile(storage_mode, helper);
if (image_classes.begin() != image_classes.end()) {
// Make sure the class got initialized.
ScopedObjectAccess soa(Thread::Current());
@@ -426,9 +425,6 @@ inline void ImageTest::TestWriteRead(ImageHeader::StorageMode storage_mode) {
image_file_sizes.push_back(file->GetLength());
}
- ASSERT_TRUE(compiler_driver_->GetImageClasses() != nullptr);
- HashSet<std::string> image_classes(*compiler_driver_->GetImageClasses());
-
// Need to delete the compiler since it has worker threads which are attached to runtime.
compiler_driver_.reset();
@@ -469,6 +465,7 @@ inline void ImageTest::TestWriteRead(ImageHeader::StorageMode storage_mode) {
// We loaded the runtime with an explicit image, so it must exist.
ASSERT_EQ(heap->GetBootImageSpaces().size(), image_file_sizes.size());
+ const HashSet<std::string>& image_classes = compiler_options_->GetImageClasses();
for (size_t i = 0; i < helper.dex_file_locations.size(); ++i) {
std::unique_ptr<const DexFile> dex(
LoadExpectSingleDexFile(helper.dex_file_locations[i].c_str()));
diff --git a/dex2oat/linker/image_writer.cc b/dex2oat/linker/image_writer.cc
index a61ad8f7c2..bb730d3374 100644
--- a/dex2oat/linker/image_writer.cc
+++ b/dex2oat/linker/image_writer.cc
@@ -38,6 +38,7 @@
#include "dex/dex_file-inl.h"
#include "dex/dex_file_types.h"
#include "driver/compiler_driver.h"
+#include "driver/compiler_options.h"
#include "elf_file.h"
#include "elf_utils.h"
#include "gc/accounting/card_table-inl.h"
@@ -441,7 +442,7 @@ void ImageWriter::PrepareDexCacheArraySlots() {
// Prepare dex cache array starts based on the ordering specified in the CompilerDriver.
// Set the slot size early to avoid DCHECK() failures in IsImageBinSlotAssigned()
// when AssignImageBinSlot() assigns their indexes out or order.
- for (const DexFile* dex_file : compiler_driver_.GetDexFilesForOatFile()) {
+ for (const DexFile* dex_file : compiler_driver_.GetCompilerOptions().GetDexFilesForOatFile()) {
auto it = dex_file_oat_index_map_.find(dex_file);
DCHECK(it != dex_file_oat_index_map_.end()) << dex_file->GetLocation();
ImageInfo& image_info = GetImageInfo(it->second);
@@ -851,7 +852,8 @@ bool ImageWriter::PruneAppImageClassInternal(
std::string temp;
// Prune if not an image class, this handles any broken sets of image classes such as having a
// class in the set but not it's superclass.
- result = result || !compiler_driver_.IsImageClass(klass->GetDescriptor(&temp));
+ result = result ||
+ !compiler_driver_.GetCompilerOptions().IsImageClass(klass->GetDescriptor(&temp));
bool my_early_exit = false; // Only for ourselves, ignore caller.
// Remove classes that failed to verify since we don't want to have java.lang.VerifyError in the
// app image.
@@ -941,7 +943,7 @@ bool ImageWriter::KeepClass(ObjPtr<mirror::Class> klass) {
return true;
}
std::string temp;
- if (!compiler_driver_.IsImageClass(klass->GetDescriptor(&temp))) {
+ if (!compiler_driver_.GetCompilerOptions().IsImageClass(klass->GetDescriptor(&temp))) {
return false;
}
if (compile_app_image_) {
@@ -1212,27 +1214,22 @@ void ImageWriter::PruneNonImageClasses() {
}
void ImageWriter::CheckNonImageClassesRemoved() {
- if (compiler_driver_.GetImageClasses() != nullptr) {
- auto visitor = [&](Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
- if (obj->IsClass() && !IsInBootImage(obj)) {
- Class* klass = obj->AsClass();
- if (!KeepClass(klass)) {
- DumpImageClasses();
- std::string temp;
- CHECK(KeepClass(klass))
- << Runtime::Current()->GetHeap()->GetVerification()->FirstPathFromRootSet(klass);
- }
+ auto visitor = [&](Object* obj) REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (obj->IsClass() && !IsInBootImage(obj)) {
+ Class* klass = obj->AsClass();
+ if (!KeepClass(klass)) {
+ DumpImageClasses();
+ CHECK(KeepClass(klass))
+ << Runtime::Current()->GetHeap()->GetVerification()->FirstPathFromRootSet(klass);
}
- };
- gc::Heap* heap = Runtime::Current()->GetHeap();
- heap->VisitObjects(visitor);
- }
+ }
+ };
+ gc::Heap* heap = Runtime::Current()->GetHeap();
+ heap->VisitObjects(visitor);
}
void ImageWriter::DumpImageClasses() {
- auto image_classes = compiler_driver_.GetImageClasses();
- CHECK(image_classes != nullptr);
- for (const std::string& image_class : *image_classes) {
+ for (const std::string& image_class : compiler_driver_.GetCompilerOptions().GetImageClasses()) {
LOG(INFO) << " " << image_class;
}
}
@@ -1741,7 +1738,7 @@ void ImageWriter::CalculateNewObjectOffsets() {
WorkStack work_stack;
// Special case interned strings to put them in the image they are likely to be resolved from.
- for (const DexFile* dex_file : compiler_driver_.GetDexFilesForOatFile()) {
+ for (const DexFile* dex_file : compiler_driver_.GetCompilerOptions().GetDexFilesForOatFile()) {
auto it = dex_file_oat_index_map_.find(dex_file);
DCHECK(it != dex_file_oat_index_map_.end()) << dex_file->GetLocation();
const size_t oat_index = it->second;
diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc
index 99516684e8..0ed9579aed 100644
--- a/dex2oat/linker/oat_writer.cc
+++ b/dex2oat/linker/oat_writer.cc
@@ -366,6 +366,7 @@ OatWriter::OatWriter(bool compiling_boot_image,
zipped_dex_files_(),
zipped_dex_file_locations_(),
compiler_driver_(nullptr),
+ compiler_options_(nullptr),
image_writer_(nullptr),
compiling_boot_image_(compiling_boot_image),
extract_dex_files_into_vdex_(true),
@@ -642,8 +643,7 @@ dchecked_vector<std::string> OatWriter::GetSourceLocations() const {
}
bool OatWriter::MayHaveCompiledMethods() const {
- return CompilerFilter::IsAnyCompilationEnabled(
- GetCompilerDriver()->GetCompilerOptions().GetCompilerFilter());
+ return GetCompilerOptions().IsAnyCompilationEnabled();
}
bool OatWriter::WriteAndOpenDexFiles(
@@ -703,6 +703,16 @@ bool OatWriter::WriteAndOpenDexFiles(
return true;
}
+// Initialize the writer with the given parameters.
+void OatWriter::Initialize(const CompilerDriver* compiler_driver,
+ ImageWriter* image_writer,
+ const std::vector<const DexFile*>& dex_files) {
+ compiler_driver_ = compiler_driver;
+ compiler_options_ = &compiler_driver->GetCompilerOptions();
+ image_writer_ = image_writer;
+ dex_files_ = &dex_files;
+}
+
void OatWriter::PrepareLayout(MultiOatRelativePatcher* relative_patcher) {
CHECK(write_state_ == WriteState::kPrepareLayout);
@@ -1157,7 +1167,7 @@ class OatWriter::LayoutCodeMethodVisitor : public OatDexMethodVisitor {
size_t debug_info_idx = OrderedMethodData::kDebugInfoIdxInvalid;
{
- const CompilerOptions& compiler_options = writer_->compiler_driver_->GetCompilerOptions();
+ const CompilerOptions& compiler_options = writer_->GetCompilerOptions();
ArrayRef<const uint8_t> quick_code = compiled_method->GetQuickCode();
uint32_t code_size = quick_code.size() * sizeof(uint8_t);
@@ -1238,7 +1248,7 @@ class OatWriter::LayoutReserveOffsetCodeMethodVisitor : public OrderedMethodVisi
OrderedMethodList ordered_methods)
: LayoutReserveOffsetCodeMethodVisitor(writer,
offset,
- writer->GetCompilerDriver()->GetCompilerOptions(),
+ writer->GetCompilerOptions(),
std::move(ordered_methods)) {
}
@@ -1651,7 +1661,7 @@ class OatWriter::InitImageMethodVisitor : public OatDexMethodVisitor {
const DexFile::TypeId& type_id =
dex_file_->GetTypeId(dex_file_->GetClassDef(class_def_index_).class_idx_);
const char* class_descriptor = dex_file_->GetTypeDescriptor(type_id);
- return writer_->GetCompilerDriver()->IsImageClass(class_descriptor);
+ return writer_->GetCompilerOptions().IsImageClass(class_descriptor);
}
// Check whether specified dex file is in the compiled oat file.
@@ -1717,7 +1727,7 @@ class OatWriter::WriteCodeMethodVisitor : public OrderedMethodVisitor {
// Ordered method visiting is only for compiled methods.
DCHECK(writer_->MayHaveCompiledMethods());
- if (writer_->GetCompilerDriver()->GetCompilerOptions().IsAotCompilationEnabled()) {
+ if (writer_->GetCompilerOptions().IsAotCompilationEnabled()) {
// Only need to set the dex cache if we have compilation. Other modes might have unloaded it.
if (dex_cache_ == nullptr || dex_cache_->GetDexFile() != dex_file) {
dex_cache_ = class_linker_->FindDexCache(Thread::Current(), *dex_file);
@@ -2388,9 +2398,9 @@ size_t OatWriter::InitOatCode(size_t offset) {
// TODO: Remove unused trampoline offsets from the OatHeader (requires oat version change).
oat_header_->SetInterpreterToInterpreterBridgeOffset(0);
oat_header_->SetInterpreterToCompiledCodeBridgeOffset(0);
- if (compiler_driver_->GetCompilerOptions().IsBootImage()) {
+ if (GetCompilerOptions().IsBootImage()) {
InstructionSet instruction_set = compiler_driver_->GetInstructionSet();
- const bool generate_debug_info = compiler_driver_->GetCompilerOptions().GenerateAnyDebugInfo();
+ const bool generate_debug_info = GetCompilerOptions().GenerateAnyDebugInfo();
size_t adjusted_offset = offset;
#define DO_TRAMPOLINE(field, fn_name) \
@@ -2428,7 +2438,7 @@ size_t OatWriter::InitOatCode(size_t offset) {
}
size_t OatWriter::InitOatCodeDexFiles(size_t offset) {
- if (!compiler_driver_->GetCompilerOptions().IsAnyCompilationEnabled()) {
+ if (!GetCompilerOptions().IsAnyCompilationEnabled()) {
if (kOatWriterDebugOatCodeLayout) {
LOG(INFO) << "InitOatCodeDexFiles: OatWriter("
<< this << "), "
@@ -2741,7 +2751,7 @@ bool OatWriter::WriteQuickeningInfo(OutputStream* vdex_out) {
}
size_t current_offset = start_offset;
- if (compiler_driver_->GetCompilerOptions().IsQuickeningCompilationEnabled()) {
+ if (GetCompilerOptions().IsQuickeningCompilationEnabled()) {
std::vector<uint32_t> dex_files_indices;
WriteQuickeningInfoMethodVisitor write_quicken_info_visitor(this, vdex_out);
if (!write_quicken_info_visitor.VisitDexMethods(*dex_files_)) {
@@ -3019,7 +3029,7 @@ bool OatWriter::WriteHeader(OutputStream* out,
oat_header_->SetImageFileLocationOatChecksum(image_file_location_oat_checksum);
oat_header_->SetImageFileLocationOatDataBegin(image_file_location_oat_begin);
- if (compiler_driver_->GetCompilerOptions().IsBootImage()) {
+ if (GetCompilerOptions().IsBootImage()) {
CHECK_EQ(image_patch_delta, 0);
CHECK_EQ(oat_header_->GetImagePatchDelta(), 0);
} else {
@@ -3283,7 +3293,7 @@ size_t OatWriter::WriteOatDexFiles(OutputStream* out, size_t file_offset, size_t
}
size_t OatWriter::WriteCode(OutputStream* out, size_t file_offset, size_t relative_offset) {
- if (compiler_driver_->GetCompilerOptions().IsBootImage()) {
+ if (GetCompilerOptions().IsBootImage()) {
InstructionSet instruction_set = compiler_driver_->GetInstructionSet();
#define DO_TRAMPOLINE(field) \
@@ -3314,7 +3324,7 @@ size_t OatWriter::WriteCode(OutputStream* out, size_t file_offset, size_t relati
size_t OatWriter::WriteCodeDexFiles(OutputStream* out,
size_t file_offset,
size_t relative_offset) {
- if (!compiler_driver_->GetCompilerOptions().IsAnyCompilationEnabled()) {
+ if (!GetCompilerOptions().IsAnyCompilationEnabled()) {
// As with InitOatCodeDexFiles, also skip the writer if
// compilation was disabled.
if (kOatWriterDebugOatCodeLayout) {
diff --git a/dex2oat/linker/oat_writer.h b/dex2oat/linker/oat_writer.h
index 619743ef14..e8eee88bcd 100644
--- a/dex2oat/linker/oat_writer.h
+++ b/dex2oat/linker/oat_writer.h
@@ -27,7 +27,6 @@
#include "base/os.h"
#include "base/mem_map.h"
#include "base/safe_map.h"
-#include "compiler.h"
#include "debug/debug_info.h"
#include "dex/compact_dex_level.h"
#include "dex/method_reference.h"
@@ -42,6 +41,7 @@ namespace art {
class BitVector;
class CompiledMethod;
class CompilerDriver;
+class CompilerOptions;
class DexContainer;
class ProfileCompilationInfo;
class TimingLogger;
@@ -63,6 +63,12 @@ class ImageWriter;
class MultiOatRelativePatcher;
class OutputStream;
+enum class CopyOption {
+ kNever,
+ kAlways,
+ kOnlyIfCompressed
+};
+
// OatHeader variable length with count of D OatDexFiles
//
// TypeLookupTable[0] one descriptor to class def index hash table for each OatDexFile.
@@ -180,17 +186,13 @@ class OatWriter {
CopyOption copy_dex_files,
/*out*/ std::vector<std::unique_ptr<MemMap>>* opened_dex_files_map,
/*out*/ std::vector<std::unique_ptr<const DexFile>>* opened_dex_files);
+ // Initialize the writer with the given parameters.
+ void Initialize(const CompilerDriver* compiler_driver,
+ ImageWriter* image_writer,
+ const std::vector<const DexFile*>& dex_files);
bool WriteQuickeningInfo(OutputStream* vdex_out);
bool WriteVerifierDeps(OutputStream* vdex_out, verifier::VerifierDeps* verifier_deps);
bool WriteChecksumsAndVdexHeader(OutputStream* vdex_out);
- // Initialize the writer with the given parameters.
- void Initialize(const CompilerDriver* compiler,
- ImageWriter* image_writer,
- const std::vector<const DexFile*>& dex_files) {
- compiler_driver_ = compiler;
- image_writer_ = image_writer;
- dex_files_ = &dex_files;
- }
// Prepare layout of remaining data.
void PrepareLayout(MultiOatRelativePatcher* relative_patcher);
@@ -263,6 +265,11 @@ class OatWriter {
return compiler_driver_;
}
+ const CompilerOptions& GetCompilerOptions() const {
+ DCHECK(compiler_options_ != nullptr);
+ return *compiler_options_;
+ }
+
private:
class DexFileSource;
class OatClassHeader;
@@ -388,6 +395,7 @@ class OatWriter {
dchecked_vector<debug::MethodDebugInfo> method_info_;
const CompilerDriver* compiler_driver_;
+ const CompilerOptions* compiler_options_;
ImageWriter* image_writer_;
const bool compiling_boot_image_;
// Whether the dex files being compiled are going to be extracted to the vdex.
diff --git a/dex2oat/linker/oat_writer_test.cc b/dex2oat/linker/oat_writer_test.cc
index 2bc286a7f4..e43a7f3d0c 100644
--- a/dex2oat/linker/oat_writer_test.cc
+++ b/dex2oat/linker/oat_writer_test.cc
@@ -409,7 +409,7 @@ TEST_F(OatTest, WriteRead) {
jobject class_loader = nullptr;
if (kCompile) {
TimingLogger timings2("OatTest::WriteRead", false, false);
- compiler_driver_->SetDexFilesForOatFile(class_linker->GetBootClassPath());
+ SetDexFilesForOatFile(class_linker->GetBootClassPath());
compiler_driver_->CompileAll(class_loader, class_linker->GetBootClassPath(), &timings2);
}
@@ -547,7 +547,7 @@ TEST_F(OatTest, EmptyTextSection) {
ScopedObjectAccess soa(Thread::Current());
class_linker->RegisterDexFile(*dex_file, soa.Decode<mirror::ClassLoader>(class_loader));
}
- compiler_driver_->SetDexFilesForOatFile(dex_files);
+ SetDexFilesForOatFile(dex_files);
compiler_driver_->CompileAll(class_loader, dex_files, &timings);
ScratchFile tmp_base, tmp_oat(tmp_base, ".oat"), tmp_vdex(tmp_base, ".vdex");
diff --git a/libdexfile/dex/dex_file-inl.h b/libdexfile/dex/dex_file-inl.h
index f5dd374253..09668594dd 100644
--- a/libdexfile/dex/dex_file-inl.h
+++ b/libdexfile/dex/dex_file-inl.h
@@ -17,12 +17,14 @@
#ifndef ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_
#define ART_LIBDEXFILE_DEX_DEX_FILE_INL_H_
+#include "dex_file.h"
+
#include "base/casts.h"
#include "base/leb128.h"
#include "base/stringpiece.h"
#include "class_iterator.h"
#include "compact_dex_file.h"
-#include "dex_file.h"
+#include "dex_instruction_iterator.h"
#include "invoke_type.h"
#include "standard_dex_file.h"
diff --git a/libdexfile/dex/dex_file.h b/libdexfile/dex/dex_file.h
index a8cd1871b4..67abdca148 100644
--- a/libdexfile/dex/dex_file.h
+++ b/libdexfile/dex/dex_file.h
@@ -29,7 +29,6 @@
#include "base/value_object.h"
#include "class_iterator.h"
#include "dex_file_types.h"
-#include "dex_instruction_iterator.h"
#include "hidden_api_access_flags.h"
#include "jni.h"
#include "modifiers.h"
@@ -38,6 +37,7 @@ namespace art {
class ClassDataItemIterator;
class CompactDexFile;
+class DexInstructionIterator;
enum InvokeType : uint32_t;
class MemMap;
class OatDexFile;
diff --git a/runtime/Android.bp b/runtime/Android.bp
index b347019be2..0345c2f4f7 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -338,14 +338,10 @@ libart_cc_defaults {
"thread_android.cc",
],
shared_libs: [
- // For android::FileMap used by libziparchive.
- "libutils",
"libtombstoned_client",
],
static_libs: [
- // ZipArchive support, the order matters here to get all symbols.
- "libziparchive",
- "libz",
+ "libz", // For adler32.
],
},
android_arm: {
@@ -367,8 +363,7 @@ libart_cc_defaults {
"thread_linux.cc",
],
shared_libs: [
- "libziparchive",
- "libz",
+ "libz", // For adler32.
],
},
},
@@ -600,7 +595,6 @@ art_cc_test {
],
shared_libs: [
"libbacktrace",
- "libziparchive",
],
header_libs: [
"art_cmdlineparser_headers", // For parsed_options_test.
diff --git a/runtime/base/mutex-inl.h b/runtime/base/mutex-inl.h
index dfa14b91f0..51ca274cbb 100644
--- a/runtime/base/mutex-inl.h
+++ b/runtime/base/mutex-inl.h
@@ -290,10 +290,6 @@ inline ReaderMutexLock::~ReaderMutexLock() {
mu_.SharedUnlock(self_);
}
-// Catch bug where variable name is omitted. "ReaderMutexLock (lock);" instead of
-// "ReaderMutexLock mu(lock)".
-#define ReaderMutexLock(x) static_assert(0, "ReaderMutexLock declaration missing variable name")
-
} // namespace art
#endif // ART_RUNTIME_BASE_MUTEX_INL_H_
diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h
index 602d183bbb..ee47e7ce56 100644
--- a/runtime/base/mutex.h
+++ b/runtime/base/mutex.h
@@ -525,8 +525,6 @@ class SCOPED_CAPABILITY MutexLock {
Mutex& mu_;
DISALLOW_COPY_AND_ASSIGN(MutexLock);
};
-// Catch bug where variable name is omitted. "MutexLock (lock);" instead of "MutexLock mu(lock)".
-#define MutexLock(x) static_assert(0, "MutexLock declaration missing variable name")
// Scoped locker/unlocker for a ReaderWriterMutex that acquires read access to mu upon
// construction and releases it upon destruction.
@@ -560,9 +558,6 @@ class SCOPED_CAPABILITY WriterMutexLock {
ReaderWriterMutex& mu_;
DISALLOW_COPY_AND_ASSIGN(WriterMutexLock);
};
-// Catch bug where variable name is omitted. "WriterMutexLock (lock);" instead of
-// "WriterMutexLock mu(lock)".
-#define WriterMutexLock(x) static_assert(0, "WriterMutexLock declaration missing variable name")
// For StartNoThreadSuspension and EndNoThreadSuspension.
class CAPABILITY("role") Role {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 19554cd44c..7b92ba41a5 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -805,7 +805,7 @@ void ClassLinker::FinishInit(Thread* self) {
// Note: we hard code the field indexes here rather than using FindInstanceField
// as the types of the field can't be resolved prior to the runtime being
// fully initialized
- StackHandleScope<2> hs(self);
+ StackHandleScope<3> hs(self);
Handle<mirror::Class> java_lang_ref_Reference =
hs.NewHandle(GetClassRoot<mirror::Reference>(this));
Handle<mirror::Class> java_lang_ref_FinalizerReference =
@@ -847,6 +847,20 @@ void ClassLinker::FinishInit(Thread* self) {
// that Object, Class, and Object[] are setup
init_done_ = true;
+ // Under sanitization, the small carve-out to handle stack overflow might not be enough to
+ // initialize the StackOverflowError class (as it might require running the verifier). Instead,
+ // ensure that the class will be initialized.
+ if (kMemoryToolIsAvailable && !Runtime::Current()->IsAotCompiler()) {
+ verifier::MethodVerifier::Init(); // Need to prepare the verifier.
+
+ ObjPtr<mirror::Class> soe_klass = FindSystemClass(self, "Ljava/lang/StackOverflowError;");
+ if (soe_klass == nullptr || !EnsureInitialized(self, hs.NewHandle(soe_klass), true, true)) {
+ // Strange, but don't crash.
+ LOG(WARNING) << "Could not prepare StackOverflowError.";
+ self->ClearException();
+ }
+ }
+
VLOG(startup) << "ClassLinker::FinishInit exiting";
}
diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc
index cbd98800f4..12baede59b 100644
--- a/runtime/gc/collector/concurrent_copying.cc
+++ b/runtime/gc/collector/concurrent_copying.cc
@@ -2153,10 +2153,12 @@ inline void ConcurrentCopying::Process(mirror::Object* obj, MemberOffset offset)
break;
}
// Use release CAS to make sure threads reading the reference see contents of copied objects.
- } while (!obj->CasFieldWeakReleaseObjectWithoutWriteBarrier<false, false, kVerifyNone>(
+ } while (!obj->CasFieldObjectWithoutWriteBarrier<false, false, kVerifyNone>(
offset,
expected_ref,
- new_ref));
+ new_ref,
+ CASMode::kWeak,
+ std::memory_order_release));
}
// Process some roots.
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 8e3bbde224..58becb1d09 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -37,7 +37,6 @@
#include "base/systrace.h"
#include "base/time_utils.h"
#include "common_throws.h"
-#include "cutils/sched_policy.h"
#include "debugger.h"
#include "dex/dex_file-inl.h"
#include "entrypoints/quick/quick_alloc_entrypoints.h"
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index 7bd5a6a68a..c9e8426340 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -24,7 +24,6 @@
#include "hprof.h"
-#include <cutils/open_memstream.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 6a4cf56e2a..22a6e9d941 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -1485,13 +1485,17 @@ void UnstartedRuntime::UnstartedUnsafeCompareAndSwapObject(
bool success;
// Check whether we're in a transaction, call accordingly.
if (Runtime::Current()->IsActiveTransaction()) {
- success = obj->CasFieldStrongSequentiallyConsistentObject<true>(MemberOffset(offset),
- expected_value,
- newValue);
+ success = obj->CasFieldObject<true>(MemberOffset(offset),
+ expected_value,
+ newValue,
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
} else {
- success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
- expected_value,
- newValue);
+ success = obj->CasFieldObject<false>(MemberOffset(offset),
+ expected_value,
+ newValue,
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
}
result->SetZ(success ? 1 : 0);
}
diff --git a/runtime/jit/profiling_info_test.cc b/runtime/jit/profiling_info_test.cc
index 106a80a568..8424610cf8 100644
--- a/runtime/jit/profiling_info_test.cc
+++ b/runtime/jit/profiling_info_test.cc
@@ -31,7 +31,6 @@
#include "mirror/class_loader.h"
#include "profile/profile_compilation_info.h"
#include "scoped_thread_state_change-inl.h"
-#include "ziparchive/zip_writer.h"
namespace art {
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 44b0c2b007..26dba024c6 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -114,13 +114,17 @@ ClassExt* Class::EnsureExtDataPresent(Thread* self) {
bool set;
// Set the ext_data_ field using CAS semantics.
if (Runtime::Current()->IsActiveTransaction()) {
- set = h_this->CasFieldStrongSequentiallyConsistentObject<true>(ext_offset,
- ObjPtr<ClassExt>(nullptr),
- new_ext.Get());
+ set = h_this->CasFieldObject<true>(ext_offset,
+ nullptr,
+ new_ext.Get(),
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
} else {
- set = h_this->CasFieldStrongSequentiallyConsistentObject<false>(ext_offset,
- ObjPtr<ClassExt>(nullptr),
- new_ext.Get());
+ set = h_this->CasFieldObject<false>(ext_offset,
+ nullptr,
+ new_ext.Get(),
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
}
ObjPtr<ClassExt> ret(set ? new_ext.Get() : h_this->GetExtData());
DCHECK(!set || h_this->GetExtData() == new_ext.Get());
diff --git a/runtime/mirror/object-inl.h b/runtime/mirror/object-inl.h
index d94ded0f01..47f0a298de 100644
--- a/runtime/mirror/object-inl.h
+++ b/runtime/mirror/object-inl.h
@@ -665,22 +665,11 @@ inline HeapReference<Object>* Object::GetFieldObjectReferenceAddr(MemberOffset f
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- bool success = CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier<
- kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
- if (success) {
- WriteBarrier::ForFieldWrite(this, field_offset, new_value);
- }
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
+inline bool Object::CasFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order) {
VerifyTransaction<kTransactionActive, kCheckTransaction>();
VerifyCAS<kVerifyFlags>(new_value, old_value);
if (kTransactionActive) {
@@ -690,17 +679,21 @@ inline bool Object::CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(
uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetWeakSequentiallyConsistent(old_ref, new_ref);
- return success;
+ return atomic_addr->CompareAndSet(old_ref, new_ref, mode, memory_order);
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- bool success = CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier<
- kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset, old_value, new_value);
+inline bool Object::CasFieldObject(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order) {
+ bool success = CasFieldObjectWithoutWriteBarrier<
+ kTransactionActive, kCheckTransaction, kVerifyFlags>(field_offset,
+ old_value,
+ new_value,
+ mode,
+ memory_order);
if (success) {
WriteBarrier::ForFieldWrite(this, field_offset, new_value);
}
@@ -708,63 +701,6 @@ inline bool Object::CasFieldStrongSequentiallyConsistentObject(MemberOffset fiel
}
template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- VerifyTransaction<kTransactionActive, kCheckTransaction>();
- VerifyCAS<kVerifyFlags>(new_value, old_value);
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetStrongSequentiallyConsistent(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakRelaxedObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- VerifyTransaction<kTransactionActive, kCheckTransaction>();
- VerifyCAS<kVerifyFlags>(new_value, old_value);
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetWeakRelaxed(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldWeakReleaseObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- VerifyTransaction<kTransactionActive, kCheckTransaction>();
- VerifyCAS<kVerifyFlags>(new_value, old_value);
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetWeakRelease(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
inline ObjPtr<Object> Object::CompareAndExchangeFieldObject(MemberOffset field_offset,
ObjPtr<Object> old_value,
ObjPtr<Object> new_value) {
diff --git a/runtime/mirror/object-readbarrier-inl.h b/runtime/mirror/object-readbarrier-inl.h
index 634a83a6a5..df50d0613a 100644
--- a/runtime/mirror/object-readbarrier-inl.h
+++ b/runtime/mirror/object-readbarrier-inl.h
@@ -193,64 +193,6 @@ inline bool Object::AtomicSetMarkBit(uint32_t expected_mark_bit, uint32_t mark_b
return true;
}
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongRelaxedObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- if (kCheckTransaction) {
- DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
- }
- if (kVerifyFlags & kVerifyThis) {
- VerifyObject(this);
- }
- if (kVerifyFlags & kVerifyWrites) {
- VerifyObject(new_value);
- }
- if (kVerifyFlags & kVerifyReads) {
- VerifyObject(old_value);
- }
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetStrongRelaxed(old_ref, new_ref);
- return success;
-}
-
-template<bool kTransactionActive, bool kCheckTransaction, VerifyObjectFlags kVerifyFlags>
-inline bool Object::CasFieldStrongReleaseObjectWithoutWriteBarrier(
- MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value) {
- if (kCheckTransaction) {
- DCHECK_EQ(kTransactionActive, Runtime::Current()->IsActiveTransaction());
- }
- if (kVerifyFlags & kVerifyThis) {
- VerifyObject(this);
- }
- if (kVerifyFlags & kVerifyWrites) {
- VerifyObject(new_value);
- }
- if (kVerifyFlags & kVerifyReads) {
- VerifyObject(old_value);
- }
- if (kTransactionActive) {
- Runtime::Current()->RecordWriteFieldReference(this, field_offset, old_value, true);
- }
- uint32_t old_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(old_value));
- uint32_t new_ref(PtrCompression<kPoisonHeapReferences, Object>::Compress(new_value));
- uint8_t* raw_addr = reinterpret_cast<uint8_t*>(this) + field_offset.Int32Value();
- Atomic<uint32_t>* atomic_addr = reinterpret_cast<Atomic<uint32_t>*>(raw_addr);
-
- bool success = atomic_addr->CompareAndSetStrongRelease(old_ref, new_ref);
- return success;
-}
-
} // namespace mirror
} // namespace art
diff --git a/runtime/mirror/object.h b/runtime/mirror/object.h
index e19b524ef3..c7cffed69b 100644
--- a/runtime/mirror/object.h
+++ b/runtime/mirror/object.h
@@ -315,30 +315,20 @@ class MANAGED LOCKABLE Object {
template<bool kTransactionActive,
bool kCheckTransaction = true,
VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
+ ALWAYS_INLINE bool CasFieldObject(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order)
REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive,
bool kCheckTransaction = true,
VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakSequentiallyConsistentObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongSequentiallyConsistentObject(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongSequentiallyConsistentObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
+ ALWAYS_INLINE bool CasFieldObjectWithoutWriteBarrier(MemberOffset field_offset,
+ ObjPtr<Object> old_value,
+ ObjPtr<Object> new_value,
+ CASMode mode,
+ std::memory_order memory_order)
REQUIRES_SHARED(Locks::mutator_lock_);
template<bool kTransactionActive,
@@ -355,36 +345,6 @@ class MANAGED LOCKABLE Object {
ObjPtr<Object> ExchangeFieldObject(MemberOffset field_offset, ObjPtr<Object> new_value)
REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakRelaxedObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldWeakReleaseObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongRelaxedObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
- template<bool kTransactionActive,
- bool kCheckTransaction = true,
- VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
- bool CasFieldStrongReleaseObjectWithoutWriteBarrier(MemberOffset field_offset,
- ObjPtr<Object> old_value,
- ObjPtr<Object> new_value)
- REQUIRES_SHARED(Locks::mutator_lock_);
-
template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
HeapReference<Object>* GetFieldObjectReferenceAddr(MemberOffset field_offset)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/mirror/var_handle.cc b/runtime/mirror/var_handle.cc
index 4319c5df25..56c953b816 100644
--- a/runtime/mirror/var_handle.cc
+++ b/runtime/mirror/var_handle.cc
@@ -1021,15 +1021,17 @@ bool FieldAccessor<ObjPtr<Object>>::Dispatch(VarHandle::AccessMode access_mode,
ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
bool cas_result;
if (Runtime::Current()->IsActiveTransaction()) {
- cas_result = obj->CasFieldStrongSequentiallyConsistentObject<kTransactionActive>(
- field_offset,
- expected_value,
- desired_value);
+ cas_result = obj->CasFieldObject<kTransactionActive>(field_offset,
+ expected_value,
+ desired_value,
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
} else {
- cas_result = obj->CasFieldStrongSequentiallyConsistentObject<kTransactionInactive>(
- field_offset,
- expected_value,
- desired_value);
+ cas_result = obj->CasFieldObject<kTransactionInactive>(field_offset,
+ expected_value,
+ desired_value,
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
}
StoreResult(cas_result, result);
break;
@@ -1043,15 +1045,18 @@ bool FieldAccessor<ObjPtr<Object>>::Dispatch(VarHandle::AccessMode access_mode,
ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
bool cas_result;
if (Runtime::Current()->IsActiveTransaction()) {
- cas_result = obj->CasFieldWeakSequentiallyConsistentObject<kTransactionActive>(
- field_offset,
- expected_value,
- desired_value);
+ cas_result = obj->CasFieldObject<kTransactionActive>(field_offset,
+ expected_value,
+ desired_value,
+ CASMode::kWeak,
+ std::memory_order_seq_cst);
} else {
- cas_result = obj->CasFieldWeakSequentiallyConsistentObject<kTransactionInactive>(
+ cas_result = obj->CasFieldObject<kTransactionInactive>(
field_offset,
expected_value,
- desired_value);
+ desired_value,
+ CASMode::kWeak,
+ std::memory_order_seq_cst);
}
StoreResult(cas_result, result);
break;
@@ -1064,15 +1069,13 @@ bool FieldAccessor<ObjPtr<Object>>::Dispatch(VarHandle::AccessMode access_mode,
ObjPtr<Object> desired_value = ValueGetter<ObjPtr<Object>>::Get(getter);
ObjPtr<Object> witness_value;
if (Runtime::Current()->IsActiveTransaction()) {
- witness_value = obj->CompareAndExchangeFieldObject<kTransactionActive>(
- field_offset,
- expected_value,
- desired_value);
+ witness_value = obj->CompareAndExchangeFieldObject<kTransactionActive>(field_offset,
+ expected_value,
+ desired_value);
} else {
- witness_value = obj->CompareAndExchangeFieldObject<kTransactionInactive>(
- field_offset,
- expected_value,
- desired_value);
+ witness_value = obj->CompareAndExchangeFieldObject<kTransactionInactive>(field_offset,
+ expected_value,
+ desired_value);
}
StoreResult(witness_value, result);
break;
diff --git a/runtime/native/sun_misc_Unsafe.cc b/runtime/native/sun_misc_Unsafe.cc
index 0f474d3c9d..46444808d7 100644
--- a/runtime/native/sun_misc_Unsafe.cc
+++ b/runtime/native/sun_misc_Unsafe.cc
@@ -80,9 +80,11 @@ static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaOb
MemberOffset(offset),
field_addr);
}
- bool success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset),
- expectedValue,
- newValue);
+ bool success = obj->CasFieldObject<false>(MemberOffset(offset),
+ expectedValue,
+ newValue,
+ CASMode::kStrong,
+ std::memory_order_seq_cst);
return success ? JNI_TRUE : JNI_FALSE;
}
diff --git a/runtime/read_barrier-inl.h b/runtime/read_barrier-inl.h
index 5035ba077c..640fa7e393 100644
--- a/runtime/read_barrier-inl.h
+++ b/runtime/read_barrier-inl.h
@@ -64,8 +64,11 @@ inline MirrorType* ReadBarrier::Barrier(
// If kAlwaysUpdateField is true, update the field atomically. This may fail if mutator
// updates before us, but it's OK.
if (kAlwaysUpdateField && ref != old_ref) {
- obj->CasFieldStrongReleaseObjectWithoutWriteBarrier<false, false>(
- offset, old_ref, ref);
+ obj->CasFieldObjectWithoutWriteBarrier<false, false>(offset,
+ old_ref,
+ ref,
+ CASMode::kStrong,
+ std::memory_order_release);
}
}
AssertToSpaceInvariant(obj, offset, ref);
@@ -82,8 +85,11 @@ inline MirrorType* ReadBarrier::Barrier(
ref = reinterpret_cast<MirrorType*>(Mark(old_ref));
// Update the field atomically. This may fail if mutator updates before us, but it's ok.
if (ref != old_ref) {
- obj->CasFieldStrongReleaseObjectWithoutWriteBarrier<false, false>(
- offset, old_ref, ref);
+ obj->CasFieldObjectWithoutWriteBarrier<false, false>(offset,
+ old_ref,
+ ref,
+ CASMode::kStrong,
+ std::memory_order_release);
}
}
AssertToSpaceInvariant(obj, offset, ref);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 3c5569fe05..1a078d5fe6 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1579,7 +1579,7 @@ void Thread::FullSuspendCheck() {
VLOG(threads) << this << " self-suspending";
// Make thread appear suspended to other threads, release mutator_lock_.
// Transition to suspended and back to runnable, re-acquire share on mutator_lock_.
- ScopedThreadSuspension(this, kSuspended);
+ ScopedThreadSuspension(this, kSuspended); // NOLINT
VLOG(threads) << this << " self-reviving";
}
diff --git a/test/003-omnibus-opcodes/build b/test/003-omnibus-opcodes/build
index 4d3fb37d1d..c2e611259b 100644
--- a/test/003-omnibus-opcodes/build
+++ b/test/003-omnibus-opcodes/build
@@ -17,12 +17,20 @@
# Stop if something fails.
set -e
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-rm classes/UnresClass.class
-${JAVAC} -d classes `find src2 -name '*.java'`
+export ORIGINAL_JAVAC="$JAVAC"
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
-fi
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
+
+ $ORIGINAL_JAVAC "$@"
+ rm -f classes/UnresClass.class
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+./default-build "$@"
diff --git a/test/004-JniTest/build b/test/004-JniTest/build
index e563d734c2..a786b8bc62 100755
--- a/test/004-JniTest/build
+++ b/test/004-JniTest/build
@@ -23,16 +23,18 @@
# This enables the test to compile with vanilla RI javac and work on either ART or RI.
#
+# Stop on failure.
+set -e
+
export ORIGINAL_JAVAC="$JAVAC"
-# Delete CriticalNative.java, FastNative.java annotations after building the .class files.
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
$ORIGINAL_JAVAC "$@"
- local stat=$?
-
- [[ -d classes ]] && (find classes/dalvik -name '*.class' | xargs rm -rf)
-
- return $stat
+ # Delete CriticalNative.java, FastNative.java annotations after building the .class files.
+ find classes/dalvik -name '*.class' -exec rm {} \;
}
export -f javac_wrapper
@@ -40,28 +42,6 @@ export JAVAC=javac_wrapper
######################################################################
-# Use the original dx with no extra magic or pessimizing flags.
-# This ensures that any default optimizations that dx do would not break JNI.
-
-export ORIGINAL_DX="$DX"
-
-# Filter out --debug flag from dx.
-function dx_wrapper {
- local args=("$@")
- local args_filtered=()
- for i in "${args[@]}"; do
- case "$i" in
- --debug)
- ;;
- *)
- args_filtered+=("$i")
- ;;
- esac
- done
- "$ORIGINAL_DX" "${args_filtered[@]}"
-}
-
-export -f dx_wrapper
-export DX=dx_wrapper
-
+# Use release mode to check optimizations do not break JNI.
+export D8_FLAGS=--release
./default-build "$@"
diff --git a/test/004-ReferenceMap/build b/test/004-ReferenceMap/build
index 3bb63ca624..d928cd7daf 100644
--- a/test/004-ReferenceMap/build
+++ b/test/004-ReferenceMap/build
@@ -17,9 +17,26 @@
# Stop if something fails.
set -e
-# The test relies on DEX file produced by javac+dx so keep building with them for now
-# (see b/19467889)
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-${DX} -JXmx256m --debug --dex --output=classes.dex ${DX_FLAGS} classes
-zip $TEST_NAME.jar classes.dex
+# This test depends on the exact format of the DEX file. Since dx is deprecated,
+# the classes.dex file is packaged as a test input. It was created with:
+#
+# $ javac -g -Xlint:-options -source 1.7 -target 1.7 -d classes src/Main.java
+# $ dx --debug --dex --output=classes.dex classes
+
+# Wrapper function for javac which for this test does nothing as the
+# test uses a pre-built DEX file.
+function javac_wrapper {
+ # Nothing to compile, using dx generated classes.dex.
+ return 0
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+# Do not invoke D8 for this test.
+export D8=':'
+
+######################################################################
+
+jar -cf classes.jar classes.dex
+./default-build "$@"
diff --git a/test/004-ReferenceMap/classes.dex b/test/004-ReferenceMap/classes.dex
new file mode 100644
index 0000000000..993c077e43
--- /dev/null
+++ b/test/004-ReferenceMap/classes.dex
Binary files differ
diff --git a/test/004-StackWalk/build b/test/004-StackWalk/build
index 3bb63ca624..eeecbfcc40 100644
--- a/test/004-StackWalk/build
+++ b/test/004-StackWalk/build
@@ -17,9 +17,25 @@
# Stop if something fails.
set -e
-# The test relies on DEX file produced by javac+dx so keep building with them for now
-# (see b/19467889)
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-${DX} -JXmx256m --debug --dex --output=classes.dex ${DX_FLAGS} classes
-zip $TEST_NAME.jar classes.dex
+# This test depends on the exact format of the DEX file. Since dx is deprecated,
+# the classes.dex file is packaged as a test input. It was created with:
+#
+# $ javac -g -Xlint:-options -source 1.7 -target 1.7 -d classes src/Main.java
+# $ dx --debug --dex --output=classes.dex classes
+
+# Wrapper function for javac which for this test does nothing as the
+# test uses a pre-built DEX file.
+function javac_wrapper {
+ return 0
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+# Do not invoke D8 for this test.
+export D8=':'
+
+######################################################################
+
+jar -cf classes.jar classes.dex
+./default-build "$@"
diff --git a/test/004-StackWalk/classes.dex b/test/004-StackWalk/classes.dex
new file mode 100644
index 0000000000..ad452960c3
--- /dev/null
+++ b/test/004-StackWalk/classes.dex
Binary files differ
diff --git a/test/005-annotations/build b/test/005-annotations/build
index 8eb07a9bf5..5342eea4c4 100644
--- a/test/005-annotations/build
+++ b/test/005-annotations/build
@@ -17,18 +17,28 @@
# Stop if something fails.
set -e
-mkdir classes
+export ORIGINAL_JAVAC="$JAVAC"
-# android.test.anno.MissingAnnotation is available at compile time...
-${JAVAC} -d classes `find src -name '*.java'`
-# overwrite RenamedEnum
-${JAVAC} -d classes `find src2 -name '*.java'`
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
-# ...but not at run time.
-rm 'classes/android/test/anno/MissingAnnotation.class'
-rm 'classes/android/test/anno/ClassWithInnerAnnotationClass$MissingInnerAnnotationClass.class'
+ $ORIGINAL_JAVAC "$@"
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
-fi
+ # Classes available at compile time, but not at runtime.
+ rm -f classes/android/test/anno/MissingAnnotation.class
+ rm -f 'classes/android/test/anno/ClassWithInnerAnnotationClass$MissingInnerAnnotationClass.class'
+
+ # overwrite RenamedEnum in classes
+ if [ -f classes2/android/test/anno/RenamedEnumClass.java ] ; then
+ mv classes2/android/test/anno/RenamedEnumClass.java classes/android/test/anno/RenamedEnumClass.java
+ fi
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+./default-build "$@"
diff --git a/test/056-const-string-jumbo/build b/test/056-const-string-jumbo/build
index 47641d5891..c1d711b436 100644
--- a/test/056-const-string-jumbo/build
+++ b/test/056-const-string-jumbo/build
@@ -39,10 +39,4 @@ function writeFile(name, start, end) {
printf("}\n") > fileName;
}'
-mkdir classes
-${JAVAC} -d classes src/*.java
-
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx500m --debug --dex --no-optimize --positions=none --no-locals --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
-fi
+./default-build "$@"
diff --git a/test/442-checker-constant-folding/build b/test/066-mismatched-super/build
index 42b99ad9f8..c1c9ed304e 100755..100644
--- a/test/442-checker-constant-folding/build
+++ b/test/066-mismatched-super/build
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright 2017 The Android Open Source Project
+# Copyright 2018 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.
@@ -14,7 +14,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# See b/65168732
-export DX=$ANDROID_HOST_OUT/bin/dx
-
-./default-build "$@"
+DESUGAR=false ./default-build "$@"
diff --git a/test/089-many-methods/build b/test/089-many-methods/build
index ff77c60f64..5b4cda87c1 100644
--- a/test/089-many-methods/build
+++ b/test/089-many-methods/build
@@ -43,8 +43,9 @@ function writeFileMethod(name) {
printf("}\n") > fileName;
}'
-# The test relies on the error message produced by dx, not jack, so keep building with dx for now
-# (b/19467889).
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-${DX} -JXmx1024m --dex --no-optimize classes
+# Force DEX generation so test also passes with --jvm.
+export NEED_DEX=true
+
+# Specify old API level as d8 automagically produces a multidex file
+# when the API level is above 20. Failing the build here is deliberate.
+./default-build --api-level 20 "$@"
diff --git a/test/089-many-methods/check b/test/089-many-methods/check
index 65b71397b8..1f71e8e0a0 100755
--- a/test/089-many-methods/check
+++ b/test/089-many-methods/check
@@ -14,7 +14,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Strip build error debug messages, as they are environment-specific.
-sed -e '/^Failed to build/d' -e '/^Non-canonical tmpdir/d' -e '/^Args:/d' -e '/^Max filename/d' -e '/^Max pathlength/d' "$2" > "$2.tmp"
-
-diff --strip-trailing-cr -q "$1" "$2.tmp" >/dev/null \ No newline at end of file
+grep Error "$2" > "$2.tmp"
+diff --strip-trailing-cr -q "$1" "$2.tmp" >/dev/null
diff --git a/test/089-many-methods/expected.txt b/test/089-many-methods/expected.txt
index 786df7c76d..bb6ba3c7bc 100644
--- a/test/089-many-methods/expected.txt
+++ b/test/089-many-methods/expected.txt
@@ -1,6 +1 @@
-
-trouble writing output: Too many field references to fit in one dex file: 131000; max is 65536.
-You may try using multi-dex. If multi-dex is enabled then the list of classes for the main dex list is too large.
-References by package:
-131000 default
-build exit status: 2
+Error: Cannot fit requested classes in a single dex file (# fields: 131000 > 65536)
diff --git a/test/091-override-package-private-method/build b/test/091-override-package-private-method/build
index e5fa6693a3..8257d92156 100755
--- a/test/091-override-package-private-method/build
+++ b/test/091-override-package-private-method/build
@@ -17,15 +17,20 @@
# Stop if something fails.
set -e
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
+export ORIGINAL_JAVAC="$JAVAC"
-mkdir classes-ex
-mv classes/OverridePackagePrivateMethodSuper.class classes-ex
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
+ $ORIGINAL_JAVAC "$@"
+ mkdir -p classes-ex
+ mv classes/OverridePackagePrivateMethodSuper.class classes-ex
+}
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes-ex
- zip ${TEST_NAME}-ex.jar classes.dex
-fi
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+./default-build "$@"
diff --git a/test/111-unresolvable-exception/build b/test/111-unresolvable-exception/build
index f24c5b2004..1c275aa2fe 100644
--- a/test/111-unresolvable-exception/build
+++ b/test/111-unresolvable-exception/build
@@ -17,11 +17,22 @@
# Stop if something fails.
set -e
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-rm classes/TestException.class
-
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
-fi
+export ORIGINAL_JAVAC="$JAVAC"
+
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
+
+ $ORIGINAL_JAVAC "$@"
+
+ # Remove class available at compile time but not at run time.
+ rm classes/TestException.class
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+./default-build "$@"
diff --git a/test/113-multidex/build b/test/113-multidex/build
deleted file mode 100644
index 4ad7cb9134..0000000000
--- a/test/113-multidex/build
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2014 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.
-
-# Stop if something fails.
-set -e
-
-# All except Main
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-rm classes/Main.class
-
-# Only Main
-mkdir classes2
-${JAVAC} -d classes2 `find src -name '*.java'`
-rm classes2/Second.class classes2/FillerA.class classes2/FillerB.class classes2/Inf*.class
-
-if [ ${NEED_DEX} = "true" ]; then
- # All except Main
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
-
- # Only Main
- ${DX} -JXmx256m --debug --dex --output=classes2.dex classes2
- zip $TEST_NAME.jar classes.dex classes2.dex
-fi
diff --git a/test/113-multidex/src/Main.java b/test/113-multidex/src-multidex/Main.java
index 1c74220525..1c74220525 100644
--- a/test/113-multidex/src/Main.java
+++ b/test/113-multidex/src-multidex/Main.java
diff --git a/test/124-missing-classes/build b/test/124-missing-classes/build
index b13aa6e851..ec4ec84e09 100644
--- a/test/124-missing-classes/build
+++ b/test/124-missing-classes/build
@@ -17,16 +17,24 @@
# Stop if something fails.
set -e
-mkdir classes
+export ORIGINAL_JAVAC="$JAVAC"
-# Some classes are available at compile time...
-${JAVAC} -d classes `find src -name '*.java'`
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
-# ...but not at run time.
-rm 'classes/MissingClass.class'
-rm 'classes/Main$MissingInnerClass.class'
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
-fi
+ # Some classes are available at compile time...
+ $ORIGINAL_JAVAC "$@"
+
+ # ...but not at run time.
+ rm 'classes/MissingClass.class' 'classes/Main$MissingInnerClass.class'
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+./default-build "$@"
diff --git a/test/126-miranda-multidex/build b/test/126-miranda-multidex/build
index b4bb88d644..7b44863fa9 100644
--- a/test/126-miranda-multidex/build
+++ b/test/126-miranda-multidex/build
@@ -17,21 +17,30 @@
# Stop if something fails.
set -e
-# All except MirandaInterface
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-rm classes/MirandaInterface.class
+export ORIGINAL_JAVAC="$JAVAC"
-# Only MirandaInterface
-mkdir classes2
-${JAVAC} -d classes2 `find src -name '*.java'`
-rm classes2/Main.class classes2/MirandaAbstract.class classes2/MirandaClass*.class classes2/MirandaInterface2*.class
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
-if [ ${NEED_DEX} = "true" ]; then
- # All except Main
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
+ if [[ "$*" != *"classes2"* ]]; then
+ # First invocation: compile src/ files.
+ $ORIGINAL_JAVAC "$@"
+ else
+ # Second invocation: move MirandaInterface.class for placement in
+ # a secondary dex file. There are no other source files for the
+ # secondary DEX so no compilation required.
+ mv classes/MirandaInterface.class classes2
+ fi
+ return $?
+}
- # Only Main
- ${DX} -JXmx256m --debug --dex --output=classes2.dex classes2
- zip $TEST_NAME.jar classes.dex classes2.dex
-fi
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+# Signal to default-build that this is a multidex test.
+mkdir src-multidex
+./default-build "$@"
diff --git a/test/127-checker-secondarydex/build b/test/127-checker-secondarydex/build
index c23b7613b9..3135681eec 100755
--- a/test/127-checker-secondarydex/build
+++ b/test/127-checker-secondarydex/build
@@ -17,15 +17,22 @@
# Stop if something fails.
set -e
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-
-mkdir classes-ex
-mv classes/Super.class classes-ex
-
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes-ex
- zip ${TEST_NAME}-ex.jar classes.dex
-fi
+export ORIGINAL_JAVAC="$JAVAC"
+
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
+
+ $ORIGINAL_JAVAC "$@"
+
+ mkdir classes-ex
+ mv classes/Super.class classes-ex
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+./default-build "$@"
diff --git a/test/138-duplicate-classes-check2/build b/test/138-duplicate-classes-check2/build
index 3ff15aae38..4ab7320699 100755
--- a/test/138-duplicate-classes-check2/build
+++ b/test/138-duplicate-classes-check2/build
@@ -17,16 +17,22 @@
# Stop if something fails.
set -e
-mkdir classes
-${JAVAC} -d classes `find src -name '*.java'`
-
-mkdir classes-ex
-${JAVAC} -d classes-ex `find src-ex -name '*.java'`
-rm classes-ex/A.class
-
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes
- zip ${TEST_NAME}.jar classes.dex
- ${DX} -JXmx256m --debug --dex --output=classes.dex classes-ex
- zip ${TEST_NAME}-ex.jar classes.dex
-fi
+export ORIGINAL_JAVAC="$JAVAC"
+
+# Wrapper function for javac which invokes the compiler and applies
+# additional setup steps for the test.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
+
+ $ORIGINAL_JAVAC "$@"
+
+ # Remove one A.class from classes-ex
+ rm -f classes-ex/A.class
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+./default-build "$@"
diff --git a/test/1948-obsolete-const-method-handle/build b/test/1948-obsolete-const-method-handle/build
index ac0dcd97b8..d0e7a8c0d8 100644
--- a/test/1948-obsolete-const-method-handle/build
+++ b/test/1948-obsolete-const-method-handle/build
@@ -20,6 +20,4 @@ set -e
mkdir classes
./util-src/build-classes $PWD/classes
-${DX} --dex --min-sdk-version=28 --output=classes.dex classes
-
-zip $TEST_NAME.jar classes.dex
+./default-build --api-level 28 "$@"
diff --git a/test/303-verification-stress/build b/test/303-verification-stress/build
index ba79541478..87a4a851d7 100644
--- a/test/303-verification-stress/build
+++ b/test/303-verification-stress/build
@@ -21,11 +21,4 @@ set -e
gcc -Wall -Werror -o classes-gen classes-gen.c
./classes-gen
-mkdir classes
-${JAVAC} -d classes src/*.java
-
-# dx needs more memory for that test so do not pass Xmx option here.
-if [ ${NEED_DEX} = "true" ]; then
- ${DX} --debug --dex --output=classes.dex classes
- zip $TEST_NAME.jar classes.dex
-fi
+./default-build "$@"
diff --git a/test/638-no-line-number/build b/test/638-no-line-number/build
index 7eaf50e938..9cd19554bc 100644
--- a/test/638-no-line-number/build
+++ b/test/638-no-line-number/build
@@ -17,9 +17,6 @@
# Stop if something fails.
set -e
-mkdir classes
# Only keep the source name, to make sure we do remove it in the stack trace
# when there is no line number mapping.
-${JAVAC} -g:source -source 7 -target 7 -d classes `find src -name '*.java'`
-${DX} --dex --output=classes.dex classes
-zip $TEST_NAME.jar classes.dex
+JAVAC_ARGS="$JAVAC_ARGS -g:source" ./default-build "$@"
diff --git a/test/638-no-line-number/expected.txt b/test/638-no-line-number/expected.txt
index ffde15312b..4b351f4bf9 100644
--- a/test/638-no-line-number/expected.txt
+++ b/test/638-no-line-number/expected.txt
@@ -2,4 +2,4 @@ java.lang.Error
at Main.main(Unknown Source:2)
java.lang.NullPointerException: throw with null exception
at Main.doThrow(Unknown Source:0)
- at Main.main(Unknown Source:9)
+ at Main.main(Unknown Source:16)
diff --git a/test/712-varhandle-invocations/build b/test/712-varhandle-invocations/build
index 253765be91..9a6e96e18b 100755
--- a/test/712-varhandle-invocations/build
+++ b/test/712-varhandle-invocations/build
@@ -32,8 +32,4 @@ MANUAL_TESTS=$(cd "${MANUAL_SRC}" && find . -name 'Var*Tests.java' | sed -e 's@.
# Generate tests and Main that covers both the generated tests and manual tests
python3 ./util-src/generate_java.py "${GENERATED_SRC}" ${MANUAL_TESTS}
-# Desugar is not happy with our Java 9 byte code, it shouldn't be necessary here anyway.
-export USE_DESUGAR=false
-
-# Invoke default build with increased heap size for dx
-./default-build "$@" --experimental var-handles --dx-vm-option -JXmx384m
+./default-build "$@" --experimental var-handles
diff --git a/test/715-clinit-implicit-parameter-annotations/build b/test/715-clinit-implicit-parameter-annotations/build
index 4753c8c7dc..2b5f92cc88 100644
--- a/test/715-clinit-implicit-parameter-annotations/build
+++ b/test/715-clinit-implicit-parameter-annotations/build
@@ -17,8 +17,4 @@
# Make us exit on a failure
set -e
-# Always use D8 as DX does not support propagating parameter name and
-# access_flag information.
-export USE_D8=true
-
./default-build "$@" --experimental parameter-annotations
diff --git a/test/022-interface/build b/test/804-class-extends-itself/build
index ab1c822ebf..71cb3cacdc 100644
--- a/test/022-interface/build
+++ b/test/804-class-extends-itself/build
@@ -1,12 +1,12 @@
#!/bin/bash
#
-# Copyright (C) 2012 The Android Open Source Project
+# Copyright 2018 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
+# 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,
@@ -14,9 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Stop if something fails.
-set -e
-
-${DX} --debug --dex --output=classes.dex classes
-
-zip $TEST_NAME.jar classes.dex
+# Use old API level to create DEX file with 035 version. Stricter
+# checking introduced with DEX file version 37 rejects class
+# otherwise (see DexFile::kClassDefinitionOrderEnforcedVersion).
+./default-build "$@" --api-level 13
diff --git a/test/952-invoke-custom/build b/test/952-invoke-custom/build
index 53d8228808..a70fc20c05 100755
--- a/test/952-invoke-custom/build
+++ b/test/952-invoke-custom/build
@@ -14,34 +14,60 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# make us exit on a failure
+# Stop on failure.
set -e
-ASM_JAR="${ANDROID_BUILD_TOP}/prebuilts/misc/common/asm/asm-6.0.jar"
-INTERMEDIATE_CLASSES=classes-intermediate
-CLASSES=classes
+export ASM_JAR="${ANDROID_BUILD_TOP}/prebuilts/misc/common/asm/asm-6.0.jar"
-# Create directory for intermediate classes
-rm -rf "${INTERMEDIATE_CLASSES}"
-mkdir "${INTERMEDIATE_CLASSES}"
+export ORIGINAL_JAVAC="$JAVAC"
-# Generate intermediate classes that will allow transform to be applied to test classes
-JAVAC_ARGS="${JAVAC_ARGS} -source 1.8 -target 1.8 -cp ${ASM_JAR}"
-${JAVAC:-javac} ${JAVAC_ARGS} -d ${INTERMEDIATE_CLASSES} $(find src -name '*.java')
+# Wrapper function for javac which invokes the compiler and applies
+# transforms to class files after compilation.
+function javac_wrapper {
+ set -e # Stop on error - the caller script may not have this set.
-# Create directory for transformed classes
-rm -rf "${CLASSES}"
-mkdir "${CLASSES}"
+ # Update arguments to add transformer and ASM to the compiler classpath.
+ local args=()
+ local classpath="./transformer.jar:$ASM_JAR"
+ while [ $# -ne 0 ] ; do
+ case $1 in
+ -cp|-classpath|--class-path)
+ shift
+ shift
+ args+=(-cp $classpath)
+ ;;
+ *)
+ args+=("$1")
+ shift
+ ;;
+ esac
+ done
-# Run transform
-for class in ${INTERMEDIATE_CLASSES}/*.class ; do
- transformed_class=${CLASSES}/$(basename ${class})
- ${JAVA:-java} -cp "${ASM_JAR}:${INTERMEDIATE_CLASSES}" transformer.IndyTransformer ${class} ${transformed_class}
-done
+ # Compile.
+ $ORIGINAL_JAVAC "${args[@]}"
-# Create DEX
-DX_FLAGS="${DX_FLAGS} --min-sdk-version=26 --debug --dump-width=1000"
-${DX} -JXmx256m --dex ${DX_FLAGS} --output=classes.dex ${CLASSES}
+ # Move original classes to intermediate location.
+ mv classes intermediate-classes
+ mkdir classes
-# Zip DEX to file name expected by test runner
-zip ${TEST_NAME:-classes-dex}.jar classes.dex
+ # Transform intermediate classes.
+ local transformer_args="-cp ${ASM_JAR}:transformer.jar transformer.IndyTransformer"
+ for class in intermediate-classes/*.class ; do
+ local transformed_class=classes/$(basename ${class})
+ ${JAVA:-java} ${transformer_args} $PWD/${class} ${transformed_class}
+ done
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+# Build the transformer to apply to compiled classes.
+mkdir classes
+${ORIGINAL_JAVAC:-javac} ${JAVAC_ARGS} -cp "${ASM_JAR}" -d classes $(find util-src -name '*.java')
+jar -cf transformer.jar -C classes transformer/ -C classes annotations/
+rm -rf classes
+
+# Use API level 28 for invoke-custom bytecode support.
+DESUGAR=false ./default-build "$@" --api-level 28
diff --git a/test/952-invoke-custom/src/annotations/BootstrapMethod.java b/test/952-invoke-custom/util-src/annotations/BootstrapMethod.java
index c16783007f..c16783007f 100644
--- a/test/952-invoke-custom/src/annotations/BootstrapMethod.java
+++ b/test/952-invoke-custom/util-src/annotations/BootstrapMethod.java
diff --git a/test/952-invoke-custom/src/annotations/CalledByIndy.java b/test/952-invoke-custom/util-src/annotations/CalledByIndy.java
index c4d13a2af4..c4d13a2af4 100644
--- a/test/952-invoke-custom/src/annotations/CalledByIndy.java
+++ b/test/952-invoke-custom/util-src/annotations/CalledByIndy.java
diff --git a/test/952-invoke-custom/src/annotations/Constant.java b/test/952-invoke-custom/util-src/annotations/Constant.java
index 7966a524ba..7966a524ba 100644
--- a/test/952-invoke-custom/src/annotations/Constant.java
+++ b/test/952-invoke-custom/util-src/annotations/Constant.java
diff --git a/test/952-invoke-custom/src/transformer/IndyTransformer.java b/test/952-invoke-custom/util-src/transformer/IndyTransformer.java
index 45cb4760c9..d21dbbeabc 100644
--- a/test/952-invoke-custom/src/transformer/IndyTransformer.java
+++ b/test/952-invoke-custom/util-src/transformer/IndyTransformer.java
@@ -69,7 +69,7 @@ import org.objectweb.asm.Type;
*
* <p>In the example above, this results in add() being replaced by invocations of magicAdd().
*/
-class IndyTransformer {
+public class IndyTransformer {
static class BootstrapBuilder extends ClassVisitor {
@@ -164,10 +164,9 @@ class IndyTransformer {
}
private static void transform(Path inputClassPath, Path outputClassPath) throws Throwable {
+ URL url = inputClassPath.getParent().toUri().toURL();
URLClassLoader classLoader =
- new URLClassLoader(
- new URL[] {inputClassPath.toUri().toURL()},
- ClassLoader.getSystemClassLoader());
+ new URLClassLoader(new URL[] {url}, ClassLoader.getSystemClassLoader());
String inputClassName = inputClassPath.getFileName().toString().replace(".class", "");
Class<?> inputClass = classLoader.loadClass(inputClassName);
Map<String, CalledByIndy> callsiteMap = new HashMap<>();
diff --git a/test/961-default-iface-resolution-gen/build b/test/961-default-iface-resolution-gen/build
index d719a9ffe9..1d245894de 100755
--- a/test/961-default-iface-resolution-gen/build
+++ b/test/961-default-iface-resolution-gen/build
@@ -22,5 +22,4 @@ mkdir -p ./src
# Generate the smali files and expected.txt or fail
./util-src/generate_java.py ./src ./expected.txt
-# dx runs out of memory with default 256M, give it more memory.
-./default-build "$@" --experimental default-methods --dx-vm-option -JXmx1024M
+./default-build "$@" --experimental default-methods
diff --git a/test/964-default-iface-init-gen/build b/test/964-default-iface-init-gen/build
index e504690043..1d245894de 100755
--- a/test/964-default-iface-init-gen/build
+++ b/test/964-default-iface-init-gen/build
@@ -22,5 +22,4 @@ mkdir -p ./src
# Generate the smali files and expected.txt or fail
./util-src/generate_java.py ./src ./expected.txt
-# dx runs out of memory with just 256m, so increase it.
-./default-build "$@" --experimental default-methods --dx-vm-option -JXmx1024M
+./default-build "$@" --experimental default-methods
diff --git a/test/979-const-method-handle/build b/test/979-const-method-handle/build
index 67fc2a6339..4d22cb608b 100755
--- a/test/979-const-method-handle/build
+++ b/test/979-const-method-handle/build
@@ -17,34 +17,41 @@
# make us exit on a failure
set -e
-ASM_JAR="${ANDROID_BUILD_TOP}/prebuilts/misc/common/asm/asm-6.0.jar"
-INTERMEDIATE_CLASSES=classes-intermediate
-TRANSFORMER_CLASSES=classes-transformer
-CLASSES=classes
-
-# Create directories for classes
-for class_dir in "${INTERMEDIATE_CLASSES}" "${TRANSFORMER_CLASSES}" "${CLASSES}"; do
- rm -rf "${class_dir}"
- mkdir "${class_dir}"
-done
-
-# Build transformer
-${JAVAC:-javac} ${JAVAC_ARGS} -cp "${ASM_JAR}" -d ${TRANSFORMER_CLASSES} $(find util-src -name '*.java')
-
-# Generate intermediate classes that will allow transform to be applied to test classes
-JAVAC_ARGS="${JAVAC_ARGS} -source 1.8 -target 1.8"
-${JAVAC:-javac} ${JAVAC_ARGS} -cp ${TRANSFORMER_CLASSES} -d ${INTERMEDIATE_CLASSES} $(find src -name '*.java')
-
-# Run transform
-for class in ${INTERMEDIATE_CLASSES}/*.class ; do
- transformed_class=${CLASSES}/$(basename ${class})
- ${JAVA:-java} -cp "${ASM_JAR}:${TRANSFORMER_CLASSES}" \
- transformer.ConstantTransformer ${class} ${transformed_class}
-done
-
-# Create DEX
-DX_FLAGS="${DX_FLAGS} --min-sdk-version=28 --debug --dump-width=1000"
-${DX} -JXmx256m --dex ${DX_FLAGS} --output=classes.dex ${CLASSES} ${TRANSFORMER_CLASSES}
-
-# Zip DEX to file name expected by test runner
-zip ${TEST_NAME:-classes-dex}.jar classes.dex
+export ASM_JAR="${ANDROID_BUILD_TOP}/prebuilts/misc/common/asm/asm-6.0.jar"
+
+export ORIGINAL_JAVAC="$JAVAC"
+
+function javac_wrapper {
+ set -e
+
+ # Add annotation src files to our compiler inputs.
+ local asrcs=util-src/annotations/*.java
+
+ # Compile.
+ $ORIGINAL_JAVAC "$@" $asrcs
+
+ # Move original classes to intermediate location.
+ mv classes intermediate-classes
+ mkdir classes
+
+ # Transform intermediate classes.
+ local transformer_args="-cp ${ASM_JAR}:$PWD/transformer.jar transformer.ConstantTransformer"
+ for class in intermediate-classes/*.class ; do
+ local transformed_class=classes/$(basename ${class})
+ ${JAVA:-java} ${transformer_args} ${class} ${transformed_class}
+ done
+}
+
+export -f javac_wrapper
+export JAVAC=javac_wrapper
+
+######################################################################
+
+# Build the transformer to apply to compiled classes.
+mkdir classes
+${ORIGINAL_JAVAC:-javac} ${JAVAC_ARGS} -cp "${ASM_JAR}" -d classes $(find util-src -name '*.java')
+jar -cf transformer.jar -C classes transformer/ -C classes annotations/
+rm -rf classes
+
+# Use API level 28 for DEX file support constant method handles.
+./default-build "$@" --api-level 28
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index ad292fd0a7..53d4c372c4 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -19,13 +19,11 @@ include art/build/Android.common_test.mk
# Dependencies for actually running a run-test.
TEST_ART_RUN_TEST_DEPENDENCIES := \
- $(HOST_OUT_EXECUTABLES)/dx \
$(HOST_OUT_EXECUTABLES)/d8 \
$(HOST_OUT_EXECUTABLES)/d8-compat-dx \
$(HOST_OUT_EXECUTABLES)/hiddenapi \
$(HOST_OUT_EXECUTABLES)/jasmin \
- $(HOST_OUT_EXECUTABLES)/smali \
- $(HOST_OUT_JAVA_LIBRARIES)/desugar.jar
+ $(HOST_OUT_EXECUTABLES)/smali
# We need dex2oat and dalvikvm on the target as well as the core images (all images as we sync
# only once).
@@ -97,7 +95,7 @@ endif
# Host executables.
host_prereq_rules := $(ART_TEST_HOST_RUN_TEST_DEPENDENCIES)
-# Required for dx, jasmin, smali.
+# Required for jasmin and smali.
host_prereq_rules += $(TEST_ART_RUN_TEST_DEPENDENCIES)
# Sync test files to the target, depends upon all things that must be pushed
diff --git a/test/etc/default-build b/test/etc/default-build
index 39f1a251c7..073ae2c796 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -17,9 +17,14 @@
# Stop if something fails.
set -e
+function fail() {
+ echo "$*" >&2
+ exit 1
+}
+
if [[ $# -le 0 ]]; then
echo 'Error:' '$0 should have the parameters from the "build" script forwarded to it' >&2
- echo 'Error: An example of how do it correctly is ./default-build "$@"'
+ fail 'Error: An example of how do it correctly is ./default-build "$@"'
exit 1
fi
@@ -98,7 +103,7 @@ if [ -z "${USE_HIDDENAPI}" ]; then
USE_HIDDENAPI=true
fi
-# DESUGAR=false run-test... will disable desugar.
+# DESUGAR=false run-test... will disable desugaring.
if [[ "$DESUGAR" == false ]]; then
USE_DESUGAR=false
fi
@@ -109,45 +114,25 @@ ZIP_COMPRESSION_METHOD="deflate"
WITH_ZIP_ALIGN=false
ZIP_ALIGN_BYTES="-1"
-DX_FLAGS="--min-sdk-version=26"
-DX_VM_FLAGS=""
-EXPERIMENTAL=""
-
BUILD_MODE="target"
DEV_MODE="no"
-# The key for default arguments if no experimental things are enabled.
DEFAULT_EXPERIMENT="no-experiment"
+# The key for default arguments if no experimental things are enabled.
+EXPERIMENTAL=$DEFAULT_EXPERIMENT
+
# Setup experimental API level mappings in a bash associative array.
declare -A EXPERIMENTAL_API_LEVEL
+EXPERIMENTAL_API_LEVEL[${DEFAULT_EXPERIMENT}]="26"
EXPERIMENTAL_API_LEVEL["default-methods"]="24"
EXPERIMENTAL_API_LEVEL["parameter-annotations"]="25"
EXPERIMENTAL_API_LEVEL["agents"]="26"
EXPERIMENTAL_API_LEVEL["method-handles"]="26"
EXPERIMENTAL_API_LEVEL["var-handles"]="28"
-declare -A JAVAC_EXPERIMENTAL_ARGS
-JAVAC_EXPERIMENTAL_ARGS["default-methods"]="-source 1.8 -target 1.8"
-JAVAC_EXPERIMENTAL_ARGS["lambdas"]="-source 1.8 -target 1.8"
-JAVAC_EXPERIMENTAL_ARGS["method-handles"]="-source 1.8 -target 1.8"
-JAVAC_EXPERIMENTAL_ARGS["parameter-annotations"]="-source 1.8 -target 1.8"
-JAVAC_EXPERIMENTAL_ARGS["var-handles"]="-source 1.8 -target 1.8"
-JAVAC_EXPERIMENTAL_ARGS[${DEFAULT_EXPERIMENT}]="-source 1.8 -target 1.8"
-JAVAC_EXPERIMENTAL_ARGS["agents"]="-source 1.8 -target 1.8"
-
while true; do
- if [ "x$1" = "x--dx-option" ]; then
- shift
- option="$1"
- DX_FLAGS="${DX_FLAGS} $option"
- shift
- elif [ "x$1" = "x--dx-vm-option" ]; then
- shift
- option="$1"
- DX_VM_FLAGS="${DX_VM_FLAGS} $option"
- shift
- elif [ "x$1" = "x--no-src" ]; then
+ if [ "x$1" = "x--no-src" ]; then
HAS_SRC=false
shift
elif [ "x$1" = "x--no-src2" ]; then
@@ -168,11 +153,14 @@ while true; do
elif [ "x$1" = "x--no-jasmin" ]; then
HAS_JASMIN=false
shift
+ elif [ "x$1" = "x--api-level" ]; then
+ shift
+ EXPERIMENTAL_API_LEVEL[${EXPERIMENTAL}]=$1
+ shift
elif [ "x$1" = "x--experimental" ]; then
shift
# We have a specific experimental configuration so don't use the default.
- DEFAULT_EXPERIMENT=""
- EXPERIMENTAL="${EXPERIMENTAL} $1"
+ EXPERIMENTAL="$1"
shift
elif [ "x$1" = "x--zip-compression-method" ]; then
# Allow using different zip compression method, e.g. 'store'
@@ -198,30 +186,25 @@ while true; do
DEV_MODE="yes"
shift
elif expr "x$1" : "x--" >/dev/null 2>&1; then
- echo "unknown $0 option: $1" 1>&2
- exit 1
+ fail "unknown $0 option: $1"
else
break
fi
done
if [[ $BUILD_MODE == jvm ]]; then
- # Does not need desugar on jvm because it supports the latest functionality.
+ # Does not need desugaring on jvm because it supports the latest functionality.
USE_DESUGAR=false
# Do not attempt to build src-art directories on jvm, it would fail without libcore.
HAS_SRC_ART=false
fi
-# Add args from the experimental mappings.
-for experiment in ${EXPERIMENTAL} ${DEFAULT_EXPERIMENT}; do
- JAVAC_ARGS="${JAVAC_ARGS} ${JAVAC_EXPERIMENTAL_ARGS[${experiment}]}"
-done
+# Set API level for smali and d8.
+API_LEVEL="${EXPERIMENTAL_API_LEVEL[${EXPERIMENTAL}]}"
-for experiment in ${EXPERIMENTAL}; do
- SMALI_ARGS="${SMALI_ARGS} --api ${EXPERIMENTAL_API_LEVEL[${experiment}]}"
- DX_FLAGS="${DX_FLAGS} --min-sdk-version=${EXPERIMENTAL_API_LEVEL[${experiment}]}"
- D8_FLAGS="--min-api ${EXPERIMENTAL_API_LEVEL[${experiment}]}"
-done
+# Add API level arguments to smali and dx
+SMALI_ARGS="${SMALI_ARGS} --api $API_LEVEL"
+D8_FLAGS="${D8_FLAGS} --min-api $API_LEVEL"
#########################################
@@ -258,16 +241,6 @@ function make_jasmin() {
fi
}
-function desugar() {
- local desugar_args="--mode=$BUILD_MODE"
-
- if [[ $DEV_MODE == yes ]]; then
- desugar_args="$desugar_args --show-commands"
- fi
-
- "$DESUGAR" --core-only $desugar_args "$@"
-}
-
# Like regular javac but may include libcore on the bootclasspath.
function javac_with_bootclasspath {
local helper_args="--mode=$BUILD_MODE"
@@ -280,39 +253,34 @@ function javac_with_bootclasspath {
"$ANDROID_BUILD_TOP/art/tools/javac-helper.sh" --core-only $helper_args ${JAVAC_ARGS} "$@"
}
-# Make a "dex" file given a directory of classes in $1.
-# Also calls desugar on the classes first to convert lambdas.
+# Make a "dex" file given a directory of classes in $1. This will be
+# packaged in a jar file.
function make_dex() {
local name="$1"
-
- local dx_input
- if [[ "$USE_DESUGAR" != "true" ]]; then
- # Use d8 with --no-desugaring for the 3 tests that opt out of desugaring (b/110150973).
- local d8_inputs=$(find classes -name '*.class' -type f)
- ${D8} ${D8_FLAGS} --debug --no-desugaring --output ${name}.jar $d8_inputs && \
- jar -xf ${name}.jar ${name}.dex && \
- rm ${name}.jar
- return $?
+ local d8_inputs=$(find $name -name '*.class' -type f)
+ local d8_output=${name}.jar
+ local dex_output=${name}.dex
+ local d8_local_flags=""
+ if [[ "$USE_DESUGAR" = "true" ]]; then
+ local boot_class_path_list=$($ANDROID_BUILD_TOP/art/tools/bootjars.sh --$BUILD_MODE --core --path)
+ for boot_class_path_element in $boot_class_path_list; do
+ d8_local_flags="$d8_local_flags --classpath $boot_class_path_element"
+ done
+ else
+ d8_local_flags="$d8_local_flags --no-desugaring"
fi
-
- # Make a jar first so desugar doesn't need every .class file individually.
- jar cf "$name.before-desugar.jar" -C "$name" .
-
- # Make desugared JAR.
- dx_input="${name}.desugar.jar"
- desugar --input "$name.before-desugar.jar" --output "$dx_input"
-
- local dexer="${DX}"
- if [[ "${USE_D8}" != "false" ]]; then
- dexer="${ANDROID_HOST_OUT}/bin/d8-compat-dx"
+ if [ "$DEV_MODE" = "yes" ]; then
+ echo ${D8} ${D8_FLAGS} $d8_local_flags --output $d8_output $d8_inputs
fi
+ ${D8} ${D8_FLAGS} $d8_local_flags --output $d8_output $d8_inputs
- # Make dex file from desugared JAR.
- local dexer_flags="${DX_FLAGS} --debug --dex"
- if [ $DEV_MODE = "yes" ]; then
- echo ${dexer} -JXmx256m ${DX_VM_FLAGS} $dexer_flags --output=${name}.dex "${dx_input}"
+ # D8 outputs to JAR files today rather than DEX files as DX used
+ # to. To compensate, we extract the DEX from d8's output to meet the
+ # expectations of make_dex callers.
+ if [ "$DEV_MODE" = "yes" ]; then
+ echo unzip -p $d8_output classes.dex \> $dex_output
fi
- ${dexer} -JXmx256m ${DX_VM_FLAGS} $dexer_flags --output=${name}.dex "${dx_input}"
+ unzip -p $d8_output classes.dex > $dex_output
}
# Merge all the dex files in $1..$N into $1. Skip non-existing files, but at least 1 file must exist.
@@ -342,11 +310,10 @@ function make_dexmerge() {
# We assume the dexer did all the API level checks and just merge away.
mkdir d8_merge_out
- ${DXMERGER} --min-api 1000 --output ./d8_merge_out "${dex_files_to_merge[@]}"
+ ${DEXMERGER} --min-api 1000 --output ./d8_merge_out "${dex_files_to_merge[@]}"
if [[ -e "./d8_merge_out/classes2.dex" ]]; then
- echo "Cannot merge all dex files into a single dex"
- exit 1
+ fail "Cannot merge all dex files into a single dex"
fi
mv ./d8_merge_out/classes.dex "$dst_file";
@@ -426,7 +393,9 @@ else
javac_with_bootclasspath -classpath classes -d classes `find src2 -name '*.java'`
fi
- if [[ "${HAS_SRC}" == "true" || "${HAS_SRC2}" == "true" || "${HAS_SRC_ART}" == "true" ]]; then
+ # If the classes directory is not-empty, package classes in a DEX file. NB some
+ # tests provide classes rather than java files.
+ if [ "$(ls -A classes)" ]; then
if [ ${NEED_DEX} = "true" ]; then
make_dex classes
fi
@@ -450,8 +419,7 @@ if [ "${HAS_SMALI}" = "true" -a ${NEED_DEX} = "true" ]; then
# Compile Smali classes
${SMALI} -JXmx512m assemble ${SMALI_ARGS} --output smali_classes.dex `find smali -name '*.smali'`
if [[ ! -s smali_classes.dex ]] ; then
- echo ${SMALI} produced no output. >&2
- exit 1
+ fail "${SMALI} produced no output."
fi
# Merge smali files into classes.dex, this takes priority over any jasmin files.
make_dexmerge classes.dex smali_classes.dex
@@ -479,7 +447,6 @@ if [ "${HAS_SMALI_MULTIDEX}" = "true" -a ${NEED_DEX} = "true" ]; then
make_dexmerge classes2.dex smali_classes2.dex
fi
-
if [ ${HAS_SRC_EX} = "true" ]; then
# Build src-ex into classes-ex.
# Includes 'src', 'src-art' source when compiling classes-ex, but exclude their .class files.
@@ -524,7 +491,7 @@ fi
# Create a single dex jar with two dex files for multidex.
if [ ${NEED_DEX} = "true" ]; then
- if $(has_multidex); then
+ if [ -f classes2.dex ] ; then
zip $TEST_NAME.jar classes.dex classes2.dex
else
zip $TEST_NAME.jar classes.dex
diff --git a/test/run-test b/test/run-test
index b5b42854e5..d90eccdf75 100755
--- a/test/run-test
+++ b/test/run-test
@@ -41,7 +41,7 @@ else
fi
checker="${progdir}/../tools/checker/checker.py"
export JAVA="java"
-export JAVAC="javac -g -Xlint:-options"
+export JAVAC="javac -g -Xlint:-options -source 1.8 -target 1.8"
export RUN="${progdir}/etc/run-test-jar"
export DEX_LOCATION=/data/run-test/${test_dir}
export NEED_DEX="true"
@@ -56,10 +56,10 @@ fi
# If dx was not set by the environment variable, assume it is in the path.
if [ -z "$DX" ]; then
- export DX="dx"
+ export DX="d8-compat-dx"
fi
-export DXMERGER="$D8"
+export DEXMERGER="$D8"
# If jasmin was not set by the environment variable, assume it is in the path.
if [ -z "$JASMIN" ]; then
@@ -675,13 +675,6 @@ if [ "$usage" = "no" ]; then
shift
fi
-# For building with javac and dx always use Java 7. The dx compiler
-# only support byte codes from Java 7 or earlier (class file major
-# version 51 or lower).
-if [ "$NEED_DEX" = "true" ]; then
- export JAVAC="${JAVAC} -source 1.7 -target 1.7"
-fi
-
if [ "$usage" = "yes" ]; then
prog=`basename $prog`
(
diff --git a/tools/desugar.sh b/tools/desugar.sh
deleted file mode 100755
index 7f73852ee5..0000000000
--- a/tools/desugar.sh
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2017 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.
-
-#
-# Calls desugar.jar with the --bootclasspath_entry values passed in automatically.
-# (This avoids having to manually set a boot class path).
-#
-#
-# Script-specific args:
-# --mode=[host|target]: Select between host or target bootclasspath (default target).
-# --core-only: Use only "core" bootclasspath (e.g. do not include framework).
-# --show-commands: Print the desugar command being executed.
-# --help: Print above list of args.
-#
-# All other args are forwarded to desugar.jar
-#
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-TOP=$DIR/../..
-
-pushd "$TOP" >/dev/null # back to android root.
-
-out=${OUT_DIR:-out}
-desugar_jar=$out/host/linux-x86/framework/desugar.jar
-
-if ! [[ -f $desugar_jar ]]; then
- echo "Error: Missing $desugar_jar; did you do a build?" >&2
- exit 1
-fi
-
-desugar_jar=$(readlink -f "$desugar_jar") # absolute path to desugar jar
-popd >/dev/null
-
-bootjars_args=
-mode=target
-showcommands=n
-while true; do
- case $1 in
- --help)
- echo "Usage: $0 [--mode=host|target] [--core-only] [--show-commands] <desugar args>"
- exit 0
- ;;
- --mode=host)
- bootjars_args="$bootjars_args --host"
- ;;
- --mode=target)
- bootjars_args="$bootjars_args --target"
- ;;
- --mode=*)
- echo "Unsupported $0 usage with --mode=$1" >&2
- exit 1
- ;;
- --core-only)
- bootjars_args="$bootjars_args --core"
- ;;
- --show-commands)
- showcommands=y
- ;;
- *)
- break
- ;;
- esac
- shift
-done
-
-desugar_args=(--min_sdk_version=10000)
-boot_class_path_list=$($TOP/art/tools/bootjars.sh $bootjars_args --path)
-
-for path in $boot_class_path_list; do
- desugar_args+=(--bootclasspath_entry="$path")
-done
-
-if [[ ${#desugar_args[@]} -eq 0 ]]; then
- echo "FATAL: Missing bootjars.sh file path list" >&2
- exit 1
-fi
-
-if [[ $showcommands == y ]]; then
- echo java -jar "$desugar_jar" "${desugar_args[@]}" "$@"
-fi
-
-java -jar "$desugar_jar" "${desugar_args[@]}" "$@"