diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc index b6d5e16a7d4..16bcf48cd9e 100644 --- a/runtime/vm/assembler_arm.cc +++ b/runtime/vm/assembler_arm.cc @@ -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); diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h index 80b530853d1..4469027341e 100644 --- a/runtime/vm/assembler_arm.h +++ b/runtime/vm/assembler_arm.h @@ -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, diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc index 0b3ddf16400..c6d4457482a 100644 --- a/runtime/vm/assembler_arm64.cc +++ b/runtime/vm/assembler_arm64.cc @@ -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 diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h index f6f01d0f5bd..475ed21e0c6 100644 --- a/runtime/vm/assembler_arm64.h +++ b/runtime/vm/assembler_arm64.h @@ -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(); diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc index f219e8ee9fc..6c36ecf3e2c 100644 --- a/runtime/vm/assembler_ia32.cc +++ b/runtime/vm/assembler_ia32.cc @@ -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, ¬_smi, Assembler::kNearJump); + movl(result, Immediate(Smi::RawValue(kSmiCid))); + jmp(&done, Assembler::kNearJump); + Bind(¬_smi); + LoadClassId(result, object); + SmiTag(result); + Bind(&done); +} + + static const char* cpu_reg_names[kNumberOfCpuRegisters] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" }; diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h index f502bd51f8b..6688eca9b9c 100644 --- a/runtime/vm/assembler_ia32.h +++ b/runtime/vm/assembler_ia32.h @@ -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 */ diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc index f4a4f6e4356..af16a320928 100644 --- a/runtime/vm/assembler_mips.cc +++ b/runtime/vm/assembler_mips.cc @@ -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)); diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h index efbb467fb41..a4428c69f9c 100644 --- a/runtime/vm/assembler_mips.h +++ b/runtime/vm/assembler_mips.h @@ -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. diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc index c04809ed9bd..05db770a303 100644 --- a/runtime/vm/assembler_x64.cc +++ b/runtime/vm/assembler_x64.cc @@ -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" diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h index 70f345ed6b8..84ba32016be 100644 --- a/runtime/vm/assembler_x64.h +++ b/runtime/vm/assembler_x64.h @@ -737,6 +737,8 @@ class Assembler : public ValueObject { void CompareClassId(Register object, intptr_t class_id); + void LoadTaggedClassIdMayBeSmi(Register result, Register object); + /* * Misc. functionality. */ diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc index bfc41b5a95d..55d6f8e1f78 100644 --- a/runtime/vm/flow_graph_compiler_arm.cc +++ b/runtime/vm/flow_graph_compiler_arm.cc @@ -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())); diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc index 09a20f348f1..260955ee205 100644 --- a/runtime/vm/flow_graph_compiler_arm64.cc +++ b/runtime/vm/flow_graph_compiler_arm64.cc @@ -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(¬_smi, NE); - __ LoadImmediate(R0, Smi::RawValue(kSmiCid), PP); - __ b(&load_cache); - - __ Bind(¬_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); diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc index 247e537f0de..1f14dc62b81 100644 --- a/runtime/vm/flow_graph_compiler_ia32.cc +++ b/runtime/vm/flow_graph_compiler_ia32.cc @@ -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, ¬_smi, Assembler::kNearJump); - __ movl(EAX, Immediate(Smi::RawValue(kSmiCid))); - __ jmp(&load_cache); - - __ Bind(¬_smi); - __ LoadClassId(EAX, EAX); - __ SmiTag(EAX); + __ LoadTaggedClassIdMayBeSmi(EAX, EAX); // EAX: class ID of the receiver (smi). __ Bind(&load_cache); diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc index afc91328925..8a75aef9c7f 100644 --- a/runtime/vm/flow_graph_compiler_mips.cc +++ b/runtime/vm/flow_graph_compiler_mips.cc @@ -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, ¬_smi); - __ LoadImmediate(T0, Smi::RawValue(kSmiCid)); - __ b(&load_cache); - - __ Bind(¬_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())); diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc index 01629eac014..164fd1e407e 100644 --- a/runtime/vm/flow_graph_compiler_x64.cc +++ b/runtime/vm/flow_graph_compiler_x64.cc @@ -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, ¬_smi, Assembler::kNearJump); - __ LoadImmediate(RAX, Immediate(Smi::RawValue(kSmiCid)), PP); - __ jmp(&load_cache); - - __ Bind(¬_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())); diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc index 6e3892466d1..78a88513bfd 100644 --- a/runtime/vm/intermediate_language_arm.cc +++ b/runtime/vm/intermediate_language_arm.cc @@ -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); } diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc index 1e1ae7706f2..d5115be2555 100644 --- a/runtime/vm/intermediate_language_arm64.cc +++ b/runtime/vm/intermediate_language_arm64.cc @@ -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); } diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc index e25e90eca5a..63c6a9ef8b5 100644 --- a/runtime/vm/intermediate_language_ia32.cc +++ b/runtime/vm/intermediate_language_ia32.cc @@ -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); } diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc index b8ba0c03162..53e72a379a4 100644 --- a/runtime/vm/intermediate_language_mips.cc +++ b/runtime/vm/intermediate_language_mips.cc @@ -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); } diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc index 90aeed887f0..f999bddfbcd 100644 --- a/runtime/vm/intermediate_language_x64.cc +++ b/runtime/vm/intermediate_language_x64.cc @@ -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); } diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc index 4f1c8c36d58..b0ef21f3a26 100644 --- a/runtime/vm/stub_code_arm.cc +++ b/runtime/vm/stub_code_arm.cc @@ -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); } diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc index ef208980772..b2f0db8adfb 100644 --- a/runtime/vm/stub_code_arm64.cc +++ b/runtime/vm/stub_code_arm64.cc @@ -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(¬_smi, NE); - __ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP); - __ b(&done); - - __ Bind(¬_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(¬_smi, NE); - __ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP); - __ b(&done); - - __ Bind(¬_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(¬_smi, NE); - __ LoadImmediate(R0, Smi::RawValue(kSmiCid), kNoPP); - __ b(&done); - - __ Bind(¬_smi); - __ LoadClassId(R0, R0, kNoPP); - __ SmiTag(R0); - __ Bind(&done); - } + __ LoadTaggedClassIdMayBeSmi(R0, R0); } const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc index 8c1e3b9eb12..6389cbdd543 100644 --- a/runtime/vm/stub_code_ia32.cc +++ b/runtime/vm/stub_code_ia32.cc @@ -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, ¬_smi, Assembler::kNearJump); - __ movl(EAX, Immediate(Smi::RawValue(kSmiCid))); - __ ret(); - - __ Bind(¬_smi); - __ LoadClassId(EAX, EAX); - __ SmiTag(EAX); - __ ret(); + __ int3(); } diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc index 604045a9e8f..73744546c20 100644 --- a/runtime/vm/stub_code_mips.cc +++ b/runtime/vm/stub_code_mips.cc @@ -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, ¬_smi); - __ jr(RA); - __ delay_slot()->addiu(T3, ZR, Immediate(Smi::RawValue(kSmiCid))); - - __ Bind(¬_smi); - __ LoadClassId(T3, T3); - __ jr(RA); - __ delay_slot()->SmiTag(T3); } diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc index cafb2180655..490d4736929 100644 --- a/runtime/vm/stub_code_x64.cc +++ b/runtime/vm/stub_code_x64.cc @@ -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, ¬_smi, Assembler::kNearJump); - __ movq(RAX, Immediate(Smi::RawValue(kSmiCid))); - __ ret(); - - __ Bind(¬_smi); - __ LoadClassId(RAX, RAX); - __ SmiTag(RAX); - __ ret(); }