/* * Copyright (C) 2022 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. */ #include #include "code_info_table_deduper.h" #include "arch/instruction_set.h" #include "base/malloc_arena_pool.h" #include "base/scoped_arena_allocator.h" #include "base/scoped_arena_containers.h" #include "optimizing/stack_map_stream.h" namespace art { namespace linker { TEST(StackMapTest, TestDedupeBitTables) { constexpr static uint32_t kPcAlign = GetInstructionSetInstructionAlignment(kRuntimeISA); using Kind = DexRegisterLocation::Kind; MallocArenaPool pool; ArenaStack arena_stack(&pool); ScopedArenaAllocator allocator(&arena_stack); StackMapStream stream(&allocator, kRuntimeISA); stream.BeginMethod(32, 0, 0, 2); stream.BeginStackMapEntry(0, 64 * kPcAlign); stream.AddDexRegisterEntry(Kind::kInStack, 0); stream.AddDexRegisterEntry(Kind::kConstant, -2); stream.EndStackMapEntry(); stream.EndMethod(64 * kPcAlign); ScopedArenaVector memory = stream.Encode(); std::vector out; CodeInfoTableDeduper deduper(&out); size_t deduped1 = deduper.Dedupe(memory.data()); size_t deduped2 = deduper.Dedupe(memory.data()); for (size_t deduped : { deduped1, deduped2 }) { CodeInfo code_info(out.data() + deduped); ASSERT_EQ(1u, code_info.GetNumberOfStackMaps()); StackMap stack_map = code_info.GetStackMapAt(0); ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0))); ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePcOffset(64 * kPcAlign))); ASSERT_EQ(0u, stack_map.GetDexPc()); ASSERT_EQ(64u * kPcAlign, stack_map.GetNativePcOffset(kRuntimeISA)); ASSERT_TRUE(stack_map.HasDexRegisterMap()); DexRegisterMap dex_register_map = code_info.GetDexRegisterMapOf(stack_map); ASSERT_EQ(Kind::kInStack, dex_register_map[0].GetKind()); ASSERT_EQ(Kind::kConstant, dex_register_map[1].GetKind()); ASSERT_EQ(0, dex_register_map[0].GetStackOffsetInBytes()); ASSERT_EQ(-2, dex_register_map[1].GetConstant()); } ASSERT_GT(memory.size() * 2, out.size()); } } // namespace linker } // namespace art