| Index: runtime/vm/stub_code_x64.cc
|
| diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
|
| index 39d8dc96b0b2c7e2d040fa48f1b89270e7cceed6..e562e559ff6040d25961f11e23613c3631f46d2b 100644
|
| --- a/runtime/vm/stub_code_x64.cc
|
| +++ b/runtime/vm/stub_code_x64.cc
|
| @@ -2088,6 +2088,13 @@ void StubCode::GenerateOptimizedIdenticalWithNumberCheckStub(
|
| }
|
|
|
|
|
| +// Called from megamorphic calls.
|
| +// RDI: receiver
|
| +// RBX: MegamorphicCache (preserved)
|
| +// Result:
|
| +// RCX: target entry point
|
| +// CODE_REG: target Code
|
| +// R10: arguments descriptor
|
| void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
|
| __ LoadTaggedClassIdMayBeSmi(RAX, RDI);
|
| // RAX: class ID of the receiver (smi).
|
| @@ -2127,13 +2134,6 @@ void StubCode::EmitMegamorphicLookup(Assembler* assembler) {
|
| }
|
|
|
|
|
| -// Called from megamorphic calls.
|
| -// RDI: receiver
|
| -// RBX: MegamorphicCache (preserved)
|
| -// Result:
|
| -// RCX: target entry point
|
| -// CODE_REG: target Code
|
| -// R10: arguments descriptor
|
| void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
|
| EmitMegamorphicLookup(assembler);
|
| __ ret();
|
| @@ -2147,7 +2147,53 @@ void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
|
| // RCX: target entry point
|
| // CODE_REG: target Code object
|
| // R10: arguments descriptor
|
| -void StubCode::GenerateICLookupStub(Assembler* assembler) {
|
| +static void EmitICLookup(Assembler* assembler,
|
| + intptr_t args_checked,
|
| + Token::Kind kind) {
|
| + if (kind != Token::kILLEGAL) {
|
| + __ Comment("Fast Smi op");
|
| + Label not_smi_or_overflow;
|
| +
|
| + // RDI: Receiver
|
| + __ movq(RCX, Address(RSP, + 1 * kWordSize));
|
| + // RCX: Argument
|
| + __ movq(R13, RCX);
|
| + __ orq(R13, RDI);
|
| + __ testq(R13, Immediate(kSmiTagMask));
|
| + __ j(NOT_ZERO, ¬_smi_or_overflow);
|
| + __ movq(RAX, RDI);
|
| + switch (kind) {
|
| + case Token::kADD: {
|
| + __ addq(RAX, RCX);
|
| + __ j(OVERFLOW, ¬_smi_or_overflow);
|
| + break;
|
| + }
|
| + case Token::kSUB: {
|
| + __ subq(RAX, RCX);
|
| + __ j(OVERFLOW, ¬_smi_or_overflow);
|
| + break;
|
| + }
|
| + case Token::kEQ: {
|
| + Label done, is_true;
|
| + __ cmpq(RAX, RCX);
|
| + __ j(EQUAL, &is_true, Assembler::kNearJump);
|
| + __ LoadObject(RAX, Bool::False());
|
| + __ jmp(&done, Assembler::kNearJump);
|
| + __ Bind(&is_true);
|
| + __ LoadObject(RAX, Bool::True());
|
| + __ Bind(&done);
|
| + break;
|
| + }
|
| + default: UNIMPLEMENTED();
|
| + }
|
| + // Return past the call to lookup result.
|
| + intptr_t call_length = 2; // call rcx
|
| + __ AddImmediate(Address(RSP, 0), Immediate(call_length));
|
| + __ ret();
|
| +
|
| + __ Bind(¬_smi_or_overflow);
|
| + }
|
| +
|
| Label loop, found, miss;
|
|
|
| __ movq(R13, FieldAddress(RBX, ICData::ic_data_offset()));
|
| @@ -2166,12 +2212,14 @@ void StubCode::GenerateICLookupStub(Assembler* assembler) {
|
| __ testq(R9, R9);
|
| __ j(ZERO, &miss, Assembler::kNearJump);
|
|
|
| - const intptr_t entry_length = ICData::TestEntryLengthFor(1) * kWordSize;
|
| + const intptr_t entry_length =
|
| + ICData::TestEntryLengthFor(args_checked) * kWordSize;
|
| __ addq(R13, Immediate(entry_length)); // Next entry.
|
| __ jmp(&loop);
|
|
|
| __ Bind(&found);
|
| - const intptr_t target_offset = ICData::TargetIndexFor(1) * kWordSize;
|
| + const intptr_t target_offset =
|
| + ICData::TargetIndexFor(args_checked) * kWordSize;
|
| __ movq(RAX, Address(R13, target_offset));
|
| __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
|
| __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
|
| @@ -2184,6 +2232,26 @@ void StubCode::GenerateICLookupStub(Assembler* assembler) {
|
| __ ret();
|
| }
|
|
|
| +
|
| +void StubCode::GenerateICLookupStub(Assembler* assembler) {
|
| + EmitICLookup(assembler, 1, Token::kILLEGAL);
|
| +}
|
| +
|
| +
|
| +void StubCode::GenerateICSmiAddLookupStub(Assembler* assembler) {
|
| + EmitICLookup(assembler, 2, Token::kADD);
|
| +}
|
| +
|
| +
|
| +void StubCode::GenerateICSmiSubLookupStub(Assembler* assembler) {
|
| + EmitICLookup(assembler, 2, Token::kSUB);
|
| +}
|
| +
|
| +
|
| +void StubCode::GenerateICSmiEqualLookupStub(Assembler* assembler) {
|
| + EmitICLookup(assembler, 2, Token::kEQ);
|
| +}
|
| +
|
| } // namespace dart
|
|
|
| #endif // defined TARGET_ARCH_X64
|
|
|