diff options
| author | Elliott Hughes <enh@google.com> | 2010-04-05 18:13:52 -0700 |
|---|---|---|
| committer | Elliott Hughes <enh@google.com> | 2010-04-08 15:53:10 -0700 |
| commit | ee34f594881ac2d859113db33baf5e141f5a58dd (patch) | |
| tree | 46054403ccc8b27c821563574f7be6cfe70e50b4 /vm/compiler/codegen/arm/CodegenDriver.c | |
| parent | 3517705eed1cd8dc9cb0386db952de661623b2df (diff) | |
An InlineNative for String.isEmpty, so it's not slower than length() == 0.
Before:
benchmark ns logarithmic runtime
IsEmpty 115 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
LengthEqualsZero 21 XXXXX||||||||||||||
With C intrinsic:
IsEmpty 30 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
LengthEqualsZero 20 XXXXXXXXXXXXXXXXXXXX||||||
With assembler intrinsic:
IsEmpty 15 XXXXXXXXXXXXXXXXXXXX||||||
LengthEqualsZero 21 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
(All times on passion.)
Change-Id: Ifcc37fe7b8efdd377675a448e0085e490d6767bc
Diffstat (limited to 'vm/compiler/codegen/arm/CodegenDriver.c')
| -rw-r--r-- | vm/compiler/codegen/arm/CodegenDriver.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c index e92eb77cb..2f157a3bc 100644 --- a/vm/compiler/codegen/arm/CodegenDriver.c +++ b/vm/compiler/codegen/arm/CodegenDriver.c @@ -2991,8 +2991,11 @@ static bool genInlinedIndexOf(CompilationUnit *cUnit, MIR *mir, bool singleI) #endif } -static bool genInlinedStringLength(CompilationUnit *cUnit, MIR *mir) +// Generates an inlined String.isEmpty or String.length. +static bool genInlinedStringIsEmptyOrLength(CompilationUnit *cUnit, MIR *mir, + bool isEmpty) { + // dst = src.length(); RegLocation rlObj = dvmCompilerGetSrc(cUnit, mir, 0); RegLocation rlDest = inlinedTarget(cUnit, mir, false); rlObj = loadValue(cUnit, rlObj, kCoreReg); @@ -3000,10 +3003,26 @@ static bool genInlinedStringLength(CompilationUnit *cUnit, MIR *mir) genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset, NULL); loadWordDisp(cUnit, rlObj.lowReg, gDvm.offJavaLangString_count, rlResult.lowReg); + if (isEmpty) { + // dst = (dst == 0); + int tReg = dvmCompilerAllocTemp(cUnit); + opRegReg(cUnit, kOpNeg, tReg, rlResult.lowReg); + opRegRegReg(cUnit, kOpAdc, rlResult.lowReg, rlResult.lowReg, tReg); + } storeValue(cUnit, rlDest, rlResult); return false; } +static bool genInlinedStringLength(CompilationUnit *cUnit, MIR *mir) +{ + return genInlinedStringIsEmptyOrLength(cUnit, mir, false); +} + +static bool genInlinedStringIsEmpty(CompilationUnit *cUnit, MIR *mir) +{ + return genInlinedStringIsEmptyOrLength(cUnit, mir, true); +} + static bool genInlinedStringCharAt(CompilationUnit *cUnit, MIR *mir) { int contents = offsetof(ArrayObject, contents); @@ -3093,6 +3112,8 @@ static bool handleExecuteInline(CompilationUnit *cUnit, MIR *mir) return false; /* Nop */ case INLINE_STRING_LENGTH: return genInlinedStringLength(cUnit, mir); + case INLINE_STRING_IS_EMPTY: + return genInlinedStringIsEmpty(cUnit, mir); case INLINE_MATH_ABS_INT: return genInlinedAbsInt(cUnit, mir); case INLINE_MATH_ABS_LONG: |
