Home | History | Annotate | Download | only in optimizing
      1 /*
      2  * Copyright (C) 2014 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 "stack_map.h"
     18 #include "stack_map_stream.h"
     19 #include "utils/arena_bit_vector.h"
     20 
     21 #include "gtest/gtest.h"
     22 
     23 namespace art {
     24 
     25 bool SameBits(MemoryRegion region, const BitVector& bit_vector) {
     26   for (size_t i = 0; i < region.size_in_bits(); ++i) {
     27     if (region.LoadBit(i) != bit_vector.IsBitSet(i)) {
     28       return false;
     29     }
     30   }
     31   return true;
     32 }
     33 
     34 TEST(StackMapTest, Test1) {
     35   ArenaPool pool;
     36   ArenaAllocator arena(&pool);
     37   StackMapStream<size_t> stream(&arena);
     38 
     39   ArenaBitVector sp_mask(&arena, 0, false);
     40   stream.AddStackMapEntry(0, 64, 0x3, &sp_mask, 2, 0);
     41   stream.AddDexRegisterEntry(DexRegisterMap::kInStack, 0);
     42   stream.AddDexRegisterEntry(DexRegisterMap::kConstant, -2);
     43 
     44   size_t size = stream.ComputeNeededSize();
     45   void* memory = arena.Alloc(size, kArenaAllocMisc);
     46   MemoryRegion region(memory, size);
     47   stream.FillIn(region);
     48 
     49   CodeInfo<size_t> code_info(region);
     50   ASSERT_EQ(0u, code_info.GetStackMaskSize());
     51   ASSERT_EQ(1u, code_info.GetNumberOfStackMaps());
     52 
     53   StackMap<size_t> stack_map = code_info.GetStackMapAt(0);
     54   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
     55   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePc(64)));
     56   ASSERT_EQ(0u, stack_map.GetDexPc());
     57   ASSERT_EQ(64u, stack_map.GetNativePc());
     58   ASSERT_EQ(0x3u, stack_map.GetRegisterMask());
     59   ASSERT_FALSE(stack_map.HasInlineInfo());
     60 
     61   MemoryRegion stack_mask = stack_map.GetStackMask();
     62   ASSERT_TRUE(SameBits(stack_mask, sp_mask));
     63 
     64   DexRegisterMap dex_registers = code_info.GetDexRegisterMapOf(stack_map, 2);
     65   ASSERT_EQ(DexRegisterMap::kInStack, dex_registers.GetLocationKind(0));
     66   ASSERT_EQ(DexRegisterMap::kConstant, dex_registers.GetLocationKind(1));
     67   ASSERT_EQ(0, dex_registers.GetValue(0));
     68   ASSERT_EQ(-2, dex_registers.GetValue(1));
     69 }
     70 
     71 TEST(StackMapTest, Test2) {
     72   ArenaPool pool;
     73   ArenaAllocator arena(&pool);
     74   StackMapStream<size_t> stream(&arena);
     75 
     76   ArenaBitVector sp_mask1(&arena, 0, true);
     77   sp_mask1.SetBit(2);
     78   sp_mask1.SetBit(4);
     79   stream.AddStackMapEntry(0, 64, 0x3, &sp_mask1, 2, 2);
     80   stream.AddDexRegisterEntry(DexRegisterMap::kInStack, 0);
     81   stream.AddDexRegisterEntry(DexRegisterMap::kConstant, -2);
     82   stream.AddInlineInfoEntry(42);
     83   stream.AddInlineInfoEntry(82);
     84 
     85   ArenaBitVector sp_mask2(&arena, 0, true);
     86   sp_mask2.SetBit(3);
     87   sp_mask1.SetBit(8);
     88   stream.AddStackMapEntry(1, 128, 0xFF, &sp_mask2, 1, 0);
     89   stream.AddDexRegisterEntry(DexRegisterMap::kInRegister, 0);
     90 
     91   size_t size = stream.ComputeNeededSize();
     92   void* memory = arena.Alloc(size, kArenaAllocMisc);
     93   MemoryRegion region(memory, size);
     94   stream.FillIn(region);
     95 
     96   CodeInfo<size_t> code_info(region);
     97   ASSERT_EQ(1u, code_info.GetStackMaskSize());
     98   ASSERT_EQ(2u, code_info.GetNumberOfStackMaps());
     99 
    100   StackMap<size_t> stack_map = code_info.GetStackMapAt(0);
    101   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(0)));
    102   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePc(64)));
    103   ASSERT_EQ(0u, stack_map.GetDexPc());
    104   ASSERT_EQ(64u, stack_map.GetNativePc());
    105   ASSERT_EQ(0x3u, stack_map.GetRegisterMask());
    106 
    107   MemoryRegion stack_mask = stack_map.GetStackMask();
    108   ASSERT_TRUE(SameBits(stack_mask, sp_mask1));
    109 
    110   DexRegisterMap dex_registers = code_info.GetDexRegisterMapOf(stack_map, 2);
    111   ASSERT_EQ(DexRegisterMap::kInStack, dex_registers.GetLocationKind(0));
    112   ASSERT_EQ(DexRegisterMap::kConstant, dex_registers.GetLocationKind(1));
    113   ASSERT_EQ(0, dex_registers.GetValue(0));
    114   ASSERT_EQ(-2, dex_registers.GetValue(1));
    115 
    116   InlineInfo inline_info = code_info.GetInlineInfoOf(stack_map);
    117   ASSERT_EQ(2u, inline_info.GetDepth());
    118   ASSERT_EQ(42u, inline_info.GetMethodReferenceIndexAtDepth(0));
    119   ASSERT_EQ(82u, inline_info.GetMethodReferenceIndexAtDepth(1));
    120 
    121   stack_map = code_info.GetStackMapAt(1);
    122   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForDexPc(1u)));
    123   ASSERT_TRUE(stack_map.Equals(code_info.GetStackMapForNativePc(128u)));
    124   ASSERT_EQ(1u, stack_map.GetDexPc());
    125   ASSERT_EQ(128u, stack_map.GetNativePc());
    126   ASSERT_EQ(0xFFu, stack_map.GetRegisterMask());
    127 
    128   stack_mask = stack_map.GetStackMask();
    129   ASSERT_TRUE(SameBits(stack_mask, sp_mask2));
    130 
    131   ASSERT_FALSE(stack_map.HasInlineInfo());
    132 }
    133 
    134 }  // namespace art
    135