ART: Add dex::StringIndex
Add abstraction for uint32_t string index.
Test: m test-art-host
Change-Id: I917c2881702fe3df112c713f06980f2278ced7ed
diff --git a/runtime/art_field.cc b/runtime/art_field.cc
index 25b8ed2..a4a6e5a 100644
--- a/runtime/art_field.cc
+++ b/runtime/art_field.cc
@@ -54,7 +54,7 @@
ObjPtr<mirror::String> ArtField::ResolveGetStringName(Thread* self,
const DexFile& dex_file,
- uint32_t string_idx,
+ dex::StringIndex string_idx,
ObjPtr<mirror::DexCache> dex_cache) {
StackHandleScope<1> hs(self);
return Runtime::Current()->GetClassLinker()->ResolveString(dex_file,
diff --git a/runtime/art_field.h b/runtime/art_field.h
index cacb324..427e103 100644
--- a/runtime/art_field.h
+++ b/runtime/art_field.h
@@ -221,7 +221,7 @@
REQUIRES_SHARED(Locks::mutator_lock_);
ObjPtr<mirror::String> ResolveGetStringName(Thread* self,
const DexFile& dex_file,
- uint32_t string_idx,
+ dex::StringIndex string_idx,
ObjPtr<mirror::DexCache> dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 81adaeb..7005c29 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -65,14 +65,15 @@
return array_class.Ptr();
}
-inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx, ArtMethod* referrer) {
+inline mirror::String* ClassLinker::ResolveString(dex::StringIndex string_idx,
+ ArtMethod* referrer) {
Thread::PoisonObjectPointersIfDebug();
ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
// MethodVerifier refuses methods with string_idx out of bounds.
- DCHECK_LT(string_idx, declaring_class->GetDexFile().NumStringIds());
+ DCHECK_LT(string_idx.index_, declaring_class->GetDexFile().NumStringIds());
ObjPtr<mirror::String> string =
mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(),
- string_idx,
+ string_idx.index_,
mirror::DexCache::kDexCacheStringCacheSize).Read();
if (UNLIKELY(string == nullptr)) {
StackHandleScope<1> hs(Thread::Current());
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 216ec9e..f98f364 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -7557,7 +7557,7 @@
}
mirror::String* ClassLinker::ResolveString(const DexFile& dex_file,
- uint32_t string_idx,
+ dex::StringIndex string_idx,
Handle<mirror::DexCache> dex_cache) {
DCHECK(dex_cache.Get() != nullptr);
Thread::PoisonObjectPointersIfDebug();
@@ -7573,7 +7573,7 @@
}
mirror::String* ClassLinker::LookupString(const DexFile& dex_file,
- uint32_t string_idx,
+ dex::StringIndex string_idx,
Handle<mirror::DexCache> dex_cache) {
DCHECK(dex_cache.Get() != nullptr);
ObjPtr<mirror::String> resolved = dex_cache->GetResolvedString(string_idx);
@@ -7582,7 +7582,8 @@
}
uint32_t utf16_length;
const char* utf8_data = dex_file.StringDataAndUtf16LengthByIdx(string_idx, &utf16_length);
- ObjPtr<mirror::String> string = intern_table_->LookupStrong(Thread::Current(), utf16_length, utf8_data);
+ ObjPtr<mirror::String> string =
+ intern_table_->LookupStrong(Thread::Current(), utf16_length, utf8_data);
if (string != nullptr) {
dex_cache->SetResolvedString(string_idx, string);
}
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 88028ea..1205074 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -231,18 +231,20 @@
// Resolve a String with the given index from the DexFile, storing the
// result in the DexCache. The referrer is used to identify the
// target DexCache and ClassLoader to use for resolution.
- mirror::String* ResolveString(uint32_t string_idx, ArtMethod* referrer)
+ mirror::String* ResolveString(dex::StringIndex string_idx, ArtMethod* referrer)
REQUIRES_SHARED(Locks::mutator_lock_);
// Resolve a String with the given index from the DexFile, storing the
// result in the DexCache.
- mirror::String* ResolveString(const DexFile& dex_file, uint32_t string_idx,
+ mirror::String* ResolveString(const DexFile& dex_file,
+ dex::StringIndex string_idx,
Handle<mirror::DexCache> dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_);
// Find a String with the given index from the DexFile, storing the
// result in the DexCache if found. Return null if not found.
- mirror::String* LookupString(const DexFile& dex_file, uint32_t string_idx,
+ mirror::String* LookupString(const DexFile& dex_file,
+ dex::StringIndex string_idx,
Handle<mirror::DexCache> dex_cache)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h
index 77a63c1..e884e39 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -43,9 +43,9 @@
return GetStringDataAndUtf16Length(string_id, &ignored);
}
-inline const char* DexFile::StringDataAndUtf16LengthByIdx(uint32_t idx,
+inline const char* DexFile::StringDataAndUtf16LengthByIdx(dex::StringIndex idx,
uint32_t* utf16_length) const {
- if (idx == kDexNoIndex) {
+ if (!idx.IsValid()) {
*utf16_length = 0;
return nullptr;
}
@@ -53,7 +53,7 @@
return GetStringDataAndUtf16Length(string_id, utf16_length);
}
-inline const char* DexFile::StringDataByIdx(uint32_t idx) const {
+inline const char* DexFile::StringDataByIdx(dex::StringIndex idx) const {
uint32_t unicode_length;
return StringDataAndUtf16LengthByIdx(idx, &unicode_length);
}
@@ -130,8 +130,8 @@
(RoundUp(reinterpret_cast<uintptr_t>(insns_end_), 4)) + offset;
}
-static inline bool DexFileStringEquals(const DexFile* df1, uint32_t sidx1,
- const DexFile* df2, uint32_t sidx2) {
+static inline bool DexFileStringEquals(const DexFile* df1, dex::StringIndex sidx1,
+ const DexFile* df2, dex::StringIndex sidx2) {
uint32_t s1_len; // Note: utf16 length != mutf8 length.
const char* s1_data = df1->StringDataAndUtf16LengthByIdx(sidx1, &s1_len);
uint32_t s2_len;
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index cc544fd..aa8fb38 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -45,6 +45,8 @@
namespace art {
+static_assert(sizeof(dex::StringIndex) == sizeof(uint32_t), "StringIndex size is wrong");
+static_assert(std::is_trivially_copyable<dex::StringIndex>::value, "StringIndex not trivial");
static_assert(sizeof(dex::TypeIndex) == sizeof(uint16_t), "TypeIndex size is wrong");
static_assert(std::is_trivially_copyable<dex::TypeIndex>::value, "TypeIndex not trivial");
@@ -602,7 +604,7 @@
const DexFile::TypeId& type) const {
// Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass);
- const uint32_t name_idx = GetIndexForStringId(name);
+ const dex::StringIndex name_idx = GetIndexForStringId(name);
const dex::TypeIndex type_idx = GetIndexForTypeId(type);
int32_t lo = 0;
int32_t hi = NumFieldIds() - 1;
@@ -637,7 +639,7 @@
const DexFile::ProtoId& signature) const {
// Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx
const dex::TypeIndex class_idx = GetIndexForTypeId(declaring_klass);
- const uint32_t name_idx = GetIndexForStringId(name);
+ const dex::StringIndex name_idx = GetIndexForStringId(name);
const uint16_t proto_idx = GetIndexForProtoId(signature);
int32_t lo = 0;
int32_t hi = NumMethodIds() - 1;
@@ -672,7 +674,7 @@
int32_t hi = NumStringIds() - 1;
while (hi >= lo) {
int32_t mid = (hi + lo) / 2;
- const DexFile::StringId& str_id = GetStringId(mid);
+ const DexFile::StringId& str_id = GetStringId(dex::StringIndex(mid));
const char* str = GetStringData(str_id);
int compare = CompareModifiedUtf8ToModifiedUtf8AsUtf16CodePointValues(string, str);
if (compare > 0) {
@@ -711,7 +713,7 @@
int32_t hi = NumStringIds() - 1;
while (hi >= lo) {
int32_t mid = (hi + lo) / 2;
- const DexFile::StringId& str_id = GetStringId(mid);
+ const DexFile::StringId& str_id = GetStringId(dex::StringIndex(mid));
const char* str = GetStringData(str_id);
int compare = CompareModifiedUtf8ToUtf16AsCodePointValues(str, string, length);
if (compare > 0) {
@@ -725,7 +727,7 @@
return nullptr;
}
-const DexFile::TypeId* DexFile::FindTypeId(uint32_t string_idx) const {
+const DexFile::TypeId* DexFile::FindTypeId(dex::StringIndex string_idx) const {
int32_t lo = 0;
int32_t hi = NumTypeIds() - 1;
while (hi >= lo) {
@@ -912,7 +914,7 @@
}
uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
const char* descriptor = it.GetDescriptor();
- local_in_reg[arg_reg].name_ = StringDataByIdx(name_idx);
+ local_in_reg[arg_reg].name_ = StringDataByIdx(dex::StringIndex(name_idx));
local_in_reg[arg_reg].descriptor_ = descriptor;
local_in_reg[arg_reg].signature_ = nullptr;
local_in_reg[arg_reg].start_address_ = 0;
@@ -975,10 +977,10 @@
local_cb(context, local_in_reg[reg]);
}
- local_in_reg[reg].name_ = StringDataByIdx(name_idx);
+ local_in_reg[reg].name_ = StringDataByIdx(dex::StringIndex(name_idx));
local_in_reg[reg].descriptor_ =
StringByTypeIdx(dex::TypeIndex(dchecked_integral_cast<uint16_t>(descriptor_idx)));;
- local_in_reg[reg].signature_ = StringDataByIdx(signature_idx);
+ local_in_reg[reg].signature_ = StringDataByIdx(dex::StringIndex(signature_idx));
local_in_reg[reg].start_address_ = address;
local_in_reg[reg].reg_ = reg;
local_in_reg[reg].is_live_ = true;
@@ -1080,7 +1082,7 @@
break;
case DBG_SET_FILE: {
uint32_t name_idx = DecodeUnsignedLeb128P1(&stream);
- entry.source_file_ = StringDataByIdx(name_idx);
+ entry.source_file_ = StringDataByIdx(dex::StringIndex(name_idx));
break;
}
default: {
@@ -1482,6 +1484,11 @@
namespace dex {
+std::ostream& operator<<(std::ostream& os, const StringIndex& index) {
+ os << "StringIndex[" << index.index_ << "]";
+ return os;
+}
+
std::ostream& operator<<(std::ostream& os, const TypeIndex& index) {
os << "TypeIndex[" << index.index_ << "]";
return os;
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 2384eb6..250795b 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -152,7 +152,7 @@
// Raw type_id_item.
struct TypeId {
- uint32_t descriptor_idx_; // index into string_ids
+ dex::StringIndex descriptor_idx_; // index into string_ids
private:
DISALLOW_COPY_AND_ASSIGN(TypeId);
@@ -160,9 +160,9 @@
// Raw field_id_item.
struct FieldId {
- dex::TypeIndex class_idx_; // index into type_ids_ array for defining class
- dex::TypeIndex type_idx_; // index into type_ids_ array for field type
- uint32_t name_idx_; // index into string_ids_ array for field name
+ dex::TypeIndex class_idx_; // index into type_ids_ array for defining class
+ dex::TypeIndex type_idx_; // index into type_ids_ array for field type
+ dex::StringIndex name_idx_; // index into string_ids_ array for field name
private:
DISALLOW_COPY_AND_ASSIGN(FieldId);
@@ -170,10 +170,10 @@
// Raw proto_id_item.
struct ProtoId {
- uint32_t shorty_idx_; // index into string_ids array for shorty descriptor
+ dex::StringIndex shorty_idx_; // index into string_ids array for shorty descriptor
dex::TypeIndex return_type_idx_; // index into type_ids array for return type
- uint16_t pad_; // padding = 0
- uint32_t parameters_off_; // file offset to type_list for parameter types
+ uint16_t pad_; // padding = 0
+ uint32_t parameters_off_; // file offset to type_list for parameter types
private:
DISALLOW_COPY_AND_ASSIGN(ProtoId);
@@ -182,8 +182,8 @@
// Raw method_id_item.
struct MethodId {
dex::TypeIndex class_idx_; // index into type_ids_ array for defining class
- uint16_t proto_idx_; // index into proto_ids_ array for method prototype
- uint32_t name_idx_; // index into string_ids_ array for method name
+ uint16_t proto_idx_; // index into proto_ids_ array for method prototype
+ dex::StringIndex name_idx_; // index into string_ids_ array for method name
private:
DISALLOW_COPY_AND_ASSIGN(MethodId);
@@ -197,7 +197,7 @@
dex::TypeIndex superclass_idx_; // index into type_ids_ array for superclass
uint16_t pad2_; // padding = 0
uint32_t interfaces_off_; // file offset to TypeList
- uint32_t source_file_idx_; // index into string_ids_ for source file name
+ dex::StringIndex source_file_idx_; // index into string_ids_ for source file name
uint32_t annotations_off_; // file offset to annotations_directory_item
uint32_t class_data_off_; // file offset to class_data_item
uint32_t static_values_off_; // file offset to EncodedArray
@@ -501,15 +501,15 @@
}
// Returns the StringId at the specified index.
- const StringId& GetStringId(uint32_t idx) const {
- DCHECK_LT(idx, NumStringIds()) << GetLocation();
- return string_ids_[idx];
+ const StringId& GetStringId(dex::StringIndex idx) const {
+ DCHECK_LT(idx.index_, NumStringIds()) << GetLocation();
+ return string_ids_[idx.index_];
}
- uint32_t GetIndexForStringId(const StringId& string_id) const {
+ dex::StringIndex GetIndexForStringId(const StringId& string_id) const {
CHECK_GE(&string_id, string_ids_) << GetLocation();
CHECK_LT(&string_id, string_ids_ + header_->string_ids_size_) << GetLocation();
- return &string_id - string_ids_;
+ return dex::StringIndex(&string_id - string_ids_);
}
int32_t GetStringLength(const StringId& string_id) const;
@@ -522,9 +522,9 @@
const char* GetStringData(const StringId& string_id) const;
// Index version of GetStringDataAndUtf16Length.
- const char* StringDataAndUtf16LengthByIdx(uint32_t idx, uint32_t* utf16_length) const;
+ const char* StringDataAndUtf16LengthByIdx(dex::StringIndex idx, uint32_t* utf16_length) const;
- const char* StringDataByIdx(uint32_t idx) const;
+ const char* StringDataByIdx(dex::StringIndex idx) const;
// Looks up a string id for a given modified utf8 string.
const StringId* FindStringId(const char* string) const;
@@ -563,7 +563,7 @@
const char* GetTypeDescriptor(const TypeId& type_id) const;
// Looks up a type for the given string index
- const TypeId* FindTypeId(uint32_t string_idx) const;
+ const TypeId* FindTypeId(dex::StringIndex string_idx) const;
// Returns the number of field identifiers in the .dex file.
size_t NumFieldIds() const {
@@ -963,7 +963,7 @@
void* context) const;
const char* GetSourceFile(const ClassDef& class_def) const {
- if (class_def.source_file_idx_ == 0xffffffff) {
+ if (!class_def.source_file_idx_.IsValid()) {
return nullptr;
} else {
return StringDataByIdx(class_def.source_file_idx_);
diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc
index 3fe2c40..52b9f11 100644
--- a/runtime/dex_file_annotations.cc
+++ b/runtime/dex_file_annotations.cc
@@ -167,7 +167,8 @@
while (size != 0) {
uint32_t element_name_index = DecodeUnsignedLeb128(&annotation);
- const char* element_name = dex_file.GetStringData(dex_file.GetStringId(element_name_index));
+ const char* element_name =
+ dex_file.GetStringData(dex_file.GetStringId(dex::StringIndex(element_name_index)));
if (strcmp(name, element_name) == 0) {
return annotation;
}
@@ -357,7 +358,7 @@
StackHandleScope<1> hs(self);
Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
element_object = Runtime::Current()->GetClassLinker()->ResolveString(
- klass->GetDexFile(), index, dex_cache);
+ klass->GetDexFile(), dex::StringIndex(index), dex_cache);
set_object = true;
if (element_object == nullptr) {
return false;
@@ -592,7 +593,7 @@
ScopedObjectAccessUnchecked soa(self);
StackHandleScope<5> hs(self);
uint32_t element_name_index = DecodeUnsignedLeb128(annotation);
- const char* name = dex_file.StringDataByIdx(element_name_index);
+ const char* name = dex_file.StringDataByIdx(dex::StringIndex(element_name_index));
Handle<mirror::String> string_name(
hs.NewHandle(mirror::String::AllocFromModifiedUtf8(self, name)));
@@ -1341,7 +1342,9 @@
case kDouble: field->SetDouble<kTransactionActive>(field->GetDeclaringClass(), jval_.d); break;
case kNull: field->SetObject<kTransactionActive>(field->GetDeclaringClass(), nullptr); break;
case kString: {
- mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, *dex_cache_);
+ mirror::String* resolved = linker_->ResolveString(dex_file_,
+ dex::StringIndex(jval_.i),
+ *dex_cache_);
field->SetObject<kTransactionActive>(field->GetDeclaringClass(), resolved);
break;
}
diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc
index f94d07b..0fec856 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -418,7 +418,7 @@
const char* type_str = java_lang_dex_file_->StringByTypeIdx(dex::TypeIndex(i));
const DexFile::StringId* type_str_id = java_lang_dex_file_->FindStringId(type_str);
ASSERT_TRUE(type_str_id != nullptr);
- uint32_t type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
+ dex::StringIndex type_str_idx = java_lang_dex_file_->GetIndexForStringId(*type_str_id);
const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId(type_str_idx);
ASSERT_EQ(type_id, java_lang_dex_file_->FindTypeId(type_str));
ASSERT_TRUE(type_id != nullptr);
diff --git a/runtime/dex_file_types.h b/runtime/dex_file_types.h
index c6d95a1..bd779c4 100644
--- a/runtime/dex_file_types.h
+++ b/runtime/dex_file_types.h
@@ -23,12 +23,47 @@
namespace art {
namespace dex {
+class StringIndex {
+ public:
+ uint32_t index_;
+
+ constexpr StringIndex() : index_(std::numeric_limits<decltype(index_)>::max()) {}
+ explicit constexpr StringIndex(uint32_t idx) : index_(idx) {}
+
+ bool IsValid() const {
+ return index_ != std::numeric_limits<decltype(index_)>::max();
+ }
+ static StringIndex Invalid() {
+ return StringIndex(std::numeric_limits<decltype(index_)>::max());
+ }
+
+ bool operator==(const StringIndex& other) const {
+ return index_ == other.index_;
+ }
+ bool operator!=(const StringIndex& other) const {
+ return index_ != other.index_;
+ }
+ bool operator<(const StringIndex& other) const {
+ return index_ < other.index_;
+ }
+ bool operator<=(const StringIndex& other) const {
+ return index_ <= other.index_;
+ }
+ bool operator>(const StringIndex& other) const {
+ return index_ > other.index_;
+ }
+ bool operator>=(const StringIndex& other) const {
+ return index_ >= other.index_;
+ }
+};
+std::ostream& operator<<(std::ostream& os, const StringIndex& index);
+
class TypeIndex {
public:
uint16_t index_;
- TypeIndex() : index_(std::numeric_limits<decltype(index_)>::max()) {}
- explicit TypeIndex(uint16_t idx) : index_(idx) {}
+ constexpr TypeIndex() : index_(std::numeric_limits<decltype(index_)>::max()) {}
+ explicit constexpr TypeIndex(uint16_t idx) : index_(idx) {}
bool IsValid() const {
return index_ != std::numeric_limits<decltype(index_)>::max();
@@ -63,6 +98,12 @@
namespace std {
+template<> struct hash<art::dex::StringIndex> {
+ size_t operator()(const art::dex::StringIndex& index) const {
+ return hash<uint32_t>()(index.index_);
+ }
+};
+
template<> struct hash<art::dex::TypeIndex> {
size_t operator()(const art::dex::TypeIndex& index) const {
return hash<uint16_t>()(index.index_);
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index ed50711..07f0fca 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -80,8 +80,8 @@
return true;
}
-const char* DexFileVerifier::CheckLoadStringByIdx(uint32_t idx, const char* error_string) {
- if (UNLIKELY(!CheckIndex(idx, dex_file_->NumStringIds(), error_string))) {
+const char* DexFileVerifier::CheckLoadStringByIdx(dex::StringIndex idx, const char* error_string) {
+ if (UNLIKELY(!CheckIndex(idx.index_, dex_file_->NumStringIds(), error_string))) {
return nullptr;
}
return dex_file_->StringDataByIdx(idx);
@@ -92,9 +92,7 @@
if (UNLIKELY(!CheckIndex(type_idx.index_, dex_file_->NumTypeIds(), error_string))) {
return nullptr;
}
- const DexFile::TypeId& type_id = dex_file_->GetTypeId(type_idx);
- uint32_t idx = type_id.descriptor_idx_;
- return CheckLoadStringByIdx(idx, error_string);
+ return CheckLoadStringByIdx(dex_file_->GetTypeId(type_idx).descriptor_idx_, error_string);
}
const DexFile::FieldId* DexFileVerifier::CheckLoadFieldId(uint32_t idx, const char* error_string) {
@@ -1782,7 +1780,8 @@
const DexFile::TypeId* prev_item = reinterpret_cast<const DexFile::TypeId*>(previous_item_);
if (UNLIKELY(prev_item->descriptor_idx_ >= item->descriptor_idx_)) {
ErrorStringPrintf("Out-of-order type_ids: %x then %x",
- prev_item->descriptor_idx_, item->descriptor_idx_);
+ prev_item->descriptor_idx_.index_,
+ item->descriptor_idx_.index_);
return false;
}
}
@@ -2500,14 +2499,15 @@
static std::string GetStringOrError(const uint8_t* const begin,
const DexFile::Header* const header,
- uint32_t string_idx) {
+ dex::StringIndex string_idx) {
// The `string_idx` is not guaranteed to be valid yet.
- if (header->string_ids_size_ <= string_idx) {
+ if (header->string_ids_size_ <= string_idx.index_) {
return "(error)";
}
const DexFile::StringId* string_id =
- reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_) + string_idx;
+ reinterpret_cast<const DexFile::StringId*>(begin + header->string_ids_off_)
+ + string_idx.index_;
// Assume that the data is OK at this point. String data has been checked at this point.
@@ -2664,7 +2664,7 @@
}
uint32_t string_idx =
(reinterpret_cast<const DexFile::MethodId*>(begin + header->method_ids_off_) +
- method_index)->name_idx_;
+ method_index)->name_idx_.index_;
if (string_idx >= header->string_ids_size_) {
*error_msg = "String index not available for method flags verification";
return false;
diff --git a/runtime/dex_file_verifier.h b/runtime/dex_file_verifier.h
index 19a89de..0327367 100644
--- a/runtime/dex_file_verifier.h
+++ b/runtime/dex_file_verifier.h
@@ -150,7 +150,7 @@
// Load a string by (type) index. Checks whether the index is in bounds, printing the error if
// not. If there is an error, null is returned.
- const char* CheckLoadStringByIdx(uint32_t idx, const char* error_fmt);
+ const char* CheckLoadStringByIdx(dex::StringIndex idx, const char* error_fmt);
const char* CheckLoadStringByTypeIdx(dex::TypeIndex type_idx, const char* error_fmt);
// Load a field/method Id by index. Checks whether the index is in bounds, printing the error if
diff --git a/runtime/dex_file_verifier_test.cc b/runtime/dex_file_verifier_test.cc
index 0e0929f..f14b1d5 100644
--- a/runtime/dex_file_verifier_test.cc
+++ b/runtime/dex_file_verifier_test.cc
@@ -176,7 +176,7 @@
"method_id_name_idx",
[](DexFile* dex_file) {
DexFile::MethodId* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(0));
- method_id->name_idx_ = 0xFF;
+ method_id->name_idx_ = dex::StringIndex(0xFF);
},
"String index not available for method flags verification");
}
@@ -247,7 +247,7 @@
while (it.HasNextDirectMethod() || it.HasNextVirtualMethod()) {
uint32_t method_index = it.GetMemberIndex();
- uint32_t name_index = dex_file->GetMethodId(method_index).name_idx_;
+ dex::StringIndex name_index = dex_file->GetMethodId(method_index).name_idx_;
const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
const char* str = dex_file->GetStringData(string_id);
if (strcmp(name, str) == 0) {
@@ -635,7 +635,7 @@
uint32_t method_idx;
FindMethodData(dex_file, "foo", &method_idx);
auto* method_id = const_cast<DexFile::MethodId*>(&dex_file->GetMethodId(method_idx));
- method_id->name_idx_ = dex_file->NumStringIds();
+ method_id->name_idx_ = dex::StringIndex(dex_file->NumStringIds());
},
"Method may have only one of public/protected/private, LMethodFlags;.(error)");
}
@@ -856,7 +856,7 @@
while (it.HasNextStaticField() || it.HasNextInstanceField()) {
uint32_t field_index = it.GetMemberIndex();
- uint32_t name_index = dex_file->GetFieldId(field_index).name_idx_;
+ dex::StringIndex name_index = dex_file->GetFieldId(field_index).name_idx_;
const DexFile::StringId& string_id = dex_file->GetStringId(name_index);
const char* str = dex_file->GetStringData(string_id);
if (strcmp(name, str) == 0) {
@@ -1451,12 +1451,12 @@
// Swap the proto parameters and shorties to break the ordering.
std::swap(const_cast<uint32_t&>(proto1.parameters_off_),
const_cast<uint32_t&>(proto2.parameters_off_));
- std::swap(const_cast<uint32_t&>(proto1.shorty_idx_),
- const_cast<uint32_t&>(proto2.shorty_idx_));
+ std::swap(const_cast<dex::StringIndex&>(proto1.shorty_idx_),
+ const_cast<dex::StringIndex&>(proto2.shorty_idx_));
} else {
// Copy the proto parameters and shorty to create duplicate proto id.
const_cast<uint32_t&>(proto1.parameters_off_) = proto2.parameters_off_;
- const_cast<uint32_t&>(proto1.shorty_idx_) = proto2.shorty_idx_;
+ const_cast<dex::StringIndex&>(proto1.shorty_idx_) = proto2.shorty_idx_;
}
},
"Out-of-order proto_id arguments");
diff --git a/runtime/dex_instruction.cc b/runtime/dex_instruction.cc
index 751bd51..9902389 100644
--- a/runtime/dex_instruction.cc
+++ b/runtime/dex_instruction.cc
@@ -191,10 +191,11 @@
if (file != nullptr) {
uint32_t string_idx = VRegB_21c();
if (string_idx < file->NumStringIds()) {
- os << StringPrintf("const-string v%d, %s // string@%d",
- VRegA_21c(),
- PrintableString(file->StringDataByIdx(string_idx)).c_str(),
- string_idx);
+ os << StringPrintf(
+ "const-string v%d, %s // string@%d",
+ VRegA_21c(),
+ PrintableString(file->StringDataByIdx(dex::StringIndex(string_idx))).c_str(),
+ string_idx);
} else {
os << StringPrintf("const-string v%d, <<invalid-string-idx-%d>> // string@%d",
VRegA_21c(),
@@ -333,11 +334,12 @@
uint32_t string_idx = VRegB_31c();
if (file != nullptr) {
if (string_idx < file->NumStringIds()) {
- os << StringPrintf("%s v%d, %s // string@%d",
- opcode,
- VRegA_31c(),
- PrintableString(file->StringDataByIdx(string_idx)).c_str(),
- string_idx);
+ os << StringPrintf(
+ "%s v%d, %s // string@%d",
+ opcode,
+ VRegA_31c(),
+ PrintableString(file->StringDataByIdx(dex::StringIndex(string_idx))).c_str(),
+ string_idx);
} else {
os << StringPrintf("%s v%d, <<invalid-string-idx-%d>> // string@%d",
opcode,
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index ac52f4e..f6eeffc 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -826,7 +826,7 @@
return h_class.Get();
}
-inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, uint32_t string_idx) {
+inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, dex::StringIndex string_idx) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
return class_linker->ResolveString(string_idx, referrer);
}
diff --git a/runtime/entrypoints/entrypoint_utils.h b/runtime/entrypoints/entrypoint_utils.h
index d87dc67..7cc136e 100644
--- a/runtime/entrypoints/entrypoint_utils.h
+++ b/runtime/entrypoints/entrypoint_utils.h
@@ -188,7 +188,7 @@
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
-inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, uint32_t string_idx)
+inline mirror::String* ResolveStringFromCode(ArtMethod* referrer, dex::StringIndex string_idx)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Roles::uninterruptible_);
diff --git a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
index b1259e1..5dad43e 100644
--- a/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_dexcache_entrypoints.cc
@@ -66,7 +66,7 @@
// TODO: Change art_quick_resolve_string on MIPS and MIPS64 to kSaveEverything.
(kRuntimeISA == kMips || kRuntimeISA == kMips64) ? Runtime::kSaveRefsOnly
: Runtime::kSaveEverything);
- mirror::String* result = ResolveStringFromCode(caller, string_idx);
+ mirror::String* result = ResolveStringFromCode(caller, dex::StringIndex(string_idx));
if (LIKELY(result != nullptr)) {
// For AOT code, we need a write barrier for the class loader that holds
// the GC roots in the .bss.
diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h
index 9c26d24..c9a5b44 100644
--- a/runtime/interpreter/interpreter_common.h
+++ b/runtime/interpreter/interpreter_common.h
@@ -236,7 +236,7 @@
// java.lang.String class is initialized.
static inline ObjPtr<mirror::String> ResolveString(Thread* self,
ShadowFrame& shadow_frame,
- uint32_t string_idx)
+ dex::StringIndex string_idx)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::Class> java_lang_string_class = mirror::String::GetJavaLangString();
if (UNLIKELY(!java_lang_string_class->IsInitialized())) {
@@ -251,11 +251,11 @@
ArtMethod* method = shadow_frame.GetMethod();
ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass();
// MethodVerifier refuses methods with string_idx out of bounds.
- DCHECK_LT(string_idx % mirror::DexCache::kDexCacheStringCacheSize,
+ DCHECK_LT(string_idx.index_ % mirror::DexCache::kDexCacheStringCacheSize,
declaring_class->GetDexFile().NumStringIds());
ObjPtr<mirror::String> string_ptr =
mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(),
- string_idx,
+ string_idx.index_,
mirror::DexCache::kDexCacheStringCacheSize).Read();
if (UNLIKELY(string_ptr == nullptr)) {
StackHandleScope<1> hs(self);
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 22c0fe0..52eacd5 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -373,7 +373,9 @@
break;
case Instruction::CONST_STRING: {
PREAMBLE();
- ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, inst->VRegB_21c());
+ ObjPtr<mirror::String> s = ResolveString(self,
+ shadow_frame,
+ dex::StringIndex(inst->VRegB_21c()));
if (UNLIKELY(s == nullptr)) {
HANDLE_PENDING_EXCEPTION();
} else {
@@ -384,7 +386,9 @@
}
case Instruction::CONST_STRING_JUMBO: {
PREAMBLE();
- ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, inst->VRegB_31c());
+ ObjPtr<mirror::String> s = ResolveString(self,
+ shadow_frame,
+ dex::StringIndex(inst->VRegB_31c()));
if (UNLIKELY(s == nullptr)) {
HANDLE_PENDING_EXCEPTION();
} else {
diff --git a/runtime/interpreter/mterp/mterp.cc b/runtime/interpreter/mterp/mterp.cc
index fbfed40..c8c1563 100644
--- a/runtime/interpreter/mterp/mterp.cc
+++ b/runtime/interpreter/mterp/mterp.cc
@@ -291,7 +291,7 @@
ShadowFrame* shadow_frame,
Thread* self)
REQUIRES_SHARED(Locks::mutator_lock_) {
- ObjPtr<mirror::String> s = ResolveString(self, *shadow_frame, index);
+ ObjPtr<mirror::String> s = ResolveString(self, *shadow_frame, dex::StringIndex(index));
if (UNLIKELY(s == nullptr)) {
return true;
}
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h
index d903f71..be8815a 100644
--- a/runtime/mirror/dex_cache-inl.h
+++ b/runtime/mirror/dex_cache-inl.h
@@ -40,13 +40,14 @@
return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size);
}
-inline mirror::String* DexCache::GetResolvedString(uint32_t string_idx) {
- DCHECK_LT(string_idx, GetDexFile()->NumStringIds());
- return StringDexCachePair::Lookup(GetStrings(), string_idx, NumStrings()).Read();
+inline mirror::String* DexCache::GetResolvedString(dex::StringIndex string_idx) {
+ DCHECK_LT(string_idx.index_, GetDexFile()->NumStringIds());
+ return StringDexCachePair::Lookup(GetStrings(), string_idx.index_, NumStrings()).Read();
}
-inline void DexCache::SetResolvedString(uint32_t string_idx, ObjPtr<mirror::String> resolved) {
- StringDexCachePair::Assign(GetStrings(), string_idx, resolved.Ptr(), NumStrings());
+inline void DexCache::SetResolvedString(dex::StringIndex string_idx,
+ ObjPtr<mirror::String> resolved) {
+ StringDexCachePair::Assign(GetStrings(), string_idx.index_, resolved.Ptr(), NumStrings());
Runtime* const runtime = Runtime::Current();
if (UNLIKELY(runtime->IsActiveTransaction())) {
DCHECK(runtime->IsAotCompiler());
@@ -56,12 +57,12 @@
runtime->GetHeap()->WriteBarrierEveryFieldOf(this);
}
-inline void DexCache::ClearString(uint32_t string_idx) {
- const uint32_t slot_idx = string_idx % NumStrings();
+inline void DexCache::ClearString(dex::StringIndex string_idx) {
+ const uint32_t slot_idx = string_idx.index_ % NumStrings();
DCHECK(Runtime::Current()->IsAotCompiler());
StringDexCacheType* slot = &GetStrings()[slot_idx];
// This is racy but should only be called from the transactional interpreter.
- if (slot->load(std::memory_order_relaxed).index == string_idx) {
+ if (slot->load(std::memory_order_relaxed).index == string_idx.index_) {
StringDexCachePair cleared(
nullptr,
StringDexCachePair::InvalidIndexForSlot(slot_idx));
diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h
index 7d82d3a..cc4d01a 100644
--- a/runtime/mirror/dex_cache.h
+++ b/runtime/mirror/dex_cache.h
@@ -214,15 +214,15 @@
return OFFSET_OF_OBJECT_MEMBER(DexCache, num_resolved_method_types_);
}
- mirror::String* GetResolvedString(uint32_t string_idx) ALWAYS_INLINE
+ mirror::String* GetResolvedString(dex::StringIndex string_idx) ALWAYS_INLINE
REQUIRES_SHARED(Locks::mutator_lock_);
- void SetResolvedString(uint32_t string_idx, ObjPtr<mirror::String> resolved) ALWAYS_INLINE
+ void SetResolvedString(dex::StringIndex string_idx, ObjPtr<mirror::String> resolved) ALWAYS_INLINE
REQUIRES_SHARED(Locks::mutator_lock_);
// Clear a string for a string_idx, used to undo string intern transactions to make sure
// the string isn't kept live.
- void ClearString(uint32_t string_idx) REQUIRES_SHARED(Locks::mutator_lock_);
+ void ClearString(dex::StringIndex string_idx) REQUIRES_SHARED(Locks::mutator_lock_);
Class* GetResolvedType(dex::TypeIndex type_idx) REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc
index 48feb11..3058df4 100644
--- a/runtime/native/dalvik_system_VMRuntime.cc
+++ b/runtime/native/dalvik_system_VMRuntime.cc
@@ -287,7 +287,7 @@
// Based on ClassLinker::ResolveString.
static void PreloadDexCachesResolveString(
- Handle<mirror::DexCache> dex_cache, uint32_t string_idx, StringTable& strings)
+ Handle<mirror::DexCache> dex_cache, dex::StringIndex string_idx, StringTable& strings)
REQUIRES_SHARED(Locks::mutator_lock_) {
ObjPtr<mirror::String> string = dex_cache->GetResolvedString(string_idx);
if (string != nullptr) {
@@ -450,7 +450,7 @@
continue;
}
for (size_t j = 0; j < dex_cache->NumStrings(); j++) {
- ObjPtr<mirror::String> string = dex_cache->GetResolvedString(j);
+ ObjPtr<mirror::String> string = dex_cache->GetResolvedString(dex::StringIndex(j));
if (string != nullptr) {
filled->num_strings++;
}
@@ -514,7 +514,7 @@
if (kPreloadDexCachesStrings) {
for (size_t j = 0; j < dex_cache->NumStrings(); j++) {
- PreloadDexCachesResolveString(dex_cache, j, strings);
+ PreloadDexCachesResolveString(dex_cache, dex::StringIndex(j), strings);
}
}
diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc
index f6de593..f1c350f 100644
--- a/runtime/native/java_lang_DexCache.cc
+++ b/runtime/native/java_lang_DexCache.cc
@@ -61,7 +61,8 @@
ScopedFastNativeObjectAccess soa(env);
ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache);
CHECK_LT(static_cast<size_t>(string_index), dex_cache->GetDexFile()->NumStringIds());
- return soa.AddLocalReference<jobject>(dex_cache->GetResolvedString(string_index));
+ return soa.AddLocalReference<jobject>(
+ dex_cache->GetResolvedString(dex::StringIndex(string_index)));
}
static void DexCache_setResolvedType(JNIEnv* env, jobject javaDexCache, jint type_index,
@@ -77,7 +78,7 @@
ScopedFastNativeObjectAccess soa(env);
ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache);
CHECK_LT(static_cast<size_t>(string_index), dex_cache->GetDexFile()->NumStringIds());
- dex_cache->SetResolvedString(string_index, soa.Decode<mirror::String>(string));
+ dex_cache->SetResolvedString(dex::StringIndex(string_index), soa.Decode<mirror::String>(string));
}
static JNINativeMethod gMethods[] = {
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index ee4d669..e46b253 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -2023,7 +2023,8 @@
preinitialization_transaction_->RecordWeakStringRemoval(s);
}
-void Runtime::RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, uint32_t string_idx) const {
+void Runtime::RecordResolveString(ObjPtr<mirror::DexCache> dex_cache,
+ dex::StringIndex string_idx) const {
DCHECK(IsAotCompiler());
DCHECK(IsActiveTransaction());
preinitialization_transaction_->RecordResolveString(dex_cache, string_idx);
diff --git a/runtime/runtime.h b/runtime/runtime.h
index de5a356..4f31887 100644
--- a/runtime/runtime.h
+++ b/runtime/runtime.h
@@ -28,6 +28,7 @@
#include "arch/instruction_set.h"
#include "base/macros.h"
+#include "dex_file_types.h"
#include "experimental_flags.h"
#include "gc_root.h"
#include "instrumentation.h"
@@ -520,7 +521,7 @@
REQUIRES(Locks::intern_table_lock_);
void RecordWeakStringRemoval(ObjPtr<mirror::String> s) const
REQUIRES(Locks::intern_table_lock_);
- void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, uint32_t string_idx) const
+ void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx) const
REQUIRES_SHARED(Locks::mutator_lock_);
void SetFaultMessage(const std::string& message) REQUIRES(!fault_message_lock_);
diff --git a/runtime/string_reference.h b/runtime/string_reference.h
index c75c218..0fc06e6 100644
--- a/runtime/string_reference.h
+++ b/runtime/string_reference.h
@@ -21,20 +21,22 @@
#include "base/logging.h"
#include "dex_file-inl.h"
+#include "dex_file_types.h"
#include "utf-inl.h"
namespace art {
// A string is located by its DexFile and the string_ids_ table index into that DexFile.
struct StringReference {
- StringReference(const DexFile* file, uint32_t index) : dex_file(file), string_index(index) { }
+ StringReference(const DexFile* file, dex::StringIndex index)
+ : dex_file(file), string_index(index) { }
const char* GetStringData() const {
return dex_file->GetStringData(dex_file->GetStringId(string_index));
}
const DexFile* dex_file;
- uint32_t string_index;
+ dex::StringIndex string_index;
};
// Compare only the reference and not the string contents.
diff --git a/runtime/transaction.cc b/runtime/transaction.cc
index c5da5d2..2536968 100644
--- a/runtime/transaction.cc
+++ b/runtime/transaction.cc
@@ -167,9 +167,10 @@
array_log.LogValue(index, value);
}
-void Transaction::RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, uint32_t string_idx) {
+void Transaction::RecordResolveString(ObjPtr<mirror::DexCache> dex_cache,
+ dex::StringIndex string_idx) {
DCHECK(dex_cache != nullptr);
- DCHECK_LT(string_idx, dex_cache->GetDexFile()->NumStringIds());
+ DCHECK_LT(string_idx.index_, dex_cache->GetDexFile()->NumStringIds());
MutexLock mu(Thread::Current(), log_lock_);
resolve_string_logs_.push_back(ResolveStringLog(dex_cache, string_idx));
}
@@ -510,11 +511,11 @@
}
Transaction::ResolveStringLog::ResolveStringLog(ObjPtr<mirror::DexCache> dex_cache,
- uint32_t string_idx)
+ dex::StringIndex string_idx)
: dex_cache_(dex_cache),
string_idx_(string_idx) {
DCHECK(dex_cache != nullptr);
- DCHECK_LT(string_idx_, dex_cache->GetDexFile()->NumStringIds());
+ DCHECK_LT(string_idx_.index_, dex_cache->GetDexFile()->NumStringIds());
}
void Transaction::ResolveStringLog::VisitRoots(RootVisitor* visitor) {
diff --git a/runtime/transaction.h b/runtime/transaction.h
index 2ec2f50..1774657 100644
--- a/runtime/transaction.h
+++ b/runtime/transaction.h
@@ -20,6 +20,7 @@
#include "base/macros.h"
#include "base/mutex.h"
#include "base/value_object.h"
+#include "dex_file_types.h"
#include "gc_root.h"
#include "object_callbacks.h"
#include "offsets.h"
@@ -97,7 +98,7 @@
REQUIRES(!log_lock_);
// Record resolve string.
- void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, uint32_t string_idx)
+ void RecordResolveString(ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!log_lock_);
@@ -197,7 +198,7 @@
class ResolveStringLog : public ValueObject {
public:
- ResolveStringLog(ObjPtr<mirror::DexCache> dex_cache, uint32_t string_idx);
+ ResolveStringLog(ObjPtr<mirror::DexCache> dex_cache, dex::StringIndex string_idx);
void Undo() REQUIRES_SHARED(Locks::mutator_lock_);
@@ -205,7 +206,7 @@
private:
GcRoot<mirror::DexCache> dex_cache_;
- const uint32_t string_idx_;
+ const dex::StringIndex string_idx_;
};
void LogInternedString(const InternStringLog& log)
diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc
index 77c2b76..a43c967 100644
--- a/runtime/transaction_test.cc
+++ b/runtime/transaction_test.cc
@@ -26,8 +26,6 @@
namespace art {
-static const size_t kDexNoIndex = DexFile::kDexNoIndex; // Make copy to prevent linking errors.
-
class TransactionTest : public CommonRuntimeTest {
public:
// Tests failing class initialization due to native call with transaction rollback.
@@ -507,8 +505,8 @@
static const char* kResolvedString = "ResolvedString";
const DexFile::StringId* string_id = dex_file->FindStringId(kResolvedString);
ASSERT_TRUE(string_id != nullptr);
- uint32_t string_idx = dex_file->GetIndexForStringId(*string_id);
- ASSERT_NE(string_idx, kDexNoIndex);
+ dex::StringIndex string_idx = dex_file->GetIndexForStringId(*string_id);
+ ASSERT_TRUE(string_idx.IsValid());
// String should only get resolved by the initializer.
EXPECT_TRUE(class_linker_->LookupString(*dex_file, string_idx, h_dex_cache) == nullptr);
EXPECT_TRUE(h_dex_cache->GetResolvedString(string_idx) == nullptr);
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index 01af5ec..f9bff23 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -80,8 +80,8 @@
}
}
-uint32_t VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
- ObjPtr<mirror::Class> klass) {
+dex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
+ ObjPtr<mirror::Class> klass) {
DCHECK(klass != nullptr);
ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
// Array and proxy classes do not have a dex cache.
@@ -104,9 +104,9 @@
}
// Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
-static uint32_t TryGetClassDescriptorStringId(const DexFile& dex_file,
- dex::TypeIndex type_idx,
- ObjPtr<mirror::Class> klass)
+static dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file,
+ dex::TypeIndex type_idx,
+ ObjPtr<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_) {
if (!klass->IsArrayClass()) {
const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
@@ -117,21 +117,21 @@
return type_id.descriptor_idx_;
}
}
- return DexFile::kDexNoIndex;
+ return dex::StringIndex::Invalid();
}
-uint32_t VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
- uint32_t dex_method_index,
- ArtMethod* method) {
+dex::StringIndex VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_method_index,
+ ArtMethod* method) {
static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
if (method == nullptr) {
- return VerifierDeps::kUnresolvedMarker;
+ return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
}
- const uint32_t string_id = TryGetClassDescriptorStringId(
+ const dex::StringIndex string_id = TryGetClassDescriptorStringId(
dex_file,
dex_file.GetMethodId(dex_method_index).class_idx_,
method->GetDeclaringClass());
- if (string_id != DexFile::kDexNoIndex) {
+ if (string_id.IsValid()) {
// Got lucky using the original dex file, return based on the input dex file.
DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
return string_id;
@@ -139,18 +139,18 @@
return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
}
-uint32_t VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
- uint32_t dex_field_idx,
- ArtField* field) {
+dex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_field_idx,
+ ArtField* field) {
static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
if (field == nullptr) {
- return VerifierDeps::kUnresolvedMarker;
+ return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
}
- const uint32_t string_id = TryGetClassDescriptorStringId(
+ const dex::StringIndex string_id = TryGetClassDescriptorStringId(
dex_file,
dex_file.GetFieldId(dex_field_idx).class_idx_,
field->GetDeclaringClass());
- if (string_id != DexFile::kDexNoIndex) {
+ if (string_id.IsValid()) {
// Got lucky using the original dex file, return based on the input dex file.
DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
return string_id;
@@ -190,7 +190,7 @@
return false;
}
-uint32_t VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
+dex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str());
if (string_id != nullptr) {
// String is in the DEX file. Return its ID.
@@ -212,32 +212,33 @@
{
ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
if (FindExistingStringId(deps->strings_, str, &found_id)) {
- return num_ids_in_dex + found_id;
+ return dex::StringIndex(num_ids_in_dex + found_id);
}
}
{
WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
if (FindExistingStringId(deps->strings_, str, &found_id)) {
- return num_ids_in_dex + found_id;
+ return dex::StringIndex(num_ids_in_dex + found_id);
}
deps->strings_.push_back(str);
- uint32_t new_id = num_ids_in_dex + deps->strings_.size() - 1;
- CHECK_GE(new_id, num_ids_in_dex); // check for overflows
+ dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1);
+ CHECK_GE(new_id.index_, num_ids_in_dex); // check for overflows
DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
return new_id;
}
}
-std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, uint32_t string_id) const {
+std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id)
+ const {
uint32_t num_ids_in_dex = dex_file.NumStringIds();
- if (string_id < num_ids_in_dex) {
+ if (string_id.index_ < num_ids_in_dex) {
return std::string(dex_file.StringDataByIdx(string_id));
} else {
const DexFileDeps* deps = GetDexFileDeps(dex_file);
DCHECK(deps != nullptr);
- string_id -= num_ids_in_dex;
- CHECK_LT(string_id, deps->strings_.size());
- return deps->strings_[string_id];
+ string_id.index_ -= num_ids_in_dex;
+ CHECK_LT(string_id.index_, deps->strings_.size());
+ return deps->strings_[string_id.index_];
}
}
@@ -389,8 +390,8 @@
}
// Get string IDs for both descriptors and store in the appropriate set.
- uint32_t destination_id = GetClassDescriptorStringId(dex_file, destination);
- uint32_t source_id = GetClassDescriptorStringId(dex_file, source);
+ dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
+ dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
if (is_assignable) {
dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
@@ -471,6 +472,9 @@
template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
return in.index_;
}
+template<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) {
+ return in.index_;
+}
template<typename T> inline T Decode(uint32_t in);
@@ -483,6 +487,9 @@
template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
return dex::TypeIndex(in);
}
+template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
+ return dex::StringIndex(in);
+}
template<typename T1, typename T2>
static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
@@ -508,7 +515,7 @@
static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
- T3 v3 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
+ T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end));
*t = std::make_tuple(v1, v2, v3);
}
diff --git a/runtime/verifier/verifier_deps.h b/runtime/verifier/verifier_deps.h
index a12071b..4b8206f 100644
--- a/runtime/verifier/verifier_deps.h
+++ b/runtime/verifier/verifier_deps.h
@@ -129,41 +129,43 @@
uint16_t GetAccessFlags() const { return std::get<1>(*this); }
};
- using FieldResolutionBase = std::tuple<uint32_t, uint16_t, uint32_t>;
+ using FieldResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>;
struct FieldResolution : public FieldResolutionBase {
FieldResolution() = default;
FieldResolution(const FieldResolution&) = default;
- FieldResolution(uint32_t field_idx, uint16_t access_flags, uint32_t declaring_class_idx)
+ FieldResolution(uint32_t field_idx, uint16_t access_flags, dex::StringIndex declaring_class_idx)
: FieldResolutionBase(field_idx, access_flags, declaring_class_idx) {}
bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
uint32_t GetDexFieldIndex() const { return std::get<0>(*this); }
uint16_t GetAccessFlags() const { return std::get<1>(*this); }
- uint32_t GetDeclaringClassIndex() const { return std::get<2>(*this); }
+ dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); }
};
- using MethodResolutionBase = std::tuple<uint32_t, uint16_t, uint32_t>;
+ using MethodResolutionBase = std::tuple<uint32_t, uint16_t, dex::StringIndex>;
struct MethodResolution : public MethodResolutionBase {
MethodResolution() = default;
MethodResolution(const MethodResolution&) = default;
- MethodResolution(uint32_t method_idx, uint16_t access_flags, uint32_t declaring_class_idx)
+ MethodResolution(uint32_t method_idx,
+ uint16_t access_flags,
+ dex::StringIndex declaring_class_idx)
: MethodResolutionBase(method_idx, access_flags, declaring_class_idx) {}
bool IsResolved() const { return GetAccessFlags() != kUnresolvedMarker; }
uint32_t GetDexMethodIndex() const { return std::get<0>(*this); }
uint16_t GetAccessFlags() const { return std::get<1>(*this); }
- uint32_t GetDeclaringClassIndex() const { return std::get<2>(*this); }
+ dex::StringIndex GetDeclaringClassIndex() const { return std::get<2>(*this); }
};
- using TypeAssignabilityBase = std::tuple<uint32_t, uint32_t>;
+ using TypeAssignabilityBase = std::tuple<dex::StringIndex, dex::StringIndex>;
struct TypeAssignability : public TypeAssignabilityBase {
TypeAssignability() = default;
TypeAssignability(const TypeAssignability&) = default;
- TypeAssignability(uint32_t destination_idx, uint32_t source_idx)
+ TypeAssignability(dex::StringIndex destination_idx, dex::StringIndex source_idx)
: TypeAssignabilityBase(destination_idx, source_idx) {}
- uint32_t GetDestination() const { return std::get<0>(*this); }
- uint32_t GetSource() const { return std::get<1>(*this); }
+ dex::StringIndex GetDestination() const { return std::get<0>(*this); }
+ dex::StringIndex GetSource() const { return std::get<1>(*this); }
};
// Data structure representing dependencies collected during verification of
@@ -206,11 +208,11 @@
// string ID. If not, an ID is assigned to the string and cached in `strings_`
// of the corresponding DexFileDeps structure (either provided or inferred from
// `dex_file`).
- uint32_t GetIdFromString(const DexFile& dex_file, const std::string& str)
+ dex::StringIndex GetIdFromString(const DexFile& dex_file, const std::string& str)
REQUIRES(!Locks::verifier_deps_lock_);
// Returns the string represented by `id`.
- std::string GetStringFromId(const DexFile& dex_file, uint32_t string_id) const;
+ std::string GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id) const;
// Returns the bytecode access flags of `element` (bottom 16 bits), or
// `kUnresolvedMarker` if `element` is null.
@@ -220,17 +222,17 @@
// Returns a string ID of the descriptor of the declaring class of `element`,
// or `kUnresolvedMarker` if `element` is null.
- uint32_t GetMethodDeclaringClassStringId(const DexFile& dex_file,
- uint32_t dex_method_idx,
- ArtMethod* method)
+ dex::StringIndex GetMethodDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_method_idx,
+ ArtMethod* method)
REQUIRES_SHARED(Locks::mutator_lock_);
- uint32_t GetFieldDeclaringClassStringId(const DexFile& dex_file,
- uint32_t dex_field_idx,
- ArtField* field)
+ dex::StringIndex GetFieldDeclaringClassStringId(const DexFile& dex_file,
+ uint32_t dex_field_idx,
+ ArtField* field)
REQUIRES_SHARED(Locks::mutator_lock_);
// Returns a string ID of the descriptor of the class.
- uint32_t GetClassDescriptorStringId(const DexFile& dex_file, ObjPtr<mirror::Class> klass)
+ dex::StringIndex GetClassDescriptorStringId(const DexFile& dex_file, ObjPtr<mirror::Class> klass)
REQUIRES_SHARED(Locks::mutator_lock_)
REQUIRES(!Locks::verifier_deps_lock_);