diff options
author | 2021-12-02 11:50:03 +0000 | |
---|---|---|
committer | 2022-01-13 00:26:45 +0000 | |
commit | 32b8c8f33ad68982357c1fa3d0f132d06b070ab5 (patch) | |
tree | 578504a572bfe61ddc22cfb6ce5013bcae28882e | |
parent | 8515f7fcf0fca795e5408ab691846b23ba608bda (diff) |
Expand sharpening's ComputeLoadClassKind to cover cross-dex cases
We can handle some extra cross-dex cases in order to expand the support.
Bug: 154012332
Test: ART tests
Change-Id: Ic3220d809086b4b3007bf5b6d63789ffb1b91fb9
-rw-r--r-- | compiler/driver/compiler_options.h | 4 | ||||
-rw-r--r-- | compiler/optimizing/sharpening.cc | 15 | ||||
-rw-r--r-- | dex2oat/linker/oat_writer.cc | 3 | ||||
-rw-r--r-- | test/2238-checker-load-class-multidex/expected-stderr.txt | 0 | ||||
-rw-r--r-- | test/2238-checker-load-class-multidex/expected-stdout.txt | 0 | ||||
-rw-r--r-- | test/2238-checker-load-class-multidex/info.txt | 1 | ||||
-rw-r--r-- | test/2238-checker-load-class-multidex/src-multidex/Caller.java | 24 | ||||
-rw-r--r-- | test/2238-checker-load-class-multidex/src/Main.java | 22 | ||||
-rw-r--r-- | test/2238-checker-load-class-multidex/src/pkg1/SubClass.java | 28 |
9 files changed, 87 insertions, 10 deletions
diff --git a/compiler/driver/compiler_options.h b/compiler/driver/compiler_options.h index a31be3f640..326e833191 100644 --- a/compiler/driver/compiler_options.h +++ b/compiler/driver/compiler_options.h @@ -26,6 +26,7 @@ #include "base/globals.h" #include "base/hash_set.h" #include "base/macros.h" +#include "base/stl_util.h" #include "base/utils.h" #include "optimizing/register_allocator.h" @@ -374,8 +375,7 @@ class CompilerOptions final { } bool WithinOatFile(const DexFile* dex_file) const { - return std::find(GetDexFilesForOatFile().begin(), GetDexFilesForOatFile().end(), dex_file) != - GetDexFilesForOatFile().end(); + return ContainsElement(GetDexFilesForOatFile(), dex_file); } private: diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index 1fd76f7029..cb9edc0127 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -275,15 +275,18 @@ HLoadClass::LoadKind HSharpening::ComputeLoadClassKind( } HLoadClass::LoadKind load_kind = codegen->GetSupportedLoadClassKind(desired_load_kind); + // If we cannot reference this class due to .bss requirements, we're forced to bail. if (!IsSameDexFile(load_class->GetDexFile(), *dex_compilation_unit.GetDexFile())) { - if (load_kind == HLoadClass::LoadKind::kRuntimeCall || - load_kind == HLoadClass::LoadKind::kBssEntry || + if (load_kind == HLoadClass::LoadKind::kRuntimeCall) { + return HLoadClass::LoadKind::kInvalid; + } + + if (load_kind == HLoadClass::LoadKind::kBssEntry || load_kind == HLoadClass::LoadKind::kBssEntryPublic || load_kind == HLoadClass::LoadKind::kBssEntryPackage) { - // We actually cannot reference this class, we're forced to bail. - // We cannot reference this class with Bss, as the entrypoint will lookup the class - // in the caller's dex file, but that dex file does not reference the class. - return HLoadClass::LoadKind::kInvalid; + if (!codegen->GetCompilerOptions().WithinOatFile(&load_class->GetDexFile())) { + return HLoadClass::LoadKind::kInvalid; + } } } return load_kind; diff --git a/dex2oat/linker/oat_writer.cc b/dex2oat/linker/oat_writer.cc index 70260bcc02..c5f3adf867 100644 --- a/dex2oat/linker/oat_writer.cc +++ b/dex2oat/linker/oat_writer.cc @@ -946,8 +946,7 @@ class OatWriter::InitBssLayoutMethodVisitor : public DexMethodVisitor { /*inout*/ SafeMap<const DexFile*, BitVector>* references) { // We currently support inlining of throwing instructions only when they originate in the // same oat file as the outer method. All .bss references are used by throwing instructions. - DCHECK(std::find(writer_->dex_files_->begin(), writer_->dex_files_->end(), ref.dex_file) != - writer_->dex_files_->end()); + DCHECK(ContainsElement(*writer_->dex_files_, ref.dex_file)); DCHECK_LT(ref.index, number_of_indexes); auto refs_it = references->find(ref.dex_file); diff --git a/test/2238-checker-load-class-multidex/expected-stderr.txt b/test/2238-checker-load-class-multidex/expected-stderr.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2238-checker-load-class-multidex/expected-stderr.txt diff --git a/test/2238-checker-load-class-multidex/expected-stdout.txt b/test/2238-checker-load-class-multidex/expected-stdout.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/2238-checker-load-class-multidex/expected-stdout.txt diff --git a/test/2238-checker-load-class-multidex/info.txt b/test/2238-checker-load-class-multidex/info.txt new file mode 100644 index 0000000000..c4ef65e25c --- /dev/null +++ b/test/2238-checker-load-class-multidex/info.txt @@ -0,0 +1 @@ +Check that the Invoke's load class uses the .bss entries. diff --git a/test/2238-checker-load-class-multidex/src-multidex/Caller.java b/test/2238-checker-load-class-multidex/src-multidex/Caller.java new file mode 100644 index 0000000000..223230a89d --- /dev/null +++ b/test/2238-checker-load-class-multidex/src-multidex/Caller.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class Caller { + /// CHECK-START: void Caller.doCall() builder (after) + /// CHECK: LoadClass load_kind:BssEntry class_name:pkg1.SuperClass + /// CHECK: InvokeStaticOrDirect method_name:pkg1.SuperClass.$noinline$callMethod + public static void doCall() { + pkg1.SubClass.$noinline$callMethod(); + } +}
\ No newline at end of file diff --git a/test/2238-checker-load-class-multidex/src/Main.java b/test/2238-checker-load-class-multidex/src/Main.java new file mode 100644 index 0000000000..a2f595dcab --- /dev/null +++ b/test/2238-checker-load-class-multidex/src/Main.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +final class Main { + public static void main(String[] args) { + pkg1.SubClass.$noinline$callMethod(); + Caller.doCall(); + } +} diff --git a/test/2238-checker-load-class-multidex/src/pkg1/SubClass.java b/test/2238-checker-load-class-multidex/src/pkg1/SubClass.java new file mode 100644 index 0000000000..0e01c3cd4e --- /dev/null +++ b/test/2238-checker-load-class-multidex/src/pkg1/SubClass.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package pkg1; + +// `SuperClass` is only visible to classes in packge `pkg1`. +class SuperClass { + public static void $noinline$callMethod() { + } +} + +// Any class (inside or outside `pkg1`) can access `SuperClass.callMethod` by referencing it as +// `SubClass.callMethod`. +public class SubClass extends SuperClass { +} |