From 3aaa37bba53d6df0265793de48b4b0b57327e57a Mon Sep 17 00:00:00 2001 From: jessicahandojo Date: Fri, 29 Jul 2016 14:46:37 -0700 Subject: creating workflow for mirror::String compression All-ASCII String characters are stored in 8-bit blocks instead of 16-bit. The compression has not taken place, but all workflow are in the code already (changing kUseStringCompression in string.h file to TRUE will enable the feature) Notes: Feature works on interpreter only without optimizing Test art: m ART_TEST_INTERPRETER=true ART_TEST_OPTIMIZING=false test-art-host Also tested with String tests from libcore/: 1. libcore.java.lang.StringTest 2. libcore.java.lang.StringBufferTest 3. libcore.java.lang.StringBuilderTest 4. libcore.java.lang.OldStringTest 5. libcore.java.lang.OldStringBufferTest Memory improvement is 33% (from 6.03% to 4.03%, total String memory from all apps per total memory of all apps) measured on Angler with Hprof tools Bug: 31040547 Change-Id: I9cc92c265ebf1305fc06b5fc33efd83797660cce --- runtime/native/java_lang_Class.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'runtime/native/java_lang_Class.cc') diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index 6d5e7c7705..d4e54cfa34 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -198,12 +198,25 @@ ALWAYS_INLINE static inline ArtField* FindFieldByName( } size_t low = 0; size_t high = fields->size(); - const uint16_t* const data = name->GetValue(); + const bool is_name_compressed = name->IsCompressed(); + const uint16_t* const data = (is_name_compressed) ? nullptr : name->GetValue(); + const uint8_t* const data_compressed = (is_name_compressed) ? name->GetValueCompressed() + : nullptr; const size_t length = name->GetLength(); while (low < high) { auto mid = (low + high) / 2; ArtField& field = fields->At(mid); - int result = CompareModifiedUtf8ToUtf16AsCodePointValues(field.GetName(), data, length); + int result = 0; + if (is_name_compressed) { + size_t field_length = strlen(field.GetName()); + size_t min_size = (length < field_length) ? length : field_length; + result = memcmp(field.GetName(), data_compressed, min_size); + if (result == 0) { + result = field_length - length; + } + } else { + result = CompareModifiedUtf8ToUtf16AsCodePointValues(field.GetName(), data, length); + } // Alternate approach, only a few % faster at the cost of more allocations. // int result = field->GetStringName(self, true)->CompareTo(name); if (result < 0) { @@ -636,8 +649,7 @@ static jobject Class_newInstance(JNIEnv* env, jobject javaThis) { // Invoke the string allocator to return an empty string for the string class. if (klass->IsStringClass()) { gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); - mirror::SetStringCountVisitor visitor(0); - mirror::Object* obj = mirror::String::Alloc(soa.Self(), 0, allocator_type, visitor); + mirror::Object* obj = mirror::String::AllocEmptyString(soa.Self(), allocator_type); if (UNLIKELY(soa.Self()->IsExceptionPending())) { return nullptr; } else { -- cgit v1.2.3-59-g8ed1b