[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:
Ryan Macnak
2019-04-18 22:50:45 +00:00
committed by commit-bot@chromium.org
parent 3f477a6218
commit b352b5ffb7
6 changed files with 56 additions and 49 deletions
+2 -2
View File
@@ -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) {
+18 -18
View File
@@ -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) {
+17 -13
View File
@@ -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) {
+1 -1
View File
@@ -50,7 +50,7 @@ namespace dart {
V(OneArgCheckInlineCache) \
V(TwoArgsCheckInlineCache) \
V(SmiAddInlineCache) \
V(SmiSubInlineCache) \
V(SmiLessInlineCache) \
V(SmiEqualInlineCache) \
V(OneArgOptimizedCheckInlineCache) \
V(TwoArgsOptimizedCheckInlineCache) \