Add LoadTaggedClassIdMayBeSmi to assembly and improve performance of inline cache stubs.

R=zra@google.com

Review URL: https://codereview.chromium.org//313083008

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@37011 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
srdjan@google.com
2014-06-04 20:37:21 +00:00
parent 4652bb1151
commit e35ecf13e3
25 changed files with 104 additions and 202 deletions
+8
View File
@@ -1685,6 +1685,14 @@ void Assembler::CompareClassId(Register object,
}
void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) {
tst(object, Operand(kSmiTagMask));
LoadImmediate(result, Smi::RawValue(kSmiCid), EQ);
LoadClassId(result, object, NE);
SmiTag(result, NE);
}
static bool CanEncodeBranchOffset(int32_t offset) {
ASSERT(Utils::IsAligned(offset, 4));
return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset);
+1
View File
@@ -640,6 +640,7 @@ class Assembler : public ValueObject {
void LoadClassById(Register result, Register class_id);
void LoadClass(Register result, Register object, Register scratch);
void CompareClassId(Register object, intptr_t class_id, Register scratch);
void LoadTaggedClassIdMayBeSmi(Register result, Register object);
void LoadWordFromPoolOffset(Register rd, int32_t offset, Condition cond = AL);
void LoadFromOffset(OperandSize type,
+13
View File
@@ -1073,6 +1073,19 @@ void Assembler::CompareClassId(
}
void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) {
Label load, done;
tsti(object, kSmiTagMask);
b(&load, NE);
LoadImmediate(result, Smi::RawValue(kSmiCid), PP);
b(&done);
Bind(&load);
LoadClassId(result, object, PP);
SmiTag(result);
Bind(&done);
}
// Frame entry and exit.
void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
// Reserve space for arguments and align frame before entering
+1
View File
@@ -1170,6 +1170,7 @@ class Assembler : public ValueObject {
void LoadClassById(Register result, Register class_id, Register pp);
void LoadClass(Register result, Register object, Register pp);
void CompareClassId(Register object, intptr_t class_id, Register pp);
void LoadTaggedClassIdMayBeSmi(Register result, Register object);
void EnterFrame(intptr_t frame_size);
void LeaveFrame();
+13
View File
@@ -2656,6 +2656,19 @@ void Assembler::CompareClassId(Register object,
}
void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) {
testl(object, Immediate(kSmiTagMask));
Label not_smi, done;
j(NOT_ZERO, &not_smi, Assembler::kNearJump);
movl(result, Immediate(Smi::RawValue(kSmiCid)));
jmp(&done, Assembler::kNearJump);
Bind(&not_smi);
LoadClassId(result, object);
SmiTag(result);
Bind(&done);
}
static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
};
+2
View File
@@ -686,6 +686,8 @@ class Assembler : public ValueObject {
void CompareClassId(Register object, intptr_t class_id, Register scratch);
void LoadTaggedClassIdMayBeSmi(Register result, Register object);
/*
* Misc. functionality
*/
+13
View File
@@ -652,6 +652,19 @@ void Assembler::LoadClass(Register result, Register object) {
}
void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) {
Label load, done;
andi(CMPRES1, object, Immediate(kSmiTagMask));
bne(CMPRES1, ZR, &load);
LoadImmediate(result, Smi::RawValue(kSmiCid));
b(&done);
Bind(&load);
LoadClassId(result, object);
SmiTag(result);
Bind(&done);
}
void Assembler::EnterFrame() {
ASSERT(!in_delay_slot_);
addiu(SP, SP, Immediate(-2 * kWordSize));
+1
View File
@@ -1183,6 +1183,7 @@ class Assembler : public ValueObject {
void LoadClassId(Register result, Register object);
void LoadClassById(Register result, Register class_id);
void LoadClass(Register result, Register object);
void LoadTaggedClassIdMayBeSmi(Register result, Register object);
void StoreIntoObject(Register object, // Object we are storing into.
const Address& dest, // Where we are storing into.
+13
View File
@@ -3278,6 +3278,19 @@ void Assembler::CompareClassId(Register object, intptr_t class_id) {
}
void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) {
Label load, done;
testq(object, Immediate(kSmiTagMask));
j(NOT_ZERO, &load, Assembler::kNearJump);
LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)), PP);
jmp(&done);
Bind(&load);
LoadClassId(result, object);
SmiTag(result);
Bind(&done);
}
static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+2
View File
@@ -737,6 +737,8 @@ class Assembler : public ValueObject {
void CompareClassId(Register object, intptr_t class_id);
void LoadTaggedClassIdMayBeSmi(Register result, Register object);
/*
* Misc. functionality.
*/
+1 -7
View File
@@ -1232,16 +1232,10 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
const MegamorphicCache& cache =
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
Label not_smi, load_cache;
__ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
__ tst(R0, Operand(kSmiTagMask));
__ LoadClassId(R0, R0, NE);
__ SmiTag(R0, NE);
__ mov(R0, Operand(Smi::RawValue(kSmiCid)), EQ);
__ b(&load_cache, EQ);
__ LoadTaggedClassIdMayBeSmi(R0, R0);
// R0: class ID of the receiver (smi).
__ Bind(&load_cache);
__ LoadObject(R1, cache);
__ ldr(R2, FieldAddress(R1, MegamorphicCache::buckets_offset()));
__ ldr(R1, FieldAddress(R1, MegamorphicCache::mask_offset()));
+1 -10
View File
@@ -1238,19 +1238,10 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
const MegamorphicCache& cache =
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
Label not_smi, load_cache;
__ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize, PP);
__ tsti(R0, kSmiTagMask);
__ b(&not_smi, NE);
__ LoadImmediate(R0, Smi::RawValue(kSmiCid), PP);
__ b(&load_cache);
__ Bind(&not_smi);
__ LoadClassId(R0, R0, PP);
__ SmiTag(R0);
__ LoadTaggedClassIdMayBeSmi(R0, R0);
// R0: class ID of the receiver (smi).
__ Bind(&load_cache);
__ LoadObject(R1, cache, PP);
__ LoadFieldFromOffset(R2, R1, MegamorphicCache::buckets_offset(), PP);
__ LoadFieldFromOffset(R1, R1, MegamorphicCache::mask_offset(), PP);
+2 -9
View File
@@ -1279,16 +1279,9 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
const MegamorphicCache& cache =
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
Label not_smi, load_cache;
Label load_cache;
__ movl(EAX, Address(ESP, (argument_count - 1) * kWordSize));
__ testl(EAX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
__ movl(EAX, Immediate(Smi::RawValue(kSmiCid)));
__ jmp(&load_cache);
__ Bind(&not_smi);
__ LoadClassId(EAX, EAX);
__ SmiTag(EAX);
__ LoadTaggedClassIdMayBeSmi(EAX, EAX);
// EAX: class ID of the receiver (smi).
__ Bind(&load_cache);
+1 -10
View File
@@ -1272,20 +1272,11 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
const MegamorphicCache& cache =
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
Label not_smi, load_cache;
__ TraceSimMsg("MegamorphicInstanceCall");
__ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
__ andi(CMPRES1, T0, Immediate(kSmiTagMask));
__ bne(CMPRES1, ZR, &not_smi);
__ LoadImmediate(T0, Smi::RawValue(kSmiCid));
__ b(&load_cache);
__ Bind(&not_smi);
__ LoadClassId(T0, T0);
__ SmiTag(T0);
__ LoadTaggedClassIdMayBeSmi(T0, T0);
// T0: class ID of the receiver (smi).
__ Bind(&load_cache);
__ LoadObject(T1, cache);
__ lw(T2, FieldAddress(T1, MegamorphicCache::buckets_offset()));
__ lw(T1, FieldAddress(T1, MegamorphicCache::mask_offset()));
+1 -10
View File
@@ -1317,19 +1317,10 @@ void FlowGraphCompiler::EmitMegamorphicInstanceCall(
ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
const MegamorphicCache& cache =
MegamorphicCache::ZoneHandle(table->Lookup(name, arguments_descriptor));
Label not_smi, load_cache;
__ movq(RAX, Address(RSP, (argument_count - 1) * kWordSize));
__ testq(RAX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
__ LoadImmediate(RAX, Immediate(Smi::RawValue(kSmiCid)), PP);
__ jmp(&load_cache);
__ Bind(&not_smi);
__ LoadClassId(RAX, RAX);
__ SmiTag(RAX);
__ LoadTaggedClassIdMayBeSmi(RAX, RAX);
// RAX: class ID of the receiver (smi).
__ Bind(&load_cache);
__ LoadObject(RBX, cache, PP);
__ movq(RDI, FieldAddress(RBX, MegamorphicCache::buckets_offset()));
__ movq(RBX, FieldAddress(RBX, MegamorphicCache::mask_offset()));
+1 -4
View File
@@ -1053,10 +1053,7 @@ LocationSummary* LoadClassIdInstr::MakeLocationSummary(Isolate* isolate,
void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const Register object = locs()->in(0).reg();
const Register result = locs()->out(0).reg();
__ tst(object, Operand(kSmiTagMask));
__ LoadImmediate(result, Smi::RawValue(kSmiCid), EQ);
__ LoadClassId(result, object, NE);
__ SmiTag(result, NE);
__ LoadTaggedClassIdMayBeSmi(result, object);
}
+1 -9
View File
@@ -901,15 +901,7 @@ LocationSummary* LoadClassIdInstr::MakeLocationSummary(Isolate* isolate,
void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
const Register object = locs()->in(0).reg();
const Register result = locs()->out(0).reg();
Label load, done;
__ tsti(object, kSmiTagMask);
__ b(&load, NE);
__ LoadImmediate(result, Smi::RawValue(kSmiCid), PP);
__ b(&done);
__ Bind(&load);
__ LoadClassId(result, object, PP);
__ SmiTag(result);
__ Bind(&done);
__ LoadTaggedClassIdMayBeSmi(result, object);
}
+1 -9
View File
@@ -939,15 +939,7 @@ LocationSummary* LoadClassIdInstr::MakeLocationSummary(Isolate* isolate,
void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register object = locs()->in(0).reg();
Register result = locs()->out(0).reg();
Label load, done;
__ testl(object, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &load, Assembler::kNearJump);
__ movl(result, Immediate(Smi::RawValue(kSmiCid)));
__ jmp(&done);
__ Bind(&load);
__ LoadClassId(result, object);
__ SmiTag(result);
__ Bind(&done);
__ LoadTaggedClassIdMayBeSmi(result, object);
}
+1 -9
View File
@@ -1019,15 +1019,7 @@ LocationSummary* LoadClassIdInstr::MakeLocationSummary(Isolate* isolate,
void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register object = locs()->in(0).reg();
Register result = locs()->out(0).reg();
Label load, done;
__ andi(CMPRES1, object, Immediate(kSmiTagMask));
__ bne(CMPRES1, ZR, &load);
__ LoadImmediate(result, Smi::RawValue(kSmiCid));
__ b(&done);
__ Bind(&load);
__ LoadClassId(result, object);
__ SmiTag(result);
__ Bind(&done);
__ LoadTaggedClassIdMayBeSmi(result, object);
}
+1 -9
View File
@@ -868,15 +868,7 @@ LocationSummary* LoadClassIdInstr::MakeLocationSummary(Isolate* isolate,
void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
Register object = locs()->in(0).reg();
Register result = locs()->out(0).reg();
Label load, done;
__ testq(object, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &load, Assembler::kNearJump);
__ LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)), PP);
__ jmp(&done);
__ Bind(&load);
__ LoadClassId(result, object);
__ SmiTag(result);
__ Bind(&done);
__ LoadTaggedClassIdMayBeSmi(result, object);
}
+4 -15
View File
@@ -1283,7 +1283,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// Preserve return address, since LR is needed for subroutine call.
__ mov(R8, Operand(LR));
// Loop that checks if there is an IC data match.
Label loop, update, test, found, get_class_id_as_smi;
Label loop, update, test, found;
// R5: IC data object (preserved).
__ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
// R6: ic_data_array with check entries: classes and target functions.
@@ -1295,7 +1295,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
__ sub(R7, R7, Operand(Smi::RawValue(1)));
__ ldr(R0, Address(SP, R7, LSL, 1)); // R7 (argument_count - 1) is smi.
__ bl(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(R0, R0);
// R7: argument_count - 1 (smi).
// R0: receiver's class ID (smi).
__ ldr(R1, Address(R6, 0)); // First class id (smi) to check.
@@ -1307,7 +1307,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// If not the first, load the next argument's class ID.
__ AddImmediate(R0, R7, Smi::RawValue(-i));
__ ldr(R0, Address(SP, R0, LSL, 1));
__ bl(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(R0, R0);
// R0: next argument class ID (smi).
__ LoadFromOffset(kWord, R1, R6, i * kWordSize);
// R1: next class ID to check (smi).
@@ -1325,7 +1325,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// Reload receiver class ID. It has not been destroyed when num_args == 1.
if (num_args > 1) {
__ ldr(R0, Address(SP, R7, LSL, 1));
__ bl(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(R0, R0);
}
const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
@@ -1385,17 +1385,6 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ ldr(R2, FieldAddress(R0, Function::instructions_offset()));
__ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
__ bx(R2);
// Instance in R0, return its class-id in R0 as Smi.
__ Bind(&get_class_id_as_smi);
// Test if Smi -> load Smi class for comparison.
__ tst(R0, Operand(kSmiTagMask));
__ mov(R0, Operand(Smi::RawValue(kSmiCid)), EQ);
__ bx(LR, EQ);
__ LoadClassId(R0, R0);
__ SmiTag(R0);
__ bx(LR);
}
+3 -45
View File
@@ -1387,23 +1387,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// R0 <- [SP + (R7 << 3)]
__ ldr(R0, Address(SP, R7, UXTX, Address::Scaled));
{
// TODO(zra): Put this code in a subroutine call as with other architectures
// when we have a bl(Label& l) instruction.
// Instance in R0, return its class-id in R0 as Smi.
// Test if Smi -> load Smi class for comparison.
Label not_smi, done;
__ tsti(R0, kSmiTagMask);
__ b(&not_smi, NE);
__ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP);
__ b(&done);
__ Bind(&not_smi);
__ LoadClassId(R0, R0, kNoPP);
__ SmiTag(R0);
__ Bind(&done);
}
__ LoadTaggedClassIdMayBeSmi(R0, R0);
// R7: argument_count - 1 (untagged).
// R0: receiver's class ID (smi).
@@ -1417,20 +1401,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ AddImmediate(R0, R7, -i, kNoPP);
// R0 <- [SP + (R0 << 3)]
__ ldr(R0, Address(SP, R0, UXTX, Address::Scaled));
{
// Instance in R0, return its class-id in R0 as Smi.
// Test if Smi -> load Smi class for comparison.
Label not_smi, done;
__ tsti(R0, kSmiTagMask);
__ b(&not_smi, NE);
__ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP);
__ b(&done);
__ Bind(&not_smi);
__ LoadClassId(R0, R0, kNoPP);
__ SmiTag(R0);
__ Bind(&done);
}
__ LoadTaggedClassIdMayBeSmi(R0, R0);
// R0: next argument class ID (smi).
__ LoadFromOffset(R1, R6, i * kWordSize, kNoPP);
// R1: next class ID to check (smi).
@@ -1447,20 +1418,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// Reload receiver class ID. It has not been destroyed when num_args == 1.
if (num_args > 1) {
__ ldr(R0, Address(SP, R7, UXTX, Address::Scaled));
{
// Instance in R0, return its class-id in R0 as Smi.
// Test if Smi -> load Smi class for comparison.
Label not_smi, done;
__ tsti(R0, kSmiTagMask);
__ b(&not_smi, NE);
__ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP);
__ b(&done);
__ Bind(&not_smi);
__ LoadClassId(R0, R0, kNoPP);
__ SmiTag(R0);
__ Bind(&done);
}
__ LoadTaggedClassIdMayBeSmi(R0, R0);
}
const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
+7 -18
View File
@@ -1321,7 +1321,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// Load arguments descriptor into EDX.
__ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
// Loop that checks if there is an IC data match.
Label loop, update, test, found, get_class_id_as_smi;
Label loop, update, test, found;
// ECX: IC data object (preserved).
__ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
// EBX: ic_data_array with check entries: classes and target functions.
@@ -1332,7 +1332,8 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// arguments descriptor array and then access the receiver from the stack).
__ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
__ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is smi.
__ call(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(EAX, EAX);
// EAX: receiver's class ID (smi).
__ movl(EDI, Address(EBX, 0)); // First class id (smi) to check.
__ jmp(&test);
@@ -1343,7 +1344,8 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// If not the first, load the next argument's class ID.
__ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
__ movl(EAX, Address(ESP, EAX, TIMES_2, - i * kWordSize));
__ call(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(EAX, EAX);
// EAX: next argument class ID (smi).
__ movl(EDI, Address(EBX, i * kWordSize));
// EDI: next class ID to check (smi).
@@ -1361,7 +1363,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
if (num_args > 1) {
__ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
__ movl(EAX, Address(ESP, EAX, TIMES_2, 0));
__ call(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(EAX, EAX);
}
const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
@@ -1418,20 +1420,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
__ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
__ jmp(EBX);
// Instance in EAX, return its class-id in EAX as Smi.
__ Bind(&get_class_id_as_smi);
Label not_smi;
// Test if Smi -> load Smi class for comparison.
__ testl(EAX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
__ movl(EAX, Immediate(Smi::RawValue(kSmiCid)));
__ ret();
__ Bind(&not_smi);
__ LoadClassId(EAX, EAX);
__ SmiTag(EAX);
__ ret();
__ int3();
}
+8 -21
View File
@@ -1445,7 +1445,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// Preserve return address, since RA is needed for subroutine call.
__ mov(T2, RA);
// Loop that checks if there is an IC data match.
Label loop, update, test, found, get_class_id_as_smi;
Label loop, update, test, found;
// S5: IC data object (preserved).
__ lw(T0, FieldAddress(S5, ICData::ic_data_offset()));
// T0: ic_data_array with check entries: classes and target functions.
@@ -1459,8 +1459,9 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ subu(T1, T1, TMP);
__ sll(T3, T1, 1); // T1 (argument_count - 1) is smi.
__ addu(T3, T3, SP);
__ bal(&get_class_id_as_smi);
__ delay_slot()->lw(T3, Address(T3));
__ lw(T3, Address(T3));
__ LoadTaggedClassIdMayBeSmi(T3, T3);
// T1: argument_count - 1 (smi).
// T3: receiver's class ID (smi).
__ b(&test);
@@ -1474,8 +1475,8 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ addu(T3, T1, T3);
__ sll(T3, T3, 1);
__ addu(T3, SP, T3);
__ bal(&get_class_id_as_smi);
__ delay_slot()->lw(T3, Address(T3));
__ lw(T3, Address(T3));
__ LoadTaggedClassIdMayBeSmi(T3, T3);
// T3: next argument class ID (smi).
__ lw(T4, Address(T0, i * kWordSize));
// T4: next class ID to check (smi).
@@ -1496,8 +1497,8 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
if (num_args > 1) {
__ sll(T3, T1, 1);
__ addu(T3, T3, SP);
__ bal(&get_class_id_as_smi);
__ delay_slot()->lw(T3, Address(T3));
__ lw(T3, Address(T3));
__ LoadTaggedClassIdMayBeSmi(T3, T3);
}
const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
@@ -1572,20 +1573,6 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ lw(T4, FieldAddress(T0, Function::instructions_offset()));
__ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag);
__ jr(T4);
// Instance in T3, return its class-id in T3 as Smi.
__ Bind(&get_class_id_as_smi);
Label not_smi;
// Test if Smi -> load Smi class for comparison.
__ andi(CMPRES1, T3, Immediate(kSmiTagMask));
__ bne(CMPRES1, ZR, &not_smi);
__ jr(RA);
__ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid)));
__ Bind(&not_smi);
__ LoadClassId(T3, T3);
__ jr(RA);
__ delay_slot()->SmiTag(T3);
}
+4 -17
View File
@@ -1248,7 +1248,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// Load arguments descriptor into R10.
__ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
// Loop that checks if there is an IC data match.
Label loop, update, test, found, get_class_id_as_smi;
Label loop, update, test, found;
// RBX: IC data object (preserved).
__ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
// R12: ic_data_array with check entries: classes and target functions.
@@ -1259,7 +1259,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// arguments descriptor array and then access the receiver from the stack).
__ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
__ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi.
__ call(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(RAX, RAX);
// RAX: receiver's class ID as smi.
__ movq(R13, Address(R12, 0)); // First class ID (Smi) to check.
__ jmp(&test);
@@ -1270,7 +1270,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
// If not the first, load the next argument's class ID.
__ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
__ movq(RAX, Address(RSP, RAX, TIMES_4, - i * kWordSize));
__ call(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(RAX, RAX);
// RAX: next argument class ID (smi).
__ movq(R13, Address(R12, i * kWordSize));
// R13: next class ID to check (smi).
@@ -1288,7 +1288,7 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
if (num_args > 1) {
__ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
__ movq(RAX, Address(RSP, RAX, TIMES_4, 0));
__ call(&get_class_id_as_smi);
__ LoadTaggedClassIdMayBeSmi(RAX, RAX);
}
const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
@@ -1343,19 +1343,6 @@ void StubCode::GenerateNArgsCheckInlineCacheStub(
__ movq(RCX, FieldAddress(RAX, Function::instructions_offset()));
__ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
__ jmp(RCX);
__ Bind(&get_class_id_as_smi);
Label not_smi;
// Test if Smi -> load Smi class for comparison.
__ testq(RAX, Immediate(kSmiTagMask));
__ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
__ movq(RAX, Immediate(Smi::RawValue(kSmiCid)));
__ ret();
__ Bind(&not_smi);
__ LoadClassId(RAX, RAX);
__ SmiTag(RAX);
__ ret();
}