diff options
author | 2017-02-13 21:26:22 +0000 | |
---|---|---|
committer | 2017-02-13 21:26:23 +0000 | |
commit | 60acc33c5b9bb93c23c4b54f6d97db2d5ec0828c (patch) | |
tree | 1be4af0c2b98992c782e44d4706df794f99d0bc9 | |
parent | 2d33ce2d9640c32c6a912aedd9e2436b51985608 (diff) | |
parent | 37c8e5c1739c02f2c01217f556e946e554cd06d0 (diff) |
Merge "Remove special treatment of native method for CHA."
-rw-r--r-- | runtime/art_method.cc | 1 | ||||
-rw-r--r-- | runtime/cha.cc | 18 | ||||
-rw-r--r-- | test/616-cha-native/expected.txt | 1 | ||||
-rw-r--r-- | test/616-cha-native/info.txt | 2 | ||||
-rw-r--r-- | test/616-cha-native/src/Main.java | 33 | ||||
-rw-r--r-- | test/616-cha/src/Main.java | 2 |
6 files changed, 44 insertions, 13 deletions
diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 6cb8544617..4902ad42d7 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -67,7 +67,6 @@ ArtMethod* ArtMethod::GetNonObsoleteMethod() { } ArtMethod* ArtMethod::GetSingleImplementation(PointerSize pointer_size) { - DCHECK(!IsNative()); if (!IsAbstract()) { // A non-abstract's single implementation is itself. return this; diff --git a/runtime/cha.cc b/runtime/cha.cc index d11b12f700..eaba01b2ce 100644 --- a/runtime/cha.cc +++ b/runtime/cha.cc @@ -200,7 +200,8 @@ void ClassHierarchyAnalysis::VerifyNonSingleImplementation(mirror::Class* verify if (verify_method != excluded_method) { DCHECK(!verify_method->HasSingleImplementation()) << "class: " << verify_class->PrettyClass() - << " verify_method: " << verify_method->PrettyMethod(true); + << " verify_method: " << verify_method->PrettyMethod(true) + << " excluded_method: " << excluded_method->PrettyMethod(true); if (verify_method->IsAbstract()) { DCHECK(verify_method->GetSingleImplementation(image_pointer_size) == nullptr); } @@ -257,9 +258,6 @@ void ClassHierarchyAnalysis::CheckSingleImplementationInfo( return; } - // Native methods don't have single-implementation flag set. - DCHECK(!method_in_super->IsNative()); - uint16_t method_index = method_in_super->GetMethodIndex(); if (method_in_super->IsAbstract()) { if (kIsDebugBuild) { @@ -374,12 +372,12 @@ void ClassHierarchyAnalysis::InitSingleImplementationFlag(Handle<mirror::Class> // used for static methods or methods of final classes. return; } - if (method->IsNative()) { - // Native method's invocation overhead is already high and it - // cannot be inlined. It's not worthwhile to devirtualize the - // call which can add a deoptimization point. - DCHECK(!method->HasSingleImplementation()); - } else if (method->IsAbstract()) { + if (method->IsAbstract()) { + // single-implementation of abstract method shares the same field + // that's used for JNI function of native method. It's fine since a method + // cannot be both abstract and native. + DCHECK(!method->IsNative()) << "Abstract method cannot be native"; + if (method->GetDeclaringClass()->IsInstantiable()) { // Rare case, but we do accept it (such as 800-smali/smali/b_26143249.smali). // Do not attempt to devirtualize it. diff --git a/test/616-cha-native/expected.txt b/test/616-cha-native/expected.txt new file mode 100644 index 0000000000..6a5618ebc6 --- /dev/null +++ b/test/616-cha-native/expected.txt @@ -0,0 +1 @@ +JNI_OnLoad called diff --git a/test/616-cha-native/info.txt b/test/616-cha-native/info.txt new file mode 100644 index 0000000000..a17bcaba9c --- /dev/null +++ b/test/616-cha-native/info.txt @@ -0,0 +1,2 @@ +Test for Class Hierarchy Analysis (CHA) single-implementation status updating +behavior on an overridden native method. diff --git a/test/616-cha-native/src/Main.java b/test/616-cha-native/src/Main.java new file mode 100644 index 0000000000..53a463ce87 --- /dev/null +++ b/test/616-cha-native/src/Main.java @@ -0,0 +1,33 @@ +/* + * 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. + */ + +abstract class A { + public abstract void foo(); +} + +class B extends A { + public native void foo(); +} + +class C extends B { + public void foo() {} +} + +public class Main { + public static void main(String[] args) { + System.loadLibrary(args[0]); + } +} diff --git a/test/616-cha/src/Main.java b/test/616-cha/src/Main.java index b6179449df..beea90a57d 100644 --- a/test/616-cha/src/Main.java +++ b/test/616-cha/src/Main.java @@ -196,8 +196,6 @@ public class Main { // should return true for those cases. assertSingleImplementation(java.lang.String.class, "charAt", true); assertSingleImplementation(java.lang.Thread.class, "join", true); - // We don't set single-implementation modifier bit for native methods. - assertSingleImplementation(java.lang.Thread.class, "isInterrupted", false); if (isInterpreted()) { sIsOptimizing = false; |