Index: runtime/vm/assembler_x64.cc |
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc |
index d463af6d15399d3934fbc256f797984b64a2055a..4d3cfad88e3f4a8d41fdbe5b9a7368845ff520b4 100644 |
--- a/runtime/vm/assembler_x64.cc |
+++ b/runtime/vm/assembler_x64.cc |
@@ -1681,6 +1681,14 @@ void Assembler::orl(Register dst, const Immediate& imm) { |
} |
+void Assembler::orl(const Address& address, Register reg) { |
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
+ EmitOperandREX(reg, address, REX_NONE); |
+ EmitUint8(0x09); |
+ EmitOperand(reg & 7, address); |
+} |
+ |
+ |
void Assembler::xorl(Register dst, Register src) { |
AssemblerBuffer::EnsureCapacity ensured(&buffer_); |
Operand operand(src); |
@@ -3780,6 +3788,50 @@ void Assembler::LoadTaggedClassIdMayBeSmi(Register result, Register object) { |
} |
+void Assembler::ComputeRange(Register result, Register value, Label* not_mint) { |
+ Label done, not_smi; |
+ testl(value, Immediate(kSmiTagMask)); |
+ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); |
+ |
+ sarq(value, Immediate(32)); // Take the tag into account. |
+ movq(result, Immediate(ICData::kUint32RangeBit)); // Uint32 |
+ cmpq(value, Immediate(1)); |
+ j(EQUAL, &done, Assembler::kNearJump); |
+ |
+ movq(result, Immediate(ICData::kInt32RangeBit)); |
+ subq(result, value); // 10 (positive int32), 11 (negative int32) |
+ negq(value); |
+ cmpq(value, Immediate(1)); |
+ j(BELOW_EQUAL, &done); |
+ |
+ // On 64-bit we don't need to track sign of smis outside of the Int32 range. |
+ // Just pretend they are all signed. |
+ movq(result, Immediate(ICData::kSignedRangeBit)); |
+ jmp(&done); |
+ |
+ Bind(¬_smi); |
+ CompareClassId(value, kMintCid); |
+ j(NOT_EQUAL, not_mint); |
+ movq(result, Immediate(ICData::kInt64RangeBit)); |
+ |
+ Bind(&done); |
+} |
+ |
+ |
+void Assembler::UpdateRangeFeedback(Register value, |
+ intptr_t index, |
+ Register ic_data, |
+ Register scratch, |
+ Label* miss) { |
+ ASSERT(ICData::IsValidRangeFeedbackIndex(index)); |
+ ComputeRange(scratch, value, miss); |
+ if (index != 0) { |
+ shll(scratch, Immediate(ICData::kBitsPerRangeFeedback * index)); |
+ } |
+ orl(FieldAddress(ic_data, ICData::range_feedback_offset()), scratch); |
+} |
+ |
+ |
Address Assembler::ElementAddressForIntIndex(bool is_external, |
intptr_t cid, |
intptr_t index_scale, |