summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2021-03-16 16:09:30 +0000
committer Vladimir Marko <vmarko@google.com> 2021-03-17 12:12:27 +0000
commit375257870bae0f9fc66f99b69a2b1e519c170c1c (patch)
tree588b82bed0c83fdd65bef0fb86fd729a7f2c3977
parentd1c8aaedf0eb3982f7e969ab66a2c391dbfd6929 (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.cc81
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;