diff options
author | 2021-03-16 16:09:30 +0000 | |
---|---|---|
committer | 2021-03-17 12:12:27 +0000 | |
commit | 375257870bae0f9fc66f99b69a2b1e519c170c1c (patch) | |
tree | 588b82bed0c83fdd65bef0fb86fd729a7f2c3977 | |
parent | d1c8aaedf0eb3982f7e969ab66a2c391dbfd6929 (diff) |
Clean up OatHeader::GetStoreValueKey*().
Replace helper function ParseString() with calls to memchr()
and make the OatHeader::GetStoreValueKey*() more readable.
This also avoids using a pointer to `end + 1` when we fail
to find the end of the value (this was benign as that `+1`
should not cause arithmetic overflow anyway).
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I2fa9043f42048689a64fba3ab1fc3845f4684544
-rw-r--r-- | runtime/oat.cc | 81 |
1 files changed, 41 insertions, 40 deletions
diff --git a/runtime/oat.cc b/runtime/oat.cc index 321425ba00..3698ddfaed 100644 --- a/runtime/oat.cc +++ b/runtime/oat.cc @@ -335,65 +335,66 @@ const uint8_t* OatHeader::GetKeyValueStore() const { return key_value_store_; } -// Advance start until it is either end or \0. -static const char* ParseString(const char* start, const char* end) { - while (start < end && *start != 0) { - start++; - } - return start; -} - const char* OatHeader::GetStoreValueByKey(const char* key) const { + std::string_view key_view(key); const char* ptr = reinterpret_cast<const char*>(&key_value_store_); const char* end = ptr + key_value_store_size_; while (ptr < end) { // Scan for a closing zero. - const char* str_end = ParseString(ptr, end); - if (str_end < end) { - if (strcmp(key, ptr) == 0) { - // Same as key. Check if value is OK. - if (ParseString(str_end + 1, end) < end) { - return str_end + 1; - } - } else { - // Different from key. Advance over the value. - ptr = ParseString(str_end + 1, end) + 1; - } - } else { - break; + const char* str_end = reinterpret_cast<const char*>(memchr(ptr, 0, end - ptr)); + if (UNLIKELY(str_end == nullptr)) { + LOG(WARNING) << "OatHeader: Unterminated key in key value store."; + return nullptr; + } + const char* value_start = str_end + 1; + const char* value_end = + reinterpret_cast<const char*>(memchr(value_start, 0, end - value_start)); + if (UNLIKELY(value_end == nullptr)) { + LOG(WARNING) << "OatHeader: Unterminated value in key value store."; + return nullptr; } + if (key_view == std::string_view(ptr, str_end - ptr)) { + // Same as key. + return value_start; + } + // Different from key. Advance over the value. + ptr = value_end + 1; } // Not found. return nullptr; } -bool OatHeader::GetStoreKeyValuePairByIndex(size_t index, const char** key, +bool OatHeader::GetStoreKeyValuePairByIndex(size_t index, + const char** key, const char** value) const { const char* ptr = reinterpret_cast<const char*>(&key_value_store_); const char* end = ptr + key_value_store_size_; - ssize_t counter = static_cast<ssize_t>(index); + size_t counter = index; - while (ptr < end && counter >= 0) { + while (ptr < end) { // Scan for a closing zero. - const char* str_end = ParseString(ptr, end); - if (str_end < end) { - const char* maybe_key = ptr; - ptr = ParseString(str_end + 1, end) + 1; - if (ptr <= end) { - if (counter == 0) { - *key = maybe_key; - *value = str_end + 1; - return true; - } else { - counter--; - } - } else { - return false; - } + const char* str_end = reinterpret_cast<const char*>(memchr(ptr, 0, end - ptr)); + if (UNLIKELY(str_end == nullptr)) { + LOG(WARNING) << "OatHeader: Unterminated key in key value store."; + return false; + } + const char* value_start = str_end + 1; + const char* value_end = + reinterpret_cast<const char*>(memchr(value_start, 0, end - value_start)); + if (UNLIKELY(value_end == nullptr)) { + LOG(WARNING) << "OatHeader: Unterminated value in key value store."; + return false; + } + if (counter == 0) { + *key = ptr; + *value = value_start; + return true; } else { - break; + --counter; } + // Advance over the value. + ptr = value_end + 1; } // Not found. return false; |