diff options
author | Jeff Hao <jeffhao@google.com> | 2014-01-15 13:49:50 -0800 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2015-04-27 18:54:52 -0700 |
commit | 848f70a3d73833fc1bf3032a9ff6812e429661d9 (patch) | |
tree | b0349b3a40aab5a915af491b100659a5ca9fbbf6 /compiler/image_writer.cc | |
parent | d14438f0c5071962be7fab572b54687d32d9d087 (diff) | |
download | art-848f70a3d73833fc1bf3032a9ff6812e429661d9.zip art-848f70a3d73833fc1bf3032a9ff6812e429661d9.tar.gz art-848f70a3d73833fc1bf3032a9ff6812e429661d9.tar.bz2 |
Replace String CharArray with internal uint16_t array.
Summary of high level changes:
- Adds compiler inliner support to identify string init methods
- Adds compiler support (quick & optimizing) with new invoke code path
that calls method off the thread pointer
- Adds thread entrypoints for all string init methods
- Adds map to verifier to log when receiver of string init has been
copied to other registers. used by compiler and interpreter
Change-Id: I797b992a8feb566f9ad73060011ab6f51eb7ce01
Diffstat (limited to 'compiler/image_writer.cc')
-rw-r--r-- | compiler/image_writer.cc | 101 |
1 files changed, 9 insertions, 92 deletions
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index fc70d8f..4dc7509 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -89,7 +89,12 @@ bool ImageWriter::PrepareImageAddressSpace() { Thread::Current()->TransitionFromSuspendedToRunnable(); PruneNonImageClasses(); // Remove junk ComputeLazyFieldsForImageClasses(); // Add useful information - ProcessStrings(); + + // Calling this can in theory fill in some resolved strings. However, in practice it seems to + // never resolve any. + if (kComputeEagerResolvedStrings) { + ComputeEagerResolvedStrings(); + } Thread::Current()->TransitionFromRunnableToSuspended(kNative); } gc::Heap* heap = Runtime::Current()->GetHeap(); @@ -529,14 +534,6 @@ bool ImageWriter::ComputeLazyFieldsForClassesVisitor(Class* c, void* /*arg*/) { return true; } -// Count the number of strings in the heap and put the result in arg as a size_t pointer. -static void CountStringsCallback(Object* obj, void* arg) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - if (obj->GetClass()->IsStringClass()) { - ++*reinterpret_cast<size_t*>(arg); - } -} - // Collect all the java.lang.String in the heap and put them in the output strings_ array. class StringCollector { public: @@ -566,99 +563,19 @@ class LexicographicalStringComparator { SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { mirror::String* lhs_s = lhs.AsMirrorPtr(); mirror::String* rhs_s = rhs.AsMirrorPtr(); - uint16_t* lhs_begin = lhs_s->GetCharArray()->GetData() + lhs_s->GetOffset(); - uint16_t* rhs_begin = rhs_s->GetCharArray()->GetData() + rhs_s->GetOffset(); + uint16_t* lhs_begin = lhs_s->GetValue(); + uint16_t* rhs_begin = rhs_s->GetValue(); return std::lexicographical_compare(lhs_begin, lhs_begin + lhs_s->GetLength(), rhs_begin, rhs_begin + rhs_s->GetLength()); } }; -static bool IsPrefix(mirror::String* pref, mirror::String* full) - SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - if (pref->GetLength() > full->GetLength()) { - return false; - } - uint16_t* pref_begin = pref->GetCharArray()->GetData() + pref->GetOffset(); - uint16_t* full_begin = full->GetCharArray()->GetData() + full->GetOffset(); - return std::equal(pref_begin, pref_begin + pref->GetLength(), full_begin); -} - -void ImageWriter::ProcessStrings() { - size_t total_strings = 0; - gc::Heap* heap = Runtime::Current()->GetHeap(); - ClassLinker* cl = Runtime::Current()->GetClassLinker(); - // Count the strings. - heap->VisitObjects(CountStringsCallback, &total_strings); - Thread* self = Thread::Current(); - StackHandleScope<1> hs(self); - auto strings = hs.NewHandle(cl->AllocStringArray(self, total_strings)); - StringCollector string_collector(strings, 0U); - // Read strings into the array. - heap->VisitObjects(StringCollector::Callback, &string_collector); - // Some strings could have gotten freed if AllocStringArray caused a GC. - CHECK_LE(string_collector.GetIndex(), total_strings); - total_strings = string_collector.GetIndex(); - auto* strings_begin = reinterpret_cast<mirror::HeapReference<mirror::String>*>( - strings->GetRawData(sizeof(mirror::HeapReference<mirror::String>), 0)); - std::sort(strings_begin, strings_begin + total_strings, LexicographicalStringComparator()); - // Characters of strings which are non equal prefix of another string (not the same string). - // We don't count the savings from equal strings since these would get interned later anyways. - size_t prefix_saved_chars = 0; - // Count characters needed for the strings. - size_t num_chars = 0u; - mirror::String* prev_s = nullptr; - for (size_t idx = 0; idx != total_strings; ++idx) { - mirror::String* s = strings->GetWithoutChecks(idx); - size_t length = s->GetLength(); - num_chars += length; - if (prev_s != nullptr && IsPrefix(prev_s, s)) { - size_t prev_length = prev_s->GetLength(); - num_chars -= prev_length; - if (prev_length != length) { - prefix_saved_chars += prev_length; - } - } - prev_s = s; - } - // Create character array, copy characters and point the strings there. - mirror::CharArray* array = mirror::CharArray::Alloc(self, num_chars); - string_data_array_ = array; - uint16_t* array_data = array->GetData(); - size_t pos = 0u; - prev_s = nullptr; - for (size_t idx = 0; idx != total_strings; ++idx) { - mirror::String* s = strings->GetWithoutChecks(idx); - uint16_t* s_data = s->GetCharArray()->GetData() + s->GetOffset(); - int32_t s_length = s->GetLength(); - int32_t prefix_length = 0u; - if (idx != 0u && IsPrefix(prev_s, s)) { - prefix_length = prev_s->GetLength(); - } - memcpy(array_data + pos, s_data + prefix_length, (s_length - prefix_length) * sizeof(*s_data)); - s->SetOffset(pos - prefix_length); - s->SetArray(array); - pos += s_length - prefix_length; - prev_s = s; - } - CHECK_EQ(pos, num_chars); - - if (kIsDebugBuild || VLOG_IS_ON(compiler)) { - LOG(INFO) << "Total # image strings=" << total_strings << " combined length=" - << num_chars << " prefix saved chars=" << prefix_saved_chars; - } - // Calling this can in theory fill in some resolved strings. However, in practice it seems to - // never resolve any. - if (kComputeEagerResolvedStrings) { - ComputeEagerResolvedStrings(); - } -} - void ImageWriter::ComputeEagerResolvedStringsCallback(Object* obj, void* arg ATTRIBUTE_UNUSED) { if (!obj->GetClass()->IsStringClass()) { return; } mirror::String* string = obj->AsString(); - const uint16_t* utf16_string = string->GetCharArray()->GetData() + string->GetOffset(); + const uint16_t* utf16_string = string->GetValue(); size_t utf16_length = static_cast<size_t>(string->GetLength()); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); ReaderMutexLock mu(Thread::Current(), *class_linker->DexLock()); |