From 7d59309458c69e1b2b2e85be5acc150979198f6f Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Fri, 19 Jun 2015 13:32:41 +0100 Subject: [PATCH] Use compiling class instead of referrer for access checks. bug:21869670 (cherry picked from commit 30451743493bc2f589e96d68ab98f557461f97f9) Change-Id: Ia18986797d166470801e7a9a690c054d2dc57952 --- compiler/optimizing/builder.cc | 36 ++++++++++++++++++++------------- compiler/optimizing/builder.h | 4 ++++ test/507-referrer/expected.txt | 0 test/507-referrer/info.txt | 2 ++ test/507-referrer/src/Main.java | 26 ++++++++++++++++++++++++ test/507-referrer/src/p1/InPackage.java | 25 +++++++++++++++++++++++ 6 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 test/507-referrer/expected.txt create mode 100644 test/507-referrer/info.txt create mode 100644 test/507-referrer/src/Main.java create mode 100644 test/507-referrer/src/p1/InPackage.java diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index eda2a0d29..2858c5093 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -862,17 +862,25 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction, return true; } -mirror::Class* HGraphBuilder::GetOutermostCompilingClass() const { +static mirror::Class* GetClassFrom(CompilerDriver* driver, + const DexCompilationUnit& compilation_unit) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); - const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile(); + const DexFile& dex_file = *compilation_unit.GetDexFile(); Handle class_loader(hs.NewHandle( - soa.Decode(dex_compilation_unit_->GetClassLoader()))); - Handle outer_dex_cache(hs.NewHandle( - outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file))); + soa.Decode(compilation_unit.GetClassLoader()))); + Handle dex_cache(hs.NewHandle( + compilation_unit.GetClassLinker()->FindDexCache(dex_file))); + + return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); +} + +mirror::Class* HGraphBuilder::GetOutermostCompilingClass() const { + return GetClassFrom(compiler_driver_, *outer_compilation_unit_); +} - return compiler_driver_->ResolveCompilingMethodsClass( - soa, outer_dex_cache, class_loader, outer_compilation_unit_); +mirror::Class* HGraphBuilder::GetCompilingClass() const { + return GetClassFrom(compiler_driver_, *dex_compilation_unit_); } bool HGraphBuilder::IsOutermostCompilingClass(uint16_t type_index) const { @@ -912,20 +920,20 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile(); Handle outer_dex_cache(hs.NewHandle( outer_compilation_unit_->GetClassLinker()->FindDexCache(outer_dex_file))); - Handle referrer_class(hs.NewHandle(GetOutermostCompilingClass())); + Handle outer_class(hs.NewHandle(GetOutermostCompilingClass())); // The index at which the field's class is stored in the DexCache's type array. uint32_t storage_index; - bool is_referrer_class = (referrer_class.Get() == resolved_field->GetDeclaringClass()); - if (is_referrer_class) { - storage_index = referrer_class->GetDexTypeIndex(); + bool is_outer_class = (outer_class.Get() == resolved_field->GetDeclaringClass()); + if (is_outer_class) { + storage_index = outer_class->GetDexTypeIndex(); } else if (outer_dex_cache.Get() != dex_cache.Get()) { // The compiler driver cannot currently understand multiple dex caches involved. Just bailout. return false; } else { std::pair pair = compiler_driver_->IsFastStaticField( outer_dex_cache.Get(), - referrer_class.Get(), + GetCompilingClass(), resolved_field, field_index, &storage_index); @@ -940,11 +948,11 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction, *outer_compilation_unit_->GetDexFile(), storage_index); bool is_initialized = resolved_field->GetDeclaringClass()->IsInitialized() && is_in_dex_cache; - HLoadClass* constant = new (arena_) HLoadClass(storage_index, is_referrer_class, dex_pc); + HLoadClass* constant = new (arena_) HLoadClass(storage_index, is_outer_class, dex_pc); current_block_->AddInstruction(constant); HInstruction* cls = constant; - if (!is_initialized && !is_referrer_class) { + if (!is_initialized && !is_outer_class) { cls = new (arena_) HClinitCheck(constant, dex_pc); current_block_->AddInstruction(cls); } diff --git a/compiler/optimizing/builder.h b/compiler/optimizing/builder.h index 36503ce43..b1ee82484 100644 --- a/compiler/optimizing/builder.h +++ b/compiler/optimizing/builder.h @@ -222,8 +222,12 @@ class HGraphBuilder : public ValueObject { void MaybeRecordStat(MethodCompilationStat compilation_stat); + // Returns the outer-most compiling method's class. mirror::Class* GetOutermostCompilingClass() const; + // Returns the class whose method is being compiled. + mirror::Class* GetCompilingClass() const; + // Returns whether `type_index` points to the outer-most compiling method's class. bool IsOutermostCompilingClass(uint16_t type_index) const; diff --git a/test/507-referrer/expected.txt b/test/507-referrer/expected.txt new file mode 100644 index 000000000..e69de29bb diff --git a/test/507-referrer/info.txt b/test/507-referrer/info.txt new file mode 100644 index 000000000..1335994d0 --- /dev/null +++ b/test/507-referrer/info.txt @@ -0,0 +1,2 @@ +Regression test for the optimizing compiler, which used +to do incorrect access checks on static fields when inlining. diff --git a/test/507-referrer/src/Main.java b/test/507-referrer/src/Main.java new file mode 100644 index 000000000..d03e0b229 --- /dev/null +++ b/test/507-referrer/src/Main.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import p1.InPackage; + +public class Main { + public static void main(String[] args) { + int result = InPackage.foo(); + if (result != 42) { + throw new Error("Expected 42, got " + result); + } + } +} diff --git a/test/507-referrer/src/p1/InPackage.java b/test/507-referrer/src/p1/InPackage.java new file mode 100644 index 000000000..2b1142792 --- /dev/null +++ b/test/507-referrer/src/p1/InPackage.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package p1; + +public class InPackage { + public static int foo() { + return myField; + } + + protected static int myField = 42; +} -- 2.11.0