[compiler] Introduce proper StrictNotEqualStub.
Generalize the code that we have for StrictEqualStub to also general a StrictNotEqualStub and hook that up with TurboFan and Ignition. It's still falling back to the runtime for every String (in)equality check. R=yangguo@chromium.org Review URL: https://codereview.chromium.org/1756793002 Cr-Commit-Position: refs/heads/master@{#34426}
This commit is contained in:
parent
94f0abf98a
commit
ca6d0b1eb1
@ -200,6 +200,12 @@ Callable CodeFactory::StrictEqual(Isolate* isolate) {
|
||||
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StrictNotEqual(Isolate* isolate) {
|
||||
StrictNotEqualStub stub(isolate);
|
||||
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
|
||||
}
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StringAdd(Isolate* isolate, StringAddFlags flags,
|
||||
PretenureFlag pretenure_flag) {
|
||||
|
@ -76,6 +76,7 @@ class CodeFactory final {
|
||||
static Callable RegExpExec(Isolate* isolate);
|
||||
|
||||
static Callable StrictEqual(Isolate* isolate);
|
||||
static Callable StrictNotEqual(Isolate* isolate);
|
||||
|
||||
static Callable StringAdd(Isolate* isolate, StringAddFlags flags,
|
||||
PretenureFlag pretenure_flag);
|
||||
|
@ -498,9 +498,14 @@ void StringLengthStub::GenerateAssembly(
|
||||
assembler->Return(result);
|
||||
}
|
||||
|
||||
void StrictEqualStub::GenerateAssembly(
|
||||
compiler::CodeStubAssembler* assembler) const {
|
||||
// Here's pseudo-code for the algorithm below:
|
||||
namespace {
|
||||
|
||||
enum StrictEqualMode { kStrictEqual, kStrictNotEqual };
|
||||
|
||||
void GenerateStrictEqual(compiler::CodeStubAssembler* assembler,
|
||||
StrictEqualMode mode) {
|
||||
// Here's pseudo-code for the algorithm below in case of kStrictEqual mode;
|
||||
// for kStrictNotEqual mode we properly negate the result.
|
||||
//
|
||||
// if (lhs == rhs) {
|
||||
// if (lhs->IsHeapNumber()) return HeapNumber::cast(lhs)->value() != NaN;
|
||||
@ -554,7 +559,7 @@ void StrictEqualStub::GenerateAssembly(
|
||||
Node* rhs = assembler->Parameter(1);
|
||||
Node* context = assembler->Parameter(2);
|
||||
|
||||
Label if_true(assembler), if_false(assembler);
|
||||
Label if_equal(assembler), if_notequal(assembler);
|
||||
|
||||
// Check if {lhs} and {rhs} refer to the same object.
|
||||
Label if_same(assembler), if_notsame(assembler);
|
||||
@ -588,15 +593,15 @@ void StrictEqualStub::GenerateAssembly(
|
||||
Node* lhs_value = assembler->LoadHeapNumberValue(lhs);
|
||||
|
||||
// Check if the HeapNumber value is a NaN.
|
||||
assembler->BranchIfFloat64IsNaN(lhs_value, &if_false, &if_true);
|
||||
assembler->BranchIfFloat64IsNaN(lhs_value, &if_notequal, &if_equal);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_lhsisnotnumber);
|
||||
assembler->Goto(&if_true);
|
||||
assembler->Goto(&if_equal);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_lhsissmi);
|
||||
assembler->Goto(&if_true);
|
||||
assembler->Goto(&if_equal);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_notsame);
|
||||
@ -633,8 +638,8 @@ void StrictEqualStub::GenerateAssembly(
|
||||
Node* rhs_value = assembler->SmiToFloat64(rhs);
|
||||
|
||||
// Perform a floating point comparison of {lhs} and {rhs}.
|
||||
assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_true,
|
||||
&if_false);
|
||||
assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
|
||||
&if_notequal);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_rhsisnotsmi);
|
||||
@ -655,12 +660,12 @@ void StrictEqualStub::GenerateAssembly(
|
||||
Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
|
||||
|
||||
// Perform a floating point comparison of {lhs} and {rhs}.
|
||||
assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_true,
|
||||
&if_false);
|
||||
assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
|
||||
&if_notequal);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_rhsisnotnumber);
|
||||
assembler->Goto(&if_false);
|
||||
assembler->Goto(&if_notequal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -672,7 +677,7 @@ void StrictEqualStub::GenerateAssembly(
|
||||
&if_rhsisnotsmi);
|
||||
|
||||
assembler->Bind(&if_rhsissmi);
|
||||
assembler->Goto(&if_false);
|
||||
assembler->Goto(&if_notequal);
|
||||
|
||||
assembler->Bind(&if_rhsisnotsmi);
|
||||
{
|
||||
@ -702,12 +707,14 @@ void StrictEqualStub::GenerateAssembly(
|
||||
{
|
||||
// TODO(bmeurer): Optimize this further once the StringEqual
|
||||
// functionality is available in TurboFan land.
|
||||
assembler->TailCallRuntime(Runtime::kStringEqual, context, lhs,
|
||||
rhs);
|
||||
Runtime::FunctionId function_id = (mode == kStrictEqual)
|
||||
? Runtime::kStringEqual
|
||||
: Runtime::kStringNotEqual;
|
||||
assembler->TailCallRuntime(function_id, context, lhs, rhs);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_rhsisnotstring);
|
||||
assembler->Goto(&if_false);
|
||||
assembler->Goto(&if_notequal);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_lhsisnotstring);
|
||||
@ -723,12 +730,14 @@ void StrictEqualStub::GenerateAssembly(
|
||||
assembler->Bind(&if_lhsissimd128value);
|
||||
{
|
||||
// TODO(bmeurer): Inline the Simd128Value equality check.
|
||||
assembler->TailCallRuntime(Runtime::kStrictEqual, context, lhs,
|
||||
rhs);
|
||||
Runtime::FunctionId function_id = (mode == kStrictEqual)
|
||||
? Runtime::kStrictEqual
|
||||
: Runtime::kStrictNotEqual;
|
||||
assembler->TailCallRuntime(function_id, context, lhs, rhs);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_lhsisnotsimd128value);
|
||||
assembler->Goto(&if_false);
|
||||
assembler->Goto(&if_notequal);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -746,7 +755,7 @@ void StrictEqualStub::GenerateAssembly(
|
||||
&if_rhsisnotsmi);
|
||||
|
||||
assembler->Bind(&if_rhsissmi);
|
||||
assembler->Goto(&if_false);
|
||||
assembler->Goto(&if_notequal);
|
||||
|
||||
assembler->Bind(&if_rhsisnotsmi);
|
||||
{
|
||||
@ -765,21 +774,33 @@ void StrictEqualStub::GenerateAssembly(
|
||||
Node* rhs_value = assembler->LoadHeapNumberValue(rhs);
|
||||
|
||||
// Perform a floating point comparison of {lhs} and {rhs}.
|
||||
assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_true,
|
||||
&if_false);
|
||||
assembler->BranchIfFloat64Equal(lhs_value, rhs_value, &if_equal,
|
||||
&if_notequal);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_rhsisnotnumber);
|
||||
assembler->Goto(&if_false);
|
||||
assembler->Goto(&if_notequal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assembler->Bind(&if_true);
|
||||
assembler->Return(assembler->BooleanConstant(true));
|
||||
assembler->Bind(&if_equal);
|
||||
assembler->Return(assembler->BooleanConstant(mode == kStrictEqual));
|
||||
|
||||
assembler->Bind(&if_false);
|
||||
assembler->Return(assembler->BooleanConstant(false));
|
||||
assembler->Bind(&if_notequal);
|
||||
assembler->Return(assembler->BooleanConstant(mode == kStrictNotEqual));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void StrictEqualStub::GenerateAssembly(
|
||||
compiler::CodeStubAssembler* assembler) const {
|
||||
GenerateStrictEqual(assembler, kStrictEqual);
|
||||
}
|
||||
|
||||
void StrictNotEqualStub::GenerateAssembly(
|
||||
compiler::CodeStubAssembler* assembler) const {
|
||||
GenerateStrictEqual(assembler, kStrictNotEqual);
|
||||
}
|
||||
|
||||
void ToBooleanStub::GenerateAssembly(
|
||||
|
@ -102,6 +102,7 @@ namespace internal {
|
||||
V(AllocateMutableHeapNumber) \
|
||||
V(StringLength) \
|
||||
V(StrictEqual) \
|
||||
V(StrictNotEqual) \
|
||||
V(ToBoolean) \
|
||||
/* IC Handler stubs */ \
|
||||
V(ArrayBufferViewLoadField) \
|
||||
@ -642,6 +643,16 @@ class StrictEqualStub final : public TurboFanCodeStub {
|
||||
DEFINE_CODE_STUB(StrictEqual, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class StrictNotEqualStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit StrictNotEqualStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
||||
void GenerateAssembly(compiler::CodeStubAssembler* assembler) const final;
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Compare);
|
||||
DEFINE_CODE_STUB(StrictNotEqual, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class ToBooleanStub final : public TurboFanCodeStub {
|
||||
public:
|
||||
explicit ToBooleanStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
|
||||
|
@ -89,7 +89,6 @@ REPLACE_BINARY_OP_IC_CALL(JSModulus, Token::MOD)
|
||||
}
|
||||
REPLACE_RUNTIME_CALL(JSEqual, Runtime::kEqual)
|
||||
REPLACE_RUNTIME_CALL(JSNotEqual, Runtime::kNotEqual)
|
||||
REPLACE_RUNTIME_CALL(JSStrictNotEqual, Runtime::kStrictNotEqual)
|
||||
REPLACE_RUNTIME_CALL(JSLessThan, Runtime::kLessThan)
|
||||
REPLACE_RUNTIME_CALL(JSGreaterThan, Runtime::kGreaterThan)
|
||||
REPLACE_RUNTIME_CALL(JSLessThanOrEqual, Runtime::kLessThanOrEqual)
|
||||
@ -99,13 +98,14 @@ REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
|
||||
REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver)
|
||||
#undef REPLACE_RUNTIME_CALL
|
||||
|
||||
#define REPLACE_STUB_CALL(Op, Stub) \
|
||||
void JSGenericLowering::Lower##Op(Node* node) { \
|
||||
#define REPLACE_STUB_CALL(Name) \
|
||||
void JSGenericLowering::LowerJS##Name(Node* node) { \
|
||||
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
|
||||
Callable callable = CodeFactory::Stub(isolate()); \
|
||||
Callable callable = CodeFactory::Name(isolate()); \
|
||||
ReplaceWithStubCall(node, callable, flags); \
|
||||
}
|
||||
REPLACE_STUB_CALL(JSStrictEqual, StrictEqual)
|
||||
REPLACE_STUB_CALL(StrictEqual)
|
||||
REPLACE_STUB_CALL(StrictNotEqual)
|
||||
#undef REPLACE_STUB_CALL
|
||||
|
||||
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
|
||||
|
@ -1197,7 +1197,7 @@ void Interpreter::DoTestEqualStrict(InterpreterAssembler* assembler) {
|
||||
// Test if the value in the <src> register is not strictly equal to the
|
||||
// accumulator.
|
||||
void Interpreter::DoTestNotEqualStrict(InterpreterAssembler* assembler) {
|
||||
DoBinaryOp(Runtime::kStrictNotEqual, assembler);
|
||||
DoBinaryOp(CodeFactory::StrictNotEqual(isolate_), assembler);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1153,6 +1153,13 @@ RUNTIME_FUNCTION(Runtime_StringEqual) {
|
||||
return isolate->heap()->ToBoolean(String::Equals(x, y));
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_StringNotEqual) {
|
||||
HandleScope handle_scope(isolate);
|
||||
DCHECK_EQ(2, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
|
||||
return isolate->heap()->ToBoolean(!String::Equals(x, y));
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_FlattenString) {
|
||||
HandleScope scope(isolate);
|
||||
|
@ -863,6 +863,7 @@ namespace internal {
|
||||
F(TruncateString, 2, 1) \
|
||||
F(NewString, 2, 1) \
|
||||
F(StringEqual, 2, 1) \
|
||||
F(StringNotEqual, 2, 1) \
|
||||
F(FlattenString, 1, 1) \
|
||||
F(StringCharFromCode, 1, 1) \
|
||||
F(StringCharAt, 2, 1) \
|
||||
|
Loading…
Reference in New Issue
Block a user