Create templates for primitive types.
In preparation to move static fields into their own array
members off of class.
Change-Id: Ic524e12952af985d8ae16a05b5f4e50676a9c136
diff --git a/src/class_linker.cc b/src/class_linker.cc
index e1dcbf8..89c96b4 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -464,7 +464,7 @@
Field* dst) {
const DexFile::FieldId& field_id = dex_file.GetFieldId(src.field_idx_);
dst->klass_ = klass;
- dst->java_name_ = ResolveString(klass, field_id.name_idx_, dex_file);
+ dst->name_ = ResolveString(klass, field_id.name_idx_, dex_file);
dst->descriptor_.set(dex_file.dexStringByTypeIdx(field_id.type_idx_));
dst->access_flags_ = src.access_flags_;
}
@@ -475,7 +475,7 @@
Method* dst) {
const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
dst->klass_ = klass;
- dst->java_name_ = ResolveString(klass, method_id.name_idx_, dex_file);
+ dst->name_ = ResolveString(klass, method_id.name_idx_, dex_file);
{
int32_t utf16_length;
scoped_ptr<char> utf8(dex_file.CreateMethodDescriptor(method_id.proto_idx_,
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 5951c0b..5e48921 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -143,11 +143,13 @@
for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
InstanceField* field = klass->GetInstanceField(i);
EXPECT_TRUE(field != NULL);
+ EXPECT_FALSE(field->IsStatic());
}
for (size_t i = 0; i < klass->NumStaticFields(); i++) {
StaticField* field = klass->GetStaticField(i);
EXPECT_TRUE(field != NULL);
+ EXPECT_TRUE(field->IsStatic());
}
// Confirm that all instances fields are packed together at the start
@@ -368,4 +370,4 @@
EXPECT_NE(MyClass_1, MyClass_2);
}
-} // namespace art
+}// namespace art
diff --git a/src/object.h b/src/object.h
index 33db15e..6871dfb 100644
--- a/src/object.h
+++ b/src/object.h
@@ -25,7 +25,11 @@
class Object;
class String;
template<class T> class ObjectArray;
+template<class T> class PrimitiveArray;
class StaticField;
+typedef PrimitiveArray<uint16_t> CharArray;
+typedef PrimitiveArray<uint32_t> IntArray;
+typedef PrimitiveArray<uint64_t> LongArray;
union JValue {
uint8_t z;
@@ -258,7 +262,11 @@
}
const String* GetName() const {
- return java_name_;
+ return name_;
+ }
+
+ bool IsStatic() const {
+ return (access_flags_ & kAccStatic) != 0;
}
char GetType() const { // TODO: return type
@@ -275,15 +283,13 @@
Class* java_declaring_class_;
Object* java_generic_type_;
uint32_t java_generic_types_are_initialized_;
- String* java_name_;
+ String* name_;
uint32_t java_slot_;
Class* java_type_;
// The class in which this field is declared.
Class* declaring_class_;
- StringPiece name_;
-
// e.g. "I", "[C", "Landroid/os/Debug;"
StringPiece descriptor_;
@@ -380,7 +386,7 @@
public:
// Returns the method name, e.g. "<init>" or "eatLunch"
const String* GetName() const {
- return java_name_;
+ return name_;
}
const String* GetDescriptor() const {
@@ -447,7 +453,7 @@
Object* java_generic_parameter_types_;
Object* java_generic_return_type_;
Class* java_return_type_;
- String* java_name_;
+ String* name_;
ObjectArray<Class>* java_parameter_types_;
uint32_t java_generic_types_are_initialized_;
uint32_t java_slot_;
@@ -544,9 +550,6 @@
uint16_t num_outs_;
uint16_t num_ins_;
- // method name, e.g. "<init>" or "eatLunch"
- StringPiece name_;
-
// The method descriptor. This represents the parameters a method
// takes and value it returns. This string is a list of the type
// descriptors for the parameters enclosed in parenthesis followed
@@ -596,18 +599,10 @@
void SetLength(uint32_t length) {
length_ = length;
}
- const void* GetData() const {
- return &elements_;
- }
- void* GetData() {
- return &elements_;
- }
private:
// The number of array elements.
uint32_t length_;
- // Location of first element.
- uint32_t elements_[0];
Array();
};
@@ -621,15 +616,19 @@
sizeof(uint32_t)));
}
+ T* const * GetData() const {
+ return reinterpret_cast<T* const *>(&elements_);
+ }
+ T** GetData() {
+ return reinterpret_cast<T**>(&elements_);
+ }
T* Get(uint32_t i) const {
CHECK_LT(i, GetLength());
- Object* const * data = reinterpret_cast<Object* const *>(GetData());
- return down_cast<T*>(data[i]);
+ return GetData()[i];
}
void Set(uint32_t i, T* object) {
CHECK_LT(i, GetLength());
- T** data = reinterpret_cast<T**>(GetData());
- data[i] = object;
+ GetData()[i] = object;
}
static void Copy(ObjectArray<T>* src, int src_pos, ObjectArray<T>* dst, int dst_pos, size_t length) {
for (size_t i = 0; i < length; i++) {
@@ -644,6 +643,8 @@
private:
ObjectArray();
+ // Location of first element.
+ T* elements_[0];
};
// ClassLoader objects.
@@ -1055,6 +1056,10 @@
// source file name, if known. Otherwise, NULL.
const char* source_file_;
+ ObjectArray<Object>* static_references_;
+ IntArray* static_32bit_primitives_;
+ LongArray* static_64bit_primitives_;
+
// Static fields
ObjectArray<StaticField>* sfields_;
@@ -1075,34 +1080,37 @@
DataObject();
};
-class CharArray : public Array {
+template<class T>
+class PrimitiveArray : public Array {
public:
- static CharArray* Alloc(Class* char_array_class, size_t length) {
- return down_cast<CharArray*>(Array::Alloc(char_array_class,
- length,
- sizeof(uint16_t)));
+ static PrimitiveArray<T>* Alloc(Class* element_class, size_t length) {
+ return down_cast<PrimitiveArray<T>*>(Array::Alloc(element_class,
+ length,
+ sizeof(T)));
}
- uint16_t* GetChars() {
- return reinterpret_cast<uint16_t*>(GetData());
+ const T* GetData() const {
+ return reinterpret_cast<const T*>(&elements_);
}
- const uint16_t* GetChars() const {
- return reinterpret_cast<const uint16_t*>(GetData());
+ T* GetData() {
+ return reinterpret_cast<T*>(&elements_);
}
- uint16_t GetChar(uint32_t i) const {
+ T Get(T i) const {
CHECK_LT(i, GetLength());
- return GetChars()[i];
+ return GetData()[i];
}
- void SetChar(uint32_t i, uint16_t ch) {
+ void Set(uint32_t i, T value) {
CHECK_LT(i, GetLength());
- GetChars()[i] = ch;
+ GetData()[i] = value;
}
private:
- CharArray();
+ PrimitiveArray();
+ // Location of first element.
+ T elements_[0];
};
class String : public Object {
@@ -1126,19 +1134,18 @@
}
uint16_t CharAt(int32_t index) const {
- return GetCharArray()->GetChar(index + GetOffset());
+ return GetCharArray()->Get(index + GetOffset());
}
static String* AllocFromUtf16(int32_t utf16_length,
uint16_t* utf16_data_in,
int32_t hash_code) {
String* string = Alloc(GetJavaLangString(), GetCharArrayClass(), utf16_length);
- uint16_t* utf16_data_out = string->array_->GetChars();
// TODO use 16-bit wide memset variant
for (int i = 0; i < utf16_length; i++ ) {
- utf16_data_out[i] = utf16_data_in[i];
+ string->array_->Set(i, utf16_data_in[i]);
}
- string->hash_code_ = hash_code;
+ string->ComputeHashCode();
return string;
}
@@ -1147,9 +1154,9 @@
int32_t utf16_length,
const char* utf8_data_in) {
String* string = Alloc(java_lang_String, char_array, utf16_length);
- uint16_t* utf16_data_out = string->array_->GetChars();
+ uint16_t* utf16_data_out = string->array_->GetData();
ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
- string->hash_code_ = ComputeUtf16Hash(utf16_data_out, utf16_length);
+ string->ComputeHashCode();
return string;
}
@@ -1248,7 +1255,6 @@
return len;
}
-
// The java/lang/String.computeHashCode() algorithm
static int32_t ComputeUtf16Hash(const uint16_t* string_data, size_t string_length) {
int32_t hash = 0;
@@ -1258,6 +1264,10 @@
return hash;
}
+ void ComputeHashCode() {
+ hash_code_ = ComputeUtf16Hash(array_->GetData(), count_);
+ }
+
bool Equals(const char* modified_utf8) const {
for (int32_t i = 0; i < GetLength(); ++i) {
uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
diff --git a/src/object_test.cc b/src/object_test.cc
index 2d32ad0..e5bdd35 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -30,11 +30,11 @@
String* string = String::AllocFromModifiedUtf8(length, utf8_in);
ASSERT_EQ(length, string->GetLength());
ASSERT_TRUE(string->GetCharArray() != NULL);
- ASSERT_TRUE(string->GetCharArray()->GetChars() != NULL);
+ ASSERT_TRUE(string->GetCharArray()->GetData() != NULL);
// strlen is necessary because the 1-character string "\0" is interpreted as ""
ASSERT_TRUE(string->Equals(utf8_in) || length != static_cast<int32_t>(strlen(utf8_in)));
for (int32_t i = 0; i < length; i++) {
- EXPECT_EQ(utf16_expected[i], string->GetCharArray()->GetChar(i));
+ EXPECT_EQ(utf16_expected[i], string->CharAt(i));
}
EXPECT_EQ(hash_expected, string->GetHashCode());
}
@@ -162,4 +162,11 @@
EXPECT_TRUE(m4_2->HasSameNameAndDescriptor(m4_1));
}
+
+TEST_F(ObjectTest, StringHashCode) {
+ EXPECT_EQ(0, String::AllocFromAscii("")->GetHashCode());
+ EXPECT_EQ(65, String::AllocFromAscii("A")->GetHashCode());
+ EXPECT_EQ(64578, String::AllocFromAscii("ABC")->GetHashCode());
+}
+
} // namespace art