Bug 1466189: Handle equal length strings in Compare IC r=tcampbell

--HG--
extra : rebase_source : d5748a5839bf256adadae5c14d5d53d3ba949cce
This commit is contained in:
Matthew Gaudet 2018-06-05 18:02:19 -04:00
parent b3cfc1335e
commit 4ec5d0f516
7 changed files with 93 additions and 27 deletions

View File

@ -9,6 +9,7 @@
#include "jit/CacheIR.h"
#include "jit/Linker.h"
#include "jit/SharedICHelpers.h"
#include "jit/VMFunctions.h"
#include "proxy/DeadObjectProxy.h"
#include "proxy/Proxy.h"
@ -980,6 +981,47 @@ BaselineCacheIRCompiler::emitCallStringSplitResult()
return true;
}
bool
BaselineCacheIRCompiler::emitCompareStringResult()
{
AutoOutputRegister output(*this);
Register left = allocator.useRegister(masm, reader.stringOperandId());
Register right = allocator.useRegister(masm, reader.stringOperandId());
JSOp op = reader.jsop();
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Label slow, done;
masm.compareStrings(op, left, right, scratch, &slow);
masm.jump(&done);
masm.bind(&slow);
{
allocator.discardStack(masm);
AutoStubFrame stubFrame(*this);
stubFrame.enter(masm, scratch);
masm.Push(right);
masm.Push(left);
if (!callVM(masm, (op == JSOP_EQ || op == JSOP_STRICTEQ) ?
StringsEqualInfo :
StringsNotEqualInfo))
{
return false;
}
stubFrame.leave(masm);
masm.mov(ReturnReg, scratch);
}
masm.bind(&done);
masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg());
return true;
}
bool
BaselineCacheIRCompiler::callTypeUpdateIC(Register obj, ValueOperand val, Register scratch,
LiveGeneralRegisterSet saveRegs)

View File

@ -2612,26 +2612,6 @@ CacheIRCompiler::emitLoadObjectTruthyResult()
return true;
}
bool
CacheIRCompiler::emitCompareStringResult()
{
AutoOutputRegister output(*this);
Register left = allocator.useRegister(masm, reader.stringOperandId());
Register right = allocator.useRegister(masm, reader.stringOperandId());
JSOp op = reader.jsop();
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
masm.compareStrings(op, left, right, scratch, failure->label());
masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg());
return true;
}
bool
CacheIRCompiler::emitComparePointerResultShared(bool symbol)
{

View File

@ -73,7 +73,6 @@ namespace jit {
_(LoadDoubleTruthyResult) \
_(LoadStringTruthyResult) \
_(LoadObjectTruthyResult) \
_(CompareStringResult) \
_(CompareObjectResult) \
_(CompareSymbolResult) \
_(ArrayJoinResult) \

View File

@ -43,6 +43,7 @@
#include "jit/RangeAnalysis.h"
#include "jit/SharedICHelpers.h"
#include "jit/StackSlotAllocator.h"
#include "jit/VMFunctions.h"
#include "util/Unicode.h"
#include "vm/AsyncFunction.h"
#include "vm/AsyncIteration.h"
@ -7720,12 +7721,6 @@ CodeGenerator::visitBinaryV(LBinaryV* lir)
}
}
typedef bool (*StringCompareFn)(JSContext*, HandleString, HandleString, bool*);
static const VMFunction StringsEqualInfo =
FunctionInfo<StringCompareFn>(jit::StringsEqual<true>, "StringsEqual");
static const VMFunction StringsNotEqualInfo =
FunctionInfo<StringCompareFn>(jit::StringsEqual<false>, "StringsEqual");
void
CodeGenerator::emitCompareS(LInstruction* lir, JSOp op, Register left, Register right,
Register output)

View File

@ -13,6 +13,7 @@
#include "jit/JSJitFrameIter.h"
#include "jit/Linker.h"
#include "jit/SharedICHelpers.h"
#include "jit/VMFunctions.h"
#include "proxy/DeadObjectProxy.h"
#include "proxy/Proxy.h"
@ -1360,6 +1361,46 @@ IonCacheIRCompiler::emitCallStringSplitResult()
return true;
}
bool
IonCacheIRCompiler::emitCompareStringResult()
{
AutoOutputRegister output(*this);
Register left = allocator.useRegister(masm, reader.stringOperandId());
Register right = allocator.useRegister(masm, reader.stringOperandId());
JSOp op = reader.jsop();
AutoScratchRegisterMaybeOutput scratch(allocator, masm, output);
FailurePath* failure;
if (!addFailurePath(&failure))
return false;
Label slow, done;
masm.compareStrings(op, left, right, scratch, &slow);
masm.jump(&done);
masm.bind(&slow);
allocator.discardStack(masm);
prepareVMCall(masm);
masm.Push(right);
masm.Push(left);
if (!callVM(masm, (op == JSOP_EQ || op == JSOP_STRICTEQ) ?
StringsEqualInfo :
StringsNotEqualInfo))
{
return false;
}
masm.storeCallBoolResult(scratch);
masm.bind(&done);
masm.tagValue(JSVAL_TYPE_BOOLEAN, scratch, output.valueReg());
return true;
}
static bool
GroupHasPropertyTypes(ObjectGroup* group, jsid* id, Value* v)
{

View File

@ -336,6 +336,12 @@ StringsEqual(JSContext* cx, HandleString lhs, HandleString rhs, bool* res)
template bool StringsEqual<true>(JSContext* cx, HandleString lhs, HandleString rhs, bool* res);
template bool StringsEqual<false>(JSContext* cx, HandleString lhs, HandleString rhs, bool* res);
typedef bool (*StringCompareFn)(JSContext*, HandleString, HandleString, bool*);
const VMFunction StringsEqualInfo =
FunctionInfo<StringCompareFn>(jit::StringsEqual<true>, "StringsEqual");
const VMFunction StringsNotEqualInfo =
FunctionInfo<StringCompareFn>(jit::StringsEqual<false>, "StringsEqual");
bool StringSplitHelper(JSContext* cx, HandleString str, HandleString sep,
HandleObjectGroup group, uint32_t limit,
MutableHandleValue result)

View File

@ -953,6 +953,9 @@ CloseIteratorFromIon(JSContext* cx, JSObject* obj);
extern const VMFunction SetObjectElementInfo;
extern const VMFunction StringsEqualInfo;
extern const VMFunction StringsNotEqualInfo;
} // namespace jit
} // namespace js