| Index: runtime/vm/intermediate_language_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_ia32.cc (revision 35689)
|
| +++ runtime/vm/intermediate_language_ia32.cc (working copy)
|
| @@ -3289,7 +3289,8 @@
|
|
|
|
|
| void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
| - const intptr_t value_cid = value()->Type()->ToCid();
|
| + CompileType* value_type = value()->Type();
|
| + const intptr_t value_cid = value_type->ToCid();
|
| const Register value = locs()->in(0).reg();
|
| const XmmRegister result = locs()->out(0).fpu_reg();
|
|
|
| @@ -3302,18 +3303,28 @@
|
| Label* deopt = compiler->AddDeoptStub(deopt_id_,
|
| ICData::kDeoptBinaryDoubleOp);
|
| Register temp = locs()->temp(0).reg();
|
| - Label is_smi, done;
|
| - __ testl(value, Immediate(kSmiTagMask));
|
| - __ j(ZERO, &is_smi);
|
| - __ CompareClassId(value, kDoubleCid, temp);
|
| - __ j(NOT_EQUAL, deopt);
|
| - __ movsd(result, FieldAddress(value, Double::value_offset()));
|
| - __ jmp(&done);
|
| - __ Bind(&is_smi);
|
| - __ movl(temp, value);
|
| - __ SmiUntag(temp);
|
| - __ cvtsi2sd(result, temp);
|
| - __ Bind(&done);
|
| + if (value_type->is_nullable() &&
|
| + (value_type->ToNullableCid() == kDoubleCid)) {
|
| + const Immediate& raw_null =
|
| + Immediate(reinterpret_cast<intptr_t>(Object::null()));
|
| + __ cmpl(value, raw_null);
|
| + __ j(EQUAL, deopt);
|
| + // It must be double now.
|
| + __ movsd(result, FieldAddress(value, Double::value_offset()));
|
| + } else {
|
| + Label is_smi, done;
|
| + __ testl(value, Immediate(kSmiTagMask));
|
| + __ j(ZERO, &is_smi);
|
| + __ CompareClassId(value, kDoubleCid, temp);
|
| + __ j(NOT_EQUAL, deopt);
|
| + __ movsd(result, FieldAddress(value, Double::value_offset()));
|
| + __ jmp(&done);
|
| + __ Bind(&is_smi);
|
| + __ movl(temp, value);
|
| + __ SmiUntag(temp);
|
| + __ cvtsi2sd(result, temp);
|
| + __ Bind(&done);
|
| + }
|
| }
|
| }
|
|
|
|
|