blob: b5525dc6a4daf5f35968c971d178a2994a1c5980 [file] [log] [blame]
Nicolas Geoffray01b70e82016-11-17 10:58:36 +00001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Nicolas Geoffray4e868fa2017-04-21 17:16:44 +010017#include "dex_to_dex_decompiler.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000018
Andreas Gampedbf54032018-06-18 14:47:01 -070019#include "base/casts.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000020#include "class_linker.h"
Vladimir Marko815d5e52019-03-04 10:18:31 +000021#include "common_compiler_driver_test.h"
Vladimir Markod8dbc8d2017-09-20 13:37:47 +010022#include "compiled_method-inl.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000023#include "compiler_callbacks.h"
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070024#include "dex/class_accessor-inl.h"
David Sehr9e734c72018-01-04 17:56:19 -080025#include "dex/dex_file.h"
Andreas Gampe2c30e4a2017-08-23 11:31:32 -070026#include "driver/compiler_driver.h"
27#include "driver/compiler_options.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000028#include "handle_scope-inl.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000029#include "mirror/class_loader.h"
Andreas Gampedbf54032018-06-18 14:47:01 -070030#include "quick_compiler_callbacks.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000031#include "runtime.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000032#include "scoped_thread_state_change-inl.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070033#include "thread.h"
34#include "verifier/method_verifier-inl.h"
Mathieu Chartier72041a02017-07-14 18:23:25 -070035#include "verifier/verifier_deps.h"
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000036
37namespace art {
38
Vladimir Marko815d5e52019-03-04 10:18:31 +000039class DexToDexDecompilerTest : public CommonCompilerDriverTest {
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000040 public:
41 void CompileAll(jobject class_loader) REQUIRES(!Locks::mutator_lock_) {
Vladimir Marko2afaff72018-11-30 17:01:50 +000042 TimingLogger timings("DexToDexDecompilerTest::CompileAll", false, false);
Vladimir Marko9c4b9702018-11-14 15:09:02 +000043 compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
Nicolas Geoffray49cda062017-04-21 13:08:25 +010044 compiler_options_->SetCompilerFilter(CompilerFilter::kQuicken);
Mathieu Chartier72041a02017-07-14 18:23:25 -070045 // Create the main VerifierDeps, here instead of in the compiler since we want to aggregate
46 // the results for all the dex files, not just the results for the current dex file.
Andreas Gampedbf54032018-06-18 14:47:01 -070047 down_cast<QuickCompilerCallbacks*>(Runtime::Current()->GetCompilerCallbacks())->SetVerifierDeps(
Mathieu Chartier72041a02017-07-14 18:23:25 -070048 new verifier::VerifierDeps(GetDexFiles(class_loader)));
Vladimir Marko2afaff72018-11-30 17:01:50 +000049 std::vector<const DexFile*> dex_files = GetDexFiles(class_loader);
Vladimir Marko815d5e52019-03-04 10:18:31 +000050 CommonCompilerDriverTest::CompileAll(class_loader, dex_files, &timings);
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000051 }
52
53 void RunTest(const char* dex_name) {
54 Thread* self = Thread::Current();
55 // First load the original dex file.
56 jobject original_class_loader;
57 {
58 ScopedObjectAccess soa(self);
59 original_class_loader = LoadDex(dex_name);
60 }
61 const DexFile* original_dex_file = GetDexFiles(original_class_loader)[0];
62
63 // Load the dex file again and make it writable to quicken them.
64 jobject class_loader;
65 const DexFile* updated_dex_file = nullptr;
66 {
67 ScopedObjectAccess soa(self);
68 class_loader = LoadDex(dex_name);
69 updated_dex_file = GetDexFiles(class_loader)[0];
70 Runtime::Current()->GetClassLinker()->RegisterDexFile(
Vladimir Markobcf17522018-06-01 13:14:32 +010071 *updated_dex_file, soa.Decode<mirror::ClassLoader>(class_loader));
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000072 }
73 // The dex files should be identical.
74 int cmp = memcmp(original_dex_file->Begin(),
75 updated_dex_file->Begin(),
76 updated_dex_file->Size());
77 ASSERT_EQ(0, cmp);
78
79 updated_dex_file->EnableWrite();
80 CompileAll(class_loader);
81 // The dex files should be different after quickening.
82 cmp = memcmp(original_dex_file->Begin(), updated_dex_file->Begin(), updated_dex_file->Size());
83 ASSERT_NE(0, cmp);
84
85 // Unquicken the dex file.
Mathieu Chartier18e26872018-06-04 17:19:02 -070086 for (ClassAccessor accessor : updated_dex_file->GetClasses()) {
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000087 // Unquicken each method.
Mathieu Chartier0d896bd2018-05-25 00:20:27 -070088 for (const ClassAccessor::Method& method : accessor.GetMethods()) {
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070089 CompiledMethod* compiled_method = compiler_driver_->GetCompiledMethod(
Mathieu Chartier0d896bd2018-05-25 00:20:27 -070090 method.GetReference());
Nicolas Geoffray01b70e82016-11-17 10:58:36 +000091 ArrayRef<const uint8_t> table;
92 if (compiled_method != nullptr) {
93 table = compiled_method->GetVmapTable();
94 }
Mathieu Chartier6238c832018-01-04 09:55:13 -080095 optimizer::ArtDecompileDEX(*updated_dex_file,
Mathieu Chartierc2b4db62018-05-18 13:58:12 -070096 *accessor.GetCodeItem(method),
Mathieu Chartier73f21d42018-01-02 14:26:50 -080097 table,
Andreas Gampe3db70682018-12-26 15:12:03 -080098 /* decompile_return_instruction= */ true);
Mathieu Chartier0d896bd2018-05-25 00:20:27 -070099 }
Nicolas Geoffray01b70e82016-11-17 10:58:36 +0000100 }
101
102 // Make sure after unquickening we go back to the same contents as the original dex file.
103 cmp = memcmp(original_dex_file->Begin(), updated_dex_file->Begin(), updated_dex_file->Size());
104 ASSERT_EQ(0, cmp);
105 }
106};
107
108TEST_F(DexToDexDecompilerTest, VerifierDeps) {
109 RunTest("VerifierDeps");
110}
111
112TEST_F(DexToDexDecompilerTest, DexToDexDecompiler) {
113 RunTest("DexToDexDecompiler");
114}
115
116} // namespace art