| Index: runtime/vm/intermediate_language_x64.cc
|
| diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
|
| index 8253b0cbdee7a1a09cb307744d7862a17355733a..e1a73e86f6f71c0c71cca773398d89d2df2f59f1 100644
|
| --- a/runtime/vm/intermediate_language_x64.cc
|
| +++ b/runtime/vm/intermediate_language_x64.cc
|
| @@ -926,19 +926,25 @@ LocationSummary* LoadClassIdInstr::MakeLocationSummary(Zone* zone,
|
| void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| const Register object = locs()->in(0).reg();
|
| const Register result = locs()->out(0).reg();
|
| - Label load, done;
|
| -
|
| - // We don't use Assembler::LoadTaggedClassIdMayBeSmi() here---which uses
|
| - // a conditional move instead---because it is slower, probably due to
|
| - // branch prediction usually working just fine in this case.
|
| - __ testq(object, Immediate(kSmiTagMask));
|
| - __ j(NOT_ZERO, &load, Assembler::kNearJump);
|
| - __ LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)));
|
| - __ jmp(&done);
|
| - __ Bind(&load);
|
| - __ LoadClassId(result, object);
|
| - __ SmiTag(result);
|
| - __ Bind(&done);
|
| + const AbstractType& value_type = *this->object()->Type()->ToAbstractType();
|
| + if (CompileType::Smi().IsAssignableTo(value_type) ||
|
| + value_type.IsTypeParameter()) {
|
| + // We don't use Assembler::LoadTaggedClassIdMayBeSmi() here---which uses
|
| + // a conditional move instead---because it is slower, probably due to
|
| + // branch prediction usually working just fine in this case.
|
| + Label load, done;
|
| + __ testq(object, Immediate(kSmiTagMask));
|
| + __ j(NOT_ZERO, &load, Assembler::kNearJump);
|
| + __ LoadImmediate(result, Immediate(Smi::RawValue(kSmiCid)));
|
| + __ jmp(&done);
|
| + __ Bind(&load);
|
| + __ LoadClassId(result, object);
|
| + __ SmiTag(result);
|
| + __ Bind(&done);
|
| + } else {
|
| + __ LoadClassId(result, object);
|
| + __ SmiTag(result);
|
| + }
|
| }
|
|
|
|
|
|
|