[vm, jit] The hottest Smi ops are + < == not + - ==.
Bug: https://github.com/dart-lang/sdk/issues/36409 Change-Id: Id1a6a65b26c95fb3f56bf844943aa09cc4f13a2a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99728 Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
3f477a6218
commit
b352b5ffb7
@@ -4048,8 +4048,8 @@ static RawCode* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) {
|
||||
switch (kind) {
|
||||
case Token::kADD:
|
||||
return StubCode::SmiAddInlineCache().raw();
|
||||
case Token::kSUB:
|
||||
return StubCode::SmiSubInlineCache().raw();
|
||||
case Token::kLT:
|
||||
return StubCode::SmiLessInlineCache().raw();
|
||||
case Token::kEQ:
|
||||
return StubCode::SmiEqualInlineCache().raw();
|
||||
default:
|
||||
|
||||
@@ -1841,8 +1841,8 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
intptr_t num_args,
|
||||
Label* not_smi_or_overflow) {
|
||||
__ Comment("Fast Smi op");
|
||||
__ ldr(R0, Address(SP, 0 * target::kWordSize));
|
||||
__ ldr(R1, Address(SP, 1 * target::kWordSize));
|
||||
__ ldr(R0, Address(SP, 1 * target::kWordSize)); // Left.
|
||||
__ ldr(R1, Address(SP, 0 * target::kWordSize)); // Right.
|
||||
__ orr(TMP, R0, Operand(R1));
|
||||
__ tst(TMP, Operand(kSmiTagMask));
|
||||
__ b(not_smi_or_overflow, NE);
|
||||
@@ -1852,9 +1852,10 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
__ b(not_smi_or_overflow, VS); // Branch if overflow.
|
||||
break;
|
||||
}
|
||||
case Token::kSUB: {
|
||||
__ subs(R0, R1, Operand(R0)); // Subtract.
|
||||
__ b(not_smi_or_overflow, VS); // Branch if overflow.
|
||||
case Token::kLT: {
|
||||
__ cmp(R0, Operand(R1));
|
||||
__ LoadObject(R0, CastHandle<Object>(TrueObject()), LT);
|
||||
__ LoadObject(R0, CastHandle<Object>(FalseObject()), GE);
|
||||
break;
|
||||
}
|
||||
case Token::kEQ: {
|
||||
@@ -2114,10 +2115,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
|
||||
void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) {
|
||||
GenerateUsageCounterIncrement(assembler, R8);
|
||||
GenerateNArgsCheckInlineCacheStub(
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
|
||||
|
||||
@@ -1903,8 +1903,8 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
intptr_t num_args,
|
||||
Label* not_smi_or_overflow) {
|
||||
__ Comment("Fast Smi op");
|
||||
__ ldr(R0, Address(SP, +0 * target::kWordSize)); // Right.
|
||||
__ ldr(R1, Address(SP, +1 * target::kWordSize)); // Left.
|
||||
__ ldr(R0, Address(SP, +1 * target::kWordSize)); // Left.
|
||||
__ ldr(R1, Address(SP, +0 * target::kWordSize)); // Right.
|
||||
__ orr(TMP, R0, Operand(R1));
|
||||
__ BranchIfNotSmi(TMP, not_smi_or_overflow);
|
||||
switch (kind) {
|
||||
@@ -1913,16 +1913,18 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
__ b(not_smi_or_overflow, VS); // Branch if overflow.
|
||||
break;
|
||||
}
|
||||
case Token::kSUB: {
|
||||
__ subs(R0, R1, Operand(R0)); // Subtract.
|
||||
__ b(not_smi_or_overflow, VS); // Branch if overflow.
|
||||
case Token::kLT: {
|
||||
__ CompareRegisters(R0, R1);
|
||||
__ LoadObject(R0, CastHandle<Object>(TrueObject()));
|
||||
__ LoadObject(R1, CastHandle<Object>(FalseObject()));
|
||||
__ csel(R0, R0, R1, LT);
|
||||
break;
|
||||
}
|
||||
case Token::kEQ: {
|
||||
__ CompareRegisters(R0, R1);
|
||||
__ LoadObject(R0, CastHandle<Object>(TrueObject()));
|
||||
__ LoadObject(R1, CastHandle<Object>(FalseObject()));
|
||||
__ csel(R0, R1, R0, NE);
|
||||
__ csel(R0, R0, R1, EQ);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -2188,10 +2190,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
|
||||
void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) {
|
||||
GenerateUsageCounterIncrement(assembler, R6);
|
||||
GenerateNArgsCheckInlineCacheStub(
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
|
||||
|
||||
@@ -1539,8 +1539,8 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
Label* not_smi_or_overflow) {
|
||||
__ Comment("Fast Smi op");
|
||||
ASSERT(num_args == 2);
|
||||
__ movl(EDI, Address(ESP, +1 * target::kWordSize)); // Right
|
||||
__ movl(EAX, Address(ESP, +2 * target::kWordSize)); // Left
|
||||
__ movl(EDI, Address(ESP, +1 * target::kWordSize)); // Right
|
||||
__ movl(EBX, EDI);
|
||||
__ orl(EBX, EAX);
|
||||
__ testl(EBX, Immediate(kSmiTagMask));
|
||||
@@ -1551,26 +1551,26 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
__ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
|
||||
break;
|
||||
}
|
||||
case Token::kSUB: {
|
||||
__ subl(EAX, EDI);
|
||||
__ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
|
||||
break;
|
||||
}
|
||||
case Token::kMUL: {
|
||||
__ SmiUntag(EAX);
|
||||
__ imull(EAX, EDI);
|
||||
__ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
|
||||
case Token::kLT: {
|
||||
Label done, is_true;
|
||||
__ cmpl(EAX, EDI);
|
||||
__ setcc(GREATER_EQUAL, AL);
|
||||
__ movzxb(EAX, AL); // EAX := EAX < EDI ? 0 : 1
|
||||
__ movl(EAX,
|
||||
Address(THR, EAX, TIMES_4, target::Thread::bool_true_offset()));
|
||||
ASSERT(target::Thread::bool_true_offset() + 4 ==
|
||||
target::Thread::bool_false_offset());
|
||||
break;
|
||||
}
|
||||
case Token::kEQ: {
|
||||
Label done, is_true;
|
||||
__ cmpl(EAX, EDI);
|
||||
__ j(EQUAL, &is_true, Assembler::kNearJump);
|
||||
__ LoadObject(EAX, CastHandle<Object>(FalseObject()));
|
||||
__ jmp(&done, Assembler::kNearJump);
|
||||
__ Bind(&is_true);
|
||||
__ LoadObject(EAX, CastHandle<Object>(TrueObject()));
|
||||
__ Bind(&done);
|
||||
__ setcc(NOT_EQUAL, AL);
|
||||
__ movzxb(EAX, AL); // EAX := EAX == EDI ? 0 : 1
|
||||
__ movl(EAX,
|
||||
Address(THR, EAX, TIMES_4, target::Thread::bool_true_offset()));
|
||||
ASSERT(target::Thread::bool_true_offset() + 4 ==
|
||||
target::Thread::bool_false_offset());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1825,10 +1825,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
|
||||
void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) {
|
||||
GenerateUsageCounterIncrement(assembler, EBX);
|
||||
GenerateNArgsCheckInlineCacheStub(
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
|
||||
|
||||
@@ -1872,8 +1872,8 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
Label* not_smi_or_overflow) {
|
||||
__ Comment("Fast Smi op");
|
||||
ASSERT(num_args == 2);
|
||||
__ movq(RCX, Address(RSP, +1 * target::kWordSize)); // Right
|
||||
__ movq(RAX, Address(RSP, +2 * target::kWordSize)); // Left.
|
||||
__ movq(RCX, Address(RSP, +1 * target::kWordSize)); // Right
|
||||
__ movq(R13, RCX);
|
||||
__ orq(R13, RAX);
|
||||
__ testq(R13, Immediate(kSmiTagMask));
|
||||
@@ -1884,20 +1884,24 @@ static void EmitFastSmiOp(Assembler* assembler,
|
||||
__ j(OVERFLOW, not_smi_or_overflow);
|
||||
break;
|
||||
}
|
||||
case Token::kSUB: {
|
||||
__ subq(RAX, RCX);
|
||||
__ j(OVERFLOW, not_smi_or_overflow);
|
||||
case Token::kLT: {
|
||||
__ cmpq(RAX, RCX);
|
||||
__ setcc(GREATER_EQUAL, ByteRegisterOf(RAX));
|
||||
__ movzxb(RAX, RAX); // RAX := RAX < RCX ? 0 : 1
|
||||
__ movq(RAX,
|
||||
Address(THR, RAX, TIMES_8, target::Thread::bool_true_offset()));
|
||||
ASSERT(target::Thread::bool_true_offset() + 8 ==
|
||||
target::Thread::bool_false_offset());
|
||||
break;
|
||||
}
|
||||
case Token::kEQ: {
|
||||
Label done, is_true;
|
||||
__ cmpq(RAX, RCX);
|
||||
__ j(EQUAL, &is_true, Assembler::kNearJump);
|
||||
__ LoadObject(RAX, CastHandle<Object>(FalseObject()));
|
||||
__ jmp(&done, Assembler::kNearJump);
|
||||
__ Bind(&is_true);
|
||||
__ LoadObject(RAX, CastHandle<Object>(TrueObject()));
|
||||
__ Bind(&done);
|
||||
__ setcc(NOT_EQUAL, ByteRegisterOf(RAX));
|
||||
__ movzxb(RAX, RAX); // RAX := RAX == RCX ? 0 : 1
|
||||
__ movq(RAX,
|
||||
Address(THR, RAX, TIMES_8, target::Thread::bool_true_offset()));
|
||||
ASSERT(target::Thread::bool_true_offset() + 8 ==
|
||||
target::Thread::bool_false_offset());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -2192,10 +2196,10 @@ void StubCodeCompiler::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
|
||||
void StubCodeCompiler::GenerateSmiLessInlineCacheStub(Assembler* assembler) {
|
||||
GenerateUsageCounterIncrement(assembler, RCX);
|
||||
GenerateNArgsCheckInlineCacheStub(
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
|
||||
assembler, 2, kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kLT);
|
||||
}
|
||||
|
||||
void StubCodeCompiler::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace dart {
|
||||
V(OneArgCheckInlineCache) \
|
||||
V(TwoArgsCheckInlineCache) \
|
||||
V(SmiAddInlineCache) \
|
||||
V(SmiSubInlineCache) \
|
||||
V(SmiLessInlineCache) \
|
||||
V(SmiEqualInlineCache) \
|
||||
V(OneArgOptimizedCheckInlineCache) \
|
||||
V(TwoArgsOptimizedCheckInlineCache) \
|
||||
|
||||
Reference in New Issue
Block a user