1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker *
4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker *
8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker *
10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker */
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Worker #include "method_verifier.h"
18*795d594fSAndroid Build Coastguard Worker
19*795d594fSAndroid Build Coastguard Worker #include <stdio.h>
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker #include <memory>
22*795d594fSAndroid Build Coastguard Worker
23*795d594fSAndroid Build Coastguard Worker #include "android-base/strings.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/metrics/metrics_test.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/utils.h"
26*795d594fSAndroid Build Coastguard Worker #include "class_linker-inl.h"
27*795d594fSAndroid Build Coastguard Worker #include "class_verifier.h"
28*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
29*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file-inl.h"
30*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change-inl.h"
31*795d594fSAndroid Build Coastguard Worker #include "verifier_enums.h"
32*795d594fSAndroid Build Coastguard Worker
33*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
34*795d594fSAndroid Build Coastguard Worker namespace verifier {
35*795d594fSAndroid Build Coastguard Worker
36*795d594fSAndroid Build Coastguard Worker using metrics::test::CounterValue;
37*795d594fSAndroid Build Coastguard Worker
38*795d594fSAndroid Build Coastguard Worker class MethodVerifierTest : public CommonRuntimeTest {
39*795d594fSAndroid Build Coastguard Worker protected:
MethodVerifierTest()40*795d594fSAndroid Build Coastguard Worker MethodVerifierTest() {
41*795d594fSAndroid Build Coastguard Worker use_boot_image_ = true; // Make the Runtime creation cheaper.
42*795d594fSAndroid Build Coastguard Worker }
43*795d594fSAndroid Build Coastguard Worker
VerifyClass(const std::string & descriptor)44*795d594fSAndroid Build Coastguard Worker void VerifyClass(const std::string& descriptor)
45*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
46*795d594fSAndroid Build Coastguard Worker ASSERT_FALSE(descriptor.empty());
47*795d594fSAndroid Build Coastguard Worker Thread* self = Thread::Current();
48*795d594fSAndroid Build Coastguard Worker StackHandleScope<3> hs(self);
49*795d594fSAndroid Build Coastguard Worker Handle<mirror::Class> klass(
50*795d594fSAndroid Build Coastguard Worker hs.NewHandle(class_linker_->FindSystemClass(self, descriptor.c_str())));
51*795d594fSAndroid Build Coastguard Worker Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
52*795d594fSAndroid Build Coastguard Worker Handle<mirror::ClassLoader> loader(hs.NewHandle(klass->GetClassLoader()));
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker // Verify the class
55*795d594fSAndroid Build Coastguard Worker std::string error_msg;
56*795d594fSAndroid Build Coastguard Worker FailureKind failure = ClassVerifier::VerifyClass(self,
57*795d594fSAndroid Build Coastguard Worker /* verifier_deps= */ nullptr,
58*795d594fSAndroid Build Coastguard Worker dex_cache->GetDexFile(),
59*795d594fSAndroid Build Coastguard Worker klass,
60*795d594fSAndroid Build Coastguard Worker dex_cache,
61*795d594fSAndroid Build Coastguard Worker loader,
62*795d594fSAndroid Build Coastguard Worker *klass->GetClassDef(),
63*795d594fSAndroid Build Coastguard Worker nullptr,
64*795d594fSAndroid Build Coastguard Worker HardFailLogMode::kLogWarning,
65*795d594fSAndroid Build Coastguard Worker /* api_level= */ 0u,
66*795d594fSAndroid Build Coastguard Worker &error_msg);
67*795d594fSAndroid Build Coastguard Worker
68*795d594fSAndroid Build Coastguard Worker if (descriptor.starts_with("Ljava/lang/invoke")) {
69*795d594fSAndroid Build Coastguard Worker ASSERT_TRUE(failure == FailureKind::kSoftFailure ||
70*795d594fSAndroid Build Coastguard Worker failure == FailureKind::kNoFailure) << error_msg;
71*795d594fSAndroid Build Coastguard Worker
72*795d594fSAndroid Build Coastguard Worker } else {
73*795d594fSAndroid Build Coastguard Worker ASSERT_TRUE(failure == FailureKind::kNoFailure) << error_msg;
74*795d594fSAndroid Build Coastguard Worker }
75*795d594fSAndroid Build Coastguard Worker }
76*795d594fSAndroid Build Coastguard Worker
VerifyDexFile(const DexFile & dex)77*795d594fSAndroid Build Coastguard Worker void VerifyDexFile(const DexFile& dex)
78*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) {
79*795d594fSAndroid Build Coastguard Worker // Verify all the classes defined in this file
80*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < dex.NumClassDefs(); i++) {
81*795d594fSAndroid Build Coastguard Worker const dex::ClassDef& class_def = dex.GetClassDef(i);
82*795d594fSAndroid Build Coastguard Worker const char* descriptor = dex.GetClassDescriptor(class_def);
83*795d594fSAndroid Build Coastguard Worker VerifyClass(descriptor);
84*795d594fSAndroid Build Coastguard Worker }
85*795d594fSAndroid Build Coastguard Worker }
86*795d594fSAndroid Build Coastguard Worker };
87*795d594fSAndroid Build Coastguard Worker
TEST_F(MethodVerifierTest,LibCore)88*795d594fSAndroid Build Coastguard Worker TEST_F(MethodVerifierTest, LibCore) {
89*795d594fSAndroid Build Coastguard Worker ScopedObjectAccess soa(Thread::Current());
90*795d594fSAndroid Build Coastguard Worker ASSERT_TRUE(java_lang_dex_file_ != nullptr);
91*795d594fSAndroid Build Coastguard Worker VerifyDexFile(*java_lang_dex_file_);
92*795d594fSAndroid Build Coastguard Worker }
93*795d594fSAndroid Build Coastguard Worker
94*795d594fSAndroid Build Coastguard Worker // Make sure verification time metrics are collected.
TEST_F(MethodVerifierTest,VerificationTimeMetrics)95*795d594fSAndroid Build Coastguard Worker TEST_F(MethodVerifierTest, VerificationTimeMetrics) {
96*795d594fSAndroid Build Coastguard Worker ScopedObjectAccess soa(Thread::Current());
97*795d594fSAndroid Build Coastguard Worker ASSERT_TRUE(java_lang_dex_file_ != nullptr);
98*795d594fSAndroid Build Coastguard Worker auto* class_verification_total_time = GetMetrics()->ClassVerificationTotalTime();
99*795d594fSAndroid Build Coastguard Worker auto* class_verification_count = GetMetrics()->ClassVerificationCount();
100*795d594fSAndroid Build Coastguard Worker const uint64_t original_time = CounterValue(*class_verification_total_time);
101*795d594fSAndroid Build Coastguard Worker const uint64_t original_count = CounterValue(*class_verification_count);
102*795d594fSAndroid Build Coastguard Worker VerifyDexFile(*java_lang_dex_file_);
103*795d594fSAndroid Build Coastguard Worker ASSERT_GT(CounterValue(*class_verification_total_time), original_time);
104*795d594fSAndroid Build Coastguard Worker ASSERT_GT(CounterValue(*class_verification_count), original_count);
105*795d594fSAndroid Build Coastguard Worker }
106*795d594fSAndroid Build Coastguard Worker
107*795d594fSAndroid Build Coastguard Worker } // namespace verifier
108*795d594fSAndroid Build Coastguard Worker } // namespace art
109