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