From cc3839c15555a2751e13980638fc40e4d3da633e Mon Sep 17 00:00:00 2001 From: Roland Levillain Date: Mon, 29 Feb 2016 16:23:48 +0000 Subject: [PATCH] Improve documentation about StringFactory.newStringFromChars. Make it clear that the native method requires its third argument to be non-null, and therefore that the intrinsics do not need a null check for it. Bug: 27378573 Change-Id: Id2f78ceb0f7674f1066bc3f216b738358ca25542 --- compiler/dex/quick/gen_invoke.cc | 6 ++++++ compiler/optimizing/intrinsics_arm.cc | 6 ++++++ compiler/optimizing/intrinsics_arm64.cc | 6 ++++++ compiler/optimizing/intrinsics_mips64.cc | 10 ++++++++-- compiler/optimizing/intrinsics_x86.cc | 6 ++++++ compiler/optimizing/intrinsics_x86_64.cc | 6 ++++++ runtime/native/java_lang_StringFactory.cc | 2 ++ 7 files changed, 40 insertions(+), 2 deletions(-) diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index 422d82ffa..fa7c961e4 100755 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -1140,6 +1140,12 @@ bool Mir2Lir::GenInlinedStringFactoryNewStringFromChars(CallInfo* info) { RegLocation rl_offset = info->args[0]; RegLocation rl_count = info->args[1]; RegLocation rl_data = info->args[2]; + // No need to emit code checking whether `rl_data` is a null + // pointer, as callers of the native method + // + // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) + // + // all include a null check on `data` before calling that method. CallRuntimeHelperRegLocationRegLocationRegLocation( kQuickAllocStringFromChars, rl_offset, rl_count, rl_data, true); RegLocation rl_return = GetReturn(kRefReg); diff --git a/compiler/optimizing/intrinsics_arm.cc b/compiler/optimizing/intrinsics_arm.cc index 4ce919ee3..448b4251a 100644 --- a/compiler/optimizing/intrinsics_arm.cc +++ b/compiler/optimizing/intrinsics_arm.cc @@ -1242,6 +1242,12 @@ void IntrinsicLocationsBuilderARM::VisitStringNewStringFromChars(HInvoke* invoke void IntrinsicCodeGeneratorARM::VisitStringNewStringFromChars(HInvoke* invoke) { ArmAssembler* assembler = GetAssembler(); + // No need to emit code checking whether `locations->InAt(2)` is a null + // pointer, as callers of the native method + // + // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) + // + // all include a null check on `data` before calling that method. __ LoadFromOffset( kLoadWord, LR, TR, QUICK_ENTRYPOINT_OFFSET(kArmWordSize, pAllocStringFromChars).Int32Value()); codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); diff --git a/compiler/optimizing/intrinsics_arm64.cc b/compiler/optimizing/intrinsics_arm64.cc index 4be1695a9..d05f5af15 100644 --- a/compiler/optimizing/intrinsics_arm64.cc +++ b/compiler/optimizing/intrinsics_arm64.cc @@ -1392,6 +1392,12 @@ void IntrinsicLocationsBuilderARM64::VisitStringNewStringFromChars(HInvoke* invo void IntrinsicCodeGeneratorARM64::VisitStringNewStringFromChars(HInvoke* invoke) { vixl::MacroAssembler* masm = GetVIXLAssembler(); + // No need to emit code checking whether `locations->InAt(2)` is a null + // pointer, as callers of the native method + // + // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) + // + // all include a null check on `data` before calling that method. __ Ldr(lr, MemOperand(tr, QUICK_ENTRYPOINT_OFFSET(kArm64WordSize, pAllocStringFromChars).Int32Value())); codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); diff --git a/compiler/optimizing/intrinsics_mips64.cc b/compiler/optimizing/intrinsics_mips64.cc index ca2652b74..78b436079 100644 --- a/compiler/optimizing/intrinsics_mips64.cc +++ b/compiler/optimizing/intrinsics_mips64.cc @@ -1685,7 +1685,7 @@ void IntrinsicCodeGeneratorMIPS64::VisitStringIndexOfAfter(HInvoke* invoke) { invoke, GetAssembler(), codegen_, GetAllocator(), /* start_at_zero */ false); } -// java.lang.String.String(byte[] bytes) +// java.lang.StringFactory.newStringFromBytes(byte[] data, int high, int offset, int byteCount) void IntrinsicLocationsBuilderMIPS64::VisitStringNewStringFromBytes(HInvoke* invoke) { LocationSummary* locations = new (arena_) LocationSummary(invoke, LocationSummary::kCall, @@ -1719,7 +1719,7 @@ void IntrinsicCodeGeneratorMIPS64::VisitStringNewStringFromBytes(HInvoke* invoke __ Bind(slow_path->GetExitLabel()); } -// java.lang.String.String(char[] value) +// java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) void IntrinsicLocationsBuilderMIPS64::VisitStringNewStringFromChars(HInvoke* invoke) { LocationSummary* locations = new (arena_) LocationSummary(invoke, LocationSummary::kCall, @@ -1735,6 +1735,12 @@ void IntrinsicLocationsBuilderMIPS64::VisitStringNewStringFromChars(HInvoke* inv void IntrinsicCodeGeneratorMIPS64::VisitStringNewStringFromChars(HInvoke* invoke) { Mips64Assembler* assembler = GetAssembler(); + // No need to emit code checking whether `locations->InAt(2)` is a null + // pointer, as callers of the native method + // + // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) + // + // all include a null check on `data` before calling that method. __ LoadFromOffset(kLoadDoubleword, TMP, TR, diff --git a/compiler/optimizing/intrinsics_x86.cc b/compiler/optimizing/intrinsics_x86.cc index 0df4553f5..bfa4e374f 100644 --- a/compiler/optimizing/intrinsics_x86.cc +++ b/compiler/optimizing/intrinsics_x86.cc @@ -1564,6 +1564,12 @@ void IntrinsicLocationsBuilderX86::VisitStringNewStringFromChars(HInvoke* invoke void IntrinsicCodeGeneratorX86::VisitStringNewStringFromChars(HInvoke* invoke) { X86Assembler* assembler = GetAssembler(); + // No need to emit code checking whether `locations->InAt(2)` is a null + // pointer, as callers of the native method + // + // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) + // + // all include a null check on `data` before calling that method. __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pAllocStringFromChars))); codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); } diff --git a/compiler/optimizing/intrinsics_x86_64.cc b/compiler/optimizing/intrinsics_x86_64.cc index 2a9e684d1..15c399712 100644 --- a/compiler/optimizing/intrinsics_x86_64.cc +++ b/compiler/optimizing/intrinsics_x86_64.cc @@ -1659,6 +1659,12 @@ void IntrinsicLocationsBuilderX86_64::VisitStringNewStringFromChars(HInvoke* inv void IntrinsicCodeGeneratorX86_64::VisitStringNewStringFromChars(HInvoke* invoke) { X86_64Assembler* assembler = GetAssembler(); + // No need to emit code checking whether `locations->InAt(2)` is a null + // pointer, as callers of the native method + // + // java.lang.StringFactory.newStringFromChars(int offset, int charCount, char[] data) + // + // all include a null check on `data` before calling that method. __ gs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86_64WordSize, pAllocStringFromChars), /* no_rip */ true)); codegen_->RecordPcInfo(invoke, invoke->GetDexPc()); diff --git a/runtime/native/java_lang_StringFactory.cc b/runtime/native/java_lang_StringFactory.cc index 34d6a37ab..5a219efc7 100644 --- a/runtime/native/java_lang_StringFactory.cc +++ b/runtime/native/java_lang_StringFactory.cc @@ -50,8 +50,10 @@ static jstring StringFactory_newStringFromBytes(JNIEnv* env, jclass, jbyteArray return soa.AddLocalReference(result); } +// The char array passed as `java_data` must not be a null reference. static jstring StringFactory_newStringFromChars(JNIEnv* env, jclass, jint offset, jint char_count, jcharArray java_data) { + DCHECK(java_data != nullptr); ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); Handle char_array(hs.NewHandle(soa.Decode(java_data))); -- 2.11.0