1 /*
2 * Copyright (C) 2022 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
17 #include <gtest/gtest.h>
18
19 #include "code_info_table_deduper.h"
20
21 #include "arch/instruction_set.h"
22 #include "base/malloc_arena_pool.h"
23 #include "base/scoped_arena_allocator.h"
24 #include "base/scoped_arena_containers.h"
25 #include "optimizing/stack_map_stream.h"
26
27 namespace art {
28 namespace linker {
29
TEST(StackMapTest,TestDedupeBitTables)30 TEST(StackMapTest, TestDedupeBitTables) {
31 constexpr static uint32_t kPcAlign = GetInstructionSetInstructionAlignment(kRuntimeISA);
32 using Kind = DexRegisterLocation::Kind;
33
34 MallocArenaPool pool;
35 ArenaStack arena_stack(&pool);
36 ScopedArenaAllocator allocator(&arena_stack);
37 StackMapStream stream(&allocator, kRuntimeISA);
38 stream.BeginMethod(/* frame_size_in_bytes= */ 32,
39 /* core_spill_mask= */ 0,
40 /* fp_spill_mask= */ 0,
41 /* num_dex_registers= */ 2,
42 /* baseline= */ false,
43 /* debuggable= */ false);
44
45 stream.BeginStackMapEntry(0, 64 * kPcAlign);
46 stream.AddDexRegisterEntry(Kind::kInStack, 0);
47 stream.AddDexRegisterEntry(Kind::kConstant, -2);
48 stream.EndStackMapEntry();
49
50 stream.EndMethod(64 * kPcAlign);
51 ScopedArenaVector<uint8_t> memory = stream.Encode();
52
53 std::vector<uint8_t> out;
54 CodeInfoTableDeduper deduper(&out);
55 size_t deduped1 = deduper.Dedupe(memory.data());
56 size_t deduped2 = deduper.Dedupe(memory.data());
57
58 for (size_t deduped : { deduped1, deduped2 }) {
59 CodeInfo code_info(out.data() + deduped);
60 ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
61
62 StackMap stack_map = code_info.GetStackMapAt(0);
63 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
64 ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign)));
65 ASSERT_EQ(0u, stack_map.GetDexPc());
66 ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA));
67
68 ASSERT_TRUE(stack_map.HasDexRegisterMap());
69 DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map);
70
71 ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind());
72 ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind());
73 ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes());
74 ASSERT_EQ(-2, dex_register_map[1].GetConstant());
75 }
76
77 ASSERT_GT(memory.size() * 2, out.size());
78 }
79
80 } // namespace linker
81 } // namespace art
82