diff options
| -rw-r--r-- | runtime/interpreter/interpreter_common.cc | 13 | ||||
| -rw-r--r-- | runtime/interpreter/unstarted_runtime.cc | 66 |
2 files changed, 73 insertions, 6 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc index ae67efbcd1..59d3008fc1 100644 --- a/runtime/interpreter/interpreter_common.cc +++ b/runtime/interpreter/interpreter_common.cc @@ -616,16 +616,17 @@ bool DoCall(ArtMethod* called_method, Thread* self, ShadowFrame& shadow_frame, uint16_t regList = inst->Fetch16(2); uint16_t count = num_ins; size_t arg_index = 0; - if (string_init) { - // Skip the referrer for the new static StringFactory call. - regList >>= 4; - ++arg_index; - } if (count == 5) { AssignRegister(new_shadow_frame, shadow_frame, first_dest_reg + 4U, (inst_data >> 8) & 0x0f); --count; - } + } + if (string_init) { + // Skip the referrer for the new static StringFactory call. + regList >>= 4; + ++first_dest_reg; + --count; + } for (; arg_index < count; ++arg_index, regList >>= 4) { AssignRegister(new_shadow_frame, shadow_frame, first_dest_reg + arg_index, regList & 0x0f); } diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index f30c93a5af..9006257d00 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -755,6 +755,64 @@ static void UnstartedSecurityGetSecurityPropertiesReader( result->SetL(h_obj.Get()); } +// This allows reading the new style of String objects during compilation. +static void UnstartedStringGetCharsNoCheck( + Thread* self, ShadowFrame* shadow_frame, JValue* result ATTRIBUTE_UNUSED, size_t arg_offset) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + jint start = shadow_frame->GetVReg(arg_offset + 1); + jint end = shadow_frame->GetVReg(arg_offset + 2); + jint index = shadow_frame->GetVReg(arg_offset + 4); + mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString(); + if (string == nullptr) { + AbortTransactionOrFail(self, "String.getCharsNoCheck with null object"); + return; + } + StackHandleScope<1> hs(self); + Handle<mirror::CharArray> h_char_array(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 3)->AsCharArray())); + string->GetChars(start, end, h_char_array, index); +} + +// This allows reading chars from the new style of String objects during compilation. +static void UnstartedStringCharAt( + Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + jint index = shadow_frame->GetVReg(arg_offset + 1); + mirror::String* string = shadow_frame->GetVRegReference(arg_offset)->AsString(); + if (string == nullptr) { + AbortTransactionOrFail(self, "String.charAt with null object"); + return; + } + result->SetC(string->CharAt(index)); +} + +// This allows creating the new style of String objects during compilation. +static void UnstartedStringFactoryNewStringFromChars( + Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + jint offset = shadow_frame->GetVReg(arg_offset); + jint char_count = shadow_frame->GetVReg(arg_offset + 1); + DCHECK_GE(char_count, 0); + StackHandleScope<1> hs(self); + Handle<mirror::CharArray> h_char_array(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray())); + Runtime* runtime = Runtime::Current(); + gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator(); + result->SetL(mirror::String::AllocFromCharArray<true>(self, char_count, h_char_array, offset, allocator)); +} + +// This allows creating the new style of String objects during compilation. +static void UnstartedStringFastSubstring( + Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { + jint start = shadow_frame->GetVReg(arg_offset + 1); + jint length = shadow_frame->GetVReg(arg_offset + 2); + DCHECK_GE(length, 0); + StackHandleScope<1> hs(self); + Handle<mirror::String> h_string(hs.NewHandle(shadow_frame->GetVRegReference(arg_offset)->AsString())); + Runtime* runtime = Runtime::Current(); + gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator(); + result->SetL(mirror::String::AllocFromString<true>(self, length, h_string, start, allocator)); +} + static void UnstartedJNIVMRuntimeNewUnpaddedArray(Thread* self, mirror::ArtMethod* method ATTRIBUTE_UNUSED, mirror::Object* receiver ATTRIBUTE_UNUSED, @@ -1079,6 +1137,14 @@ static void UnstartedRuntimeInitializeInvokeHandlers() { &UnstartedMemoryPeekArrayEntry }, { "java.io.Reader java.security.Security.getSecurityPropertiesReader()", &UnstartedSecurityGetSecurityPropertiesReader }, + { "void java.lang.String.getCharsNoCheck(int, int, char[], int)", + &UnstartedStringGetCharsNoCheck }, + { "char java.lang.String.charAt(int)", + &UnstartedStringCharAt }, + { "java.lang.String java.lang.StringFactory.newStringFromChars(int, int, char[])", + &UnstartedStringFactoryNewStringFromChars }, + { "java.lang.String java.lang.String.fastSubstring(int, int)", + &UnstartedStringFastSubstring }, }; for (auto& def : defs) { |