1 /* 2 * Copyright (C) 2013 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 "leb128.h" 18 19 #include "gtest/gtest.h" 20 #include "base/histogram-inl.h" 21 22 namespace art { 23 24 struct DecodeUnsignedLeb128TestCase { 25 uint32_t decoded; 26 uint8_t leb128_data[5]; 27 }; 28 29 static DecodeUnsignedLeb128TestCase uleb128_tests[] = { 30 {0, {0, 0, 0, 0, 0}}, 31 {1, {1, 0, 0, 0, 0}}, 32 {0x7F, {0x7F, 0, 0, 0, 0}}, 33 {0x80, {0x80, 1, 0, 0, 0}}, 34 {0x81, {0x81, 1, 0, 0, 0}}, 35 {0xFF, {0xFF, 1, 0, 0, 0}}, 36 {0x4000, {0x80, 0x80, 1, 0, 0}}, 37 {0x4001, {0x81, 0x80, 1, 0, 0}}, 38 {0x4081, {0x81, 0x81, 1, 0, 0}}, 39 {0x0FFFFFFF, {0xFF, 0xFF, 0xFF, 0x7F, 0}}, 40 {0xFFFFFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0xF}}, 41 }; 42 43 struct DecodeSignedLeb128TestCase { 44 int32_t decoded; 45 uint8_t leb128_data[5]; 46 }; 47 48 static DecodeSignedLeb128TestCase sleb128_tests[] = { 49 {0, {0, 0, 0, 0, 0}}, 50 {1, {1, 0, 0, 0, 0}}, 51 {0x3F, {0x3F, 0, 0, 0, 0}}, 52 {0x40, {0xC0, 0 /* sign bit */, 0, 0, 0}}, 53 {0x41, {0xC1, 0 /* sign bit */, 0, 0, 0}}, 54 {0x80, {0x80, 1, 0, 0, 0}}, 55 {0xFF, {0xFF, 1, 0, 0, 0}}, 56 {0x1FFF, {0xFF, 0x3F, 0, 0, 0}}, 57 {0x2000, {0x80, 0xC0, 0 /* sign bit */, 0, 0}}, 58 {0x2001, {0x81, 0xC0, 0 /* sign bit */, 0, 0}}, 59 {0x2081, {0x81, 0xC1, 0 /* sign bit */, 0, 0}}, 60 {0x4000, {0x80, 0x80, 1, 0, 0}}, 61 {0x0FFFFF, {0xFF, 0xFF, 0x3F, 0, 0}}, 62 {0x100000, {0x80, 0x80, 0xC0, 0 /* sign bit */, 0}}, 63 {0x100001, {0x81, 0x80, 0xC0, 0 /* sign bit */, 0}}, 64 {0x100081, {0x81, 0x81, 0xC0, 0 /* sign bit */, 0}}, 65 {0x104081, {0x81, 0x81, 0xC1, 0 /* sign bit */, 0}}, 66 {0x200000, {0x80, 0x80, 0x80, 1, 0}}, 67 {0x7FFFFFF, {0xFF, 0xFF, 0xFF, 0x3F, 0}}, 68 {0x8000000, {0x80, 0x80, 0x80, 0xC0, 0 /* sign bit */}}, 69 {0x8000001, {0x81, 0x80, 0x80, 0xC0, 0 /* sign bit */}}, 70 {0x8000081, {0x81, 0x81, 0x80, 0xC0, 0 /* sign bit */}}, 71 {0x8004081, {0x81, 0x81, 0x81, 0xC0, 0 /* sign bit */}}, 72 {0x8204081, {0x81, 0x81, 0x81, 0xC1, 0 /* sign bit */}}, 73 {0x0FFFFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0 /* sign bit */}}, 74 {0x10000000, {0x80, 0x80, 0x80, 0x80, 1}}, 75 {0x7FFFFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0x7}}, 76 {-1, {0x7F, 0, 0, 0, 0}}, 77 {-2, {0x7E, 0, 0, 0, 0}}, 78 {-0x3F, {0x41, 0, 0, 0, 0}}, 79 {-0x40, {0x40, 0, 0, 0, 0}}, 80 {-0x41, {0xBF, 0x7F, 0, 0, 0}}, 81 {-0x80, {0x80, 0x7F, 0, 0, 0}}, 82 {-0x81, {0xFF, 0x7E, 0, 0, 0}}, 83 {-0x00002000, {0x80, 0x40, 0, 0, 0}}, 84 {-0x00002001, {0xFF, 0xBF, 0x7F, 0, 0}}, 85 {-0x00100000, {0x80, 0x80, 0x40, 0, 0}}, 86 {-0x00100001, {0xFF, 0xFF, 0xBF, 0x7F, 0}}, 87 {-0x08000000, {0x80, 0x80, 0x80, 0x40, 0}}, 88 {-0x08000001, {0xFF, 0xFF, 0xFF, 0xBF, 0x7F}}, 89 {-0x20000000, {0x80, 0x80, 0x80, 0x80, 0x7E}}, 90 {(-1) << 31, {0x80, 0x80, 0x80, 0x80, 0x78}}, 91 }; 92 93 TEST(Leb128Test, UnsignedSinglesVector) { 94 // Test individual encodings. 95 for (size_t i = 0; i < arraysize(uleb128_tests); ++i) { 96 Leb128EncodingVector builder; 97 builder.PushBackUnsigned(uleb128_tests[i].decoded); 98 EXPECT_EQ(UnsignedLeb128Size(uleb128_tests[i].decoded), builder.GetData().size()); 99 const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0]; 100 const uint8_t* encoded_data_ptr = &builder.GetData()[0]; 101 for (size_t j = 0; j < 5; ++j) { 102 if (j < builder.GetData().size()) { 103 EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j; 104 } else { 105 EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j; 106 } 107 } 108 EXPECT_EQ(DecodeUnsignedLeb128(&data_ptr), uleb128_tests[i].decoded) << " i = " << i; 109 } 110 } 111 112 TEST(Leb128Test, UnsignedSingles) { 113 // Test individual encodings. 114 for (size_t i = 0; i < arraysize(uleb128_tests); ++i) { 115 uint8_t encoded_data[5]; 116 uint8_t* end = EncodeUnsignedLeb128(encoded_data, uleb128_tests[i].decoded); 117 size_t data_size = static_cast<size_t>(end - encoded_data); 118 EXPECT_EQ(UnsignedLeb128Size(uleb128_tests[i].decoded), data_size); 119 const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0]; 120 for (size_t j = 0; j < 5; ++j) { 121 if (j < data_size) { 122 EXPECT_EQ(data_ptr[j], encoded_data[j]) << " i = " << i << " j = " << j; 123 } else { 124 EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j; 125 } 126 } 127 EXPECT_EQ(DecodeUnsignedLeb128(&data_ptr), uleb128_tests[i].decoded) << " i = " << i; 128 } 129 } 130 131 TEST(Leb128Test, UnsignedStreamVector) { 132 // Encode a number of entries. 133 Leb128EncodingVector builder; 134 for (size_t i = 0; i < arraysize(uleb128_tests); ++i) { 135 builder.PushBackUnsigned(uleb128_tests[i].decoded); 136 } 137 const uint8_t* encoded_data_ptr = &builder.GetData()[0]; 138 for (size_t i = 0; i < arraysize(uleb128_tests); ++i) { 139 const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0]; 140 for (size_t j = 0; j < UnsignedLeb128Size(uleb128_tests[i].decoded); ++j) { 141 EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j; 142 } 143 for (size_t j = UnsignedLeb128Size(uleb128_tests[i].decoded); j < 5; ++j) { 144 EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j; 145 } 146 EXPECT_EQ(DecodeUnsignedLeb128(&encoded_data_ptr), uleb128_tests[i].decoded) << " i = " << i; 147 } 148 EXPECT_EQ(builder.GetData().size(), 149 static_cast<size_t>(encoded_data_ptr - &builder.GetData()[0])); 150 } 151 152 TEST(Leb128Test, UnsignedStream) { 153 // Encode a number of entries. 154 uint8_t encoded_data[5 * arraysize(uleb128_tests)]; 155 uint8_t* end = encoded_data; 156 for (size_t i = 0; i < arraysize(uleb128_tests); ++i) { 157 end = EncodeUnsignedLeb128(end, uleb128_tests[i].decoded); 158 } 159 size_t data_size = static_cast<size_t>(end - encoded_data); 160 const uint8_t* encoded_data_ptr = encoded_data; 161 for (size_t i = 0; i < arraysize(uleb128_tests); ++i) { 162 const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0]; 163 for (size_t j = 0; j < UnsignedLeb128Size(uleb128_tests[i].decoded); ++j) { 164 EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j; 165 } 166 for (size_t j = UnsignedLeb128Size(uleb128_tests[i].decoded); j < 5; ++j) { 167 EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j; 168 } 169 EXPECT_EQ(DecodeUnsignedLeb128(&encoded_data_ptr), uleb128_tests[i].decoded) << " i = " << i; 170 } 171 EXPECT_EQ(data_size, static_cast<size_t>(encoded_data_ptr - encoded_data)); 172 } 173 174 TEST(Leb128Test, SignedSinglesVector) { 175 // Test individual encodings. 176 for (size_t i = 0; i < arraysize(sleb128_tests); ++i) { 177 Leb128EncodingVector builder; 178 builder.PushBackSigned(sleb128_tests[i].decoded); 179 EXPECT_EQ(SignedLeb128Size(sleb128_tests[i].decoded), builder.GetData().size()); 180 const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0]; 181 const uint8_t* encoded_data_ptr = &builder.GetData()[0]; 182 for (size_t j = 0; j < 5; ++j) { 183 if (j < builder.GetData().size()) { 184 EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j; 185 } else { 186 EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j; 187 } 188 } 189 EXPECT_EQ(DecodeSignedLeb128(&data_ptr), sleb128_tests[i].decoded) << " i = " << i; 190 } 191 } 192 193 TEST(Leb128Test, SignedSingles) { 194 // Test individual encodings. 195 for (size_t i = 0; i < arraysize(sleb128_tests); ++i) { 196 uint8_t encoded_data[5]; 197 uint8_t* end = EncodeSignedLeb128(encoded_data, sleb128_tests[i].decoded); 198 size_t data_size = static_cast<size_t>(end - encoded_data); 199 EXPECT_EQ(SignedLeb128Size(sleb128_tests[i].decoded), data_size); 200 const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0]; 201 for (size_t j = 0; j < 5; ++j) { 202 if (j < data_size) { 203 EXPECT_EQ(data_ptr[j], encoded_data[j]) << " i = " << i << " j = " << j; 204 } else { 205 EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j; 206 } 207 } 208 EXPECT_EQ(DecodeSignedLeb128(&data_ptr), sleb128_tests[i].decoded) << " i = " << i; 209 } 210 } 211 212 TEST(Leb128Test, SignedStreamVector) { 213 // Encode a number of entries. 214 Leb128EncodingVector builder; 215 for (size_t i = 0; i < arraysize(sleb128_tests); ++i) { 216 builder.PushBackSigned(sleb128_tests[i].decoded); 217 } 218 const uint8_t* encoded_data_ptr = &builder.GetData()[0]; 219 for (size_t i = 0; i < arraysize(sleb128_tests); ++i) { 220 const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0]; 221 for (size_t j = 0; j < SignedLeb128Size(sleb128_tests[i].decoded); ++j) { 222 EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j; 223 } 224 for (size_t j = SignedLeb128Size(sleb128_tests[i].decoded); j < 5; ++j) { 225 EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j; 226 } 227 EXPECT_EQ(DecodeSignedLeb128(&encoded_data_ptr), sleb128_tests[i].decoded) << " i = " << i; 228 } 229 EXPECT_EQ(builder.GetData().size(), 230 static_cast<size_t>(encoded_data_ptr - &builder.GetData()[0])); 231 } 232 233 TEST(Leb128Test, SignedStream) { 234 // Encode a number of entries. 235 uint8_t encoded_data[5 * arraysize(sleb128_tests)]; 236 uint8_t* end = encoded_data; 237 for (size_t i = 0; i < arraysize(sleb128_tests); ++i) { 238 end = EncodeSignedLeb128(end, sleb128_tests[i].decoded); 239 } 240 size_t data_size = static_cast<size_t>(end - encoded_data); 241 const uint8_t* encoded_data_ptr = encoded_data; 242 for (size_t i = 0; i < arraysize(sleb128_tests); ++i) { 243 const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0]; 244 for (size_t j = 0; j < SignedLeb128Size(sleb128_tests[i].decoded); ++j) { 245 EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j; 246 } 247 for (size_t j = SignedLeb128Size(sleb128_tests[i].decoded); j < 5; ++j) { 248 EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j; 249 } 250 EXPECT_EQ(DecodeSignedLeb128(&encoded_data_ptr), sleb128_tests[i].decoded) << " i = " << i; 251 } 252 EXPECT_EQ(data_size, static_cast<size_t>(encoded_data_ptr - encoded_data)); 253 } 254 255 TEST(Leb128Test, Speed) { 256 std::unique_ptr<Histogram<uint64_t>> enc_hist(new Histogram<uint64_t>("Leb128EncodeSpeedTest", 5)); 257 std::unique_ptr<Histogram<uint64_t>> dec_hist(new Histogram<uint64_t>("Leb128DecodeSpeedTest", 5)); 258 Leb128EncodingVector builder; 259 // Push back 1024 chunks of 1024 values measuring encoding speed. 260 uint64_t last_time = NanoTime(); 261 for (size_t i = 0; i < 1024; i++) { 262 for (size_t j = 0; j < 1024; j++) { 263 builder.PushBackUnsigned((i * 1024) + j); 264 } 265 uint64_t cur_time = NanoTime(); 266 enc_hist->AddValue(cur_time - last_time); 267 last_time = cur_time; 268 } 269 // Verify encoding and measure decode speed. 270 const uint8_t* encoded_data_ptr = &builder.GetData()[0]; 271 last_time = NanoTime(); 272 for (size_t i = 0; i < 1024; i++) { 273 for (size_t j = 0; j < 1024; j++) { 274 EXPECT_EQ(DecodeUnsignedLeb128(&encoded_data_ptr), (i * 1024) + j); 275 } 276 uint64_t cur_time = NanoTime(); 277 dec_hist->AddValue(cur_time - last_time); 278 last_time = cur_time; 279 } 280 281 Histogram<uint64_t>::CumulativeData enc_data; 282 enc_hist->CreateHistogram(&enc_data); 283 enc_hist->PrintConfidenceIntervals(std::cout, 0.99, enc_data); 284 285 Histogram<uint64_t>::CumulativeData dec_data; 286 dec_hist->CreateHistogram(&dec_data); 287 dec_hist->PrintConfidenceIntervals(std::cout, 0.99, dec_data); 288 } 289 290 } // namespace art 291