Get ClassLinker out of the business of allocating strings.
String is now the only place we allocate strings. This requires
a bit of finesse in order to make char[] available early during
bootstrap.
Change-Id: I494a2b0691b58fdafc96513c1e697a88d437c805
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 3e1eb06..09454d8 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -49,10 +49,12 @@
Class* object_array_class = AllocClass(java_lang_Class);
CHECK(object_array_class != NULL);
- // string is necessary so that FindClass can assigning names to members
+ // string and char[] are necessary so that FindClass can assign names to members
Class* java_lang_String = AllocClass(java_lang_Class);
CHECK(java_lang_String != NULL);
java_lang_String->object_size_ = sizeof(String);
+ Class* char_array_class = AllocClass(java_lang_Class);
+ CHECK(char_array_class != NULL);
// create storage for root classes, save away our work so far
class_roots_ = ObjectArray<Class>::Alloc(object_array_class, kClassRootsMax);
@@ -60,8 +62,12 @@
class_roots_->Set(kJavaLangObject, java_lang_Object);
class_roots_->Set(kObjectArrayClass, object_array_class);
class_roots_->Set(kJavaLangString, java_lang_String);
+ class_roots_->Set(kCharArrayClass, char_array_class);
// now that these are registered, we can use AllocClass() and AllocObjectArray
+ String::InitClasses(java_lang_String, char_array_class);
+ // Now AllocString* can be used
+
// setup boot_class_path_ now that we can use AllocObjectArray to
// DexCache instances
for (size_t i = 0; i != boot_class_path.size(); ++i) {
@@ -127,8 +133,8 @@
// now FindClass can be used for non-primitive array classes
// run Object[] through FindClass to complete initialization
- Class* Object_array_class = FindSystemClass("[Ljava/lang/Object;");
- CHECK_EQ(object_array_class, Object_array_class);
+ Class* found_object_array_class = FindSystemClass("[Ljava/lang/Object;");
+ CHECK_EQ(object_array_class, found_object_array_class);
// Setup the primitive type classes.
class_roots_->Set(kPrimitiveByte, CreatePrimitiveClass("B"));
@@ -142,10 +148,9 @@
class_roots_->Set(kPrimitiveVoid, CreatePrimitiveClass("V"));
// now we can use FindSystemClass for anything, including for "[C"
- Class* char_array = FindSystemClass("[C");
- class_roots_->Set(kCharArrayClass, char_array);
- String::InitClasses(java_lang_String, char_array);
- // Now AllocString* can be used
+ // run char[] through FindClass to complete initialization
+ Class* found_char_array_class = FindSystemClass("[C");
+ CHECK_EQ(char_array_class, found_char_array_class);
// ensure all class_roots_ were initialized
for (size_t i = 0; i < kClassRootsMax; i++) {
@@ -201,14 +206,6 @@
sizeof(Method)));
}
-String* ClassLinker::AllocStringFromModifiedUtf8(int32_t utf16_length,
- const char* utf8_data_in) {
- return String::AllocFromModifiedUtf8(class_roots_->Get(kJavaLangString),
- class_roots_->Get(kCharArrayClass),
- utf16_length,
- utf8_data_in);
-}
-
Class* ClassLinker::FindClass(const StringPiece& descriptor,
Object* class_loader,
const DexFile* dex_file) {
@@ -600,9 +597,14 @@
// link step.
Class* new_class = NULL;
- if (!init_done_ && descriptor == "[Ljava/lang/Object;") {
+ if (!init_done_) {
+ if (descriptor == "[Ljava/lang/Object;") {
new_class = class_roots_->Get(kObjectArrayClass);
CHECK(new_class);
+ } else if (descriptor == "[C") {
+ new_class = class_roots_->Get(kCharArrayClass);
+ CHECK(new_class);
+ }
}
if (new_class == NULL) {
new_class = AllocClass();
@@ -1546,7 +1548,7 @@
const DexFile::StringId& string_id = dex_file->GetStringId(string_idx);
int32_t utf16_length = dex_file->GetStringLength(string_id);
const char* utf8_data = dex_file->GetStringData(string_id);
- String* new_string = AllocStringFromModifiedUtf8(utf16_length, utf8_data);
+ String* new_string = String::AllocFromModifiedUtf8(utf16_length, utf8_data);
// TODO: intern the new string
referring->GetDexCache()->SetResolvedString(string_idx, new_string);
return new_string;
diff --git a/src/class_linker.h b/src/class_linker.h
index 9f5df47..a4a9b2e 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -65,7 +65,6 @@
StaticField* AllocStaticField();
InstanceField* AllocInstanceField();
Method* AllocMethod();
- String* AllocStringFromModifiedUtf8(int32_t utf16_length, const char* utf8_data_in);
template <class T>
ObjectArray<T>* AllocObjectArray(size_t length) {
return ObjectArray<T>::Alloc(class_roots_->Get(kObjectArrayClass), length);
diff --git a/src/object.h b/src/object.h
index 0063f58..7eede5d 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1065,6 +1065,11 @@
ascii_data_in);
}
+ static String* AllocFromModifiedUtf8(int32_t utf16_length,
+ const char* utf8_data_in) {
+ return AllocFromModifiedUtf8(java_lang_String_, char_array_, utf16_length, utf8_data_in);
+ }
+
public: // TODO: private
// Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
CharArray* array_;
diff --git a/src/object_test.cc b/src/object_test.cc
index 46e9cca..d240d0c 100644
--- a/src/object_test.cc
+++ b/src/object_test.cc
@@ -27,7 +27,7 @@
utf16_expected[i] = ch;
}
- String* string = class_linker_->AllocStringFromModifiedUtf8(length, utf8_in);
+ String* string = String::AllocFromModifiedUtf8(length, utf8_in);
ASSERT_EQ(length, static_cast<size_t>(string->count_));
ASSERT_TRUE(string->array_ != NULL);
ASSERT_TRUE(string->array_->GetChars() != NULL);