Revert "[vm] Add data field to TypedData"
This reverts commit d1085e80bed1440d2981def3d37b36dcd4d57d9f.
Reason for revert: performance regressions.
Original change's description:
> [vm] Add data field to TypedData
>
> This is the first step towards unification of TypedData and
> ExternalTypedData.
>
> Issue: https://github.com/dart-lang/sdk/issues/34796
> Change-Id: I8aec72030e251f9cd9f00fc5073f8e42b83a8d17
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/79430
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>
> Reviewed-by: Ryan Macnak <rmacnak@google.com>
TBR=vegorov@google.com,kustermann@google.com,rmacnak@google.com,alexmarkov@google.com,regis@google.com
# Not skipping CQ checks because original CL landed > 1 day ago.
Issue: https://github.com/dart-lang/sdk/issues/34796
Change-Id: Ia11d8c3af0af29d49c3dbf36a3fe7041fbf9aae3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97166
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 972d93e..126d193 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -3372,8 +3372,7 @@
Deserializer::InitializeHeader(
data, cid_, TypedData::InstanceSize(length_in_bytes), is_canonical);
data->ptr()->length_ = Smi::New(length);
- data->ResetData();
- uint8_t* cdata = data->ptr()->data();
+ uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
d->ReadBytes(cdata, length_in_bytes);
}
}
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm.cc b/runtime/vm/compiler/asm_intrinsifier_arm.cc
index cf5264e..c00607e 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -165,8 +165,6 @@
__ LoadImmediate(R8, 0); \
__ mov(R9, Operand(R8)); \
__ AddImmediate(R3, R0, target::TypedData::InstanceSize() - 1); \
- __ StoreIntoObjectNoBarrier( \
- R0, FieldAddress(R0, target::TypedData::data_offset()), R3); \
Label init_loop; \
__ Bind(&init_loop); \
__ AddImmediate(R3, 2 * target::kWordSize); \
@@ -695,12 +693,13 @@
// R4 = n ~/ _DIGIT_BITS
__ Asr(R4, R3, Operand(5));
// R8 = &x_digits[0]
- __ ldr(R8, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R8, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// NOTFP = &x_digits[x_used]
__ add(NOTFP, R8, Operand(R0, LSL, 1));
// R6 = &r_digits[1]
- __ ldr(R6, FieldAddress(R2, target::TypedData::data_offset()));
- __ add(R6, R6, Operand(kBytesPerBigIntDigit));
+ __ add(R6, R2,
+ Operand(target::TypedData::data_offset() - kHeapObjectTag +
+ kBytesPerBigIntDigit));
// R6 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
__ add(R4, R4, Operand(R0, ASR, 1));
__ add(R6, R6, Operand(R4, LSL, 2));
@@ -734,9 +733,9 @@
// R4 = n ~/ _DIGIT_BITS
__ Asr(R4, R3, Operand(5));
// R6 = &r_digits[0]
- __ ldr(R6, FieldAddress(R2, target::TypedData::data_offset()));
+ __ add(R6, R2, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// NOTFP = &x_digits[n ~/ _DIGIT_BITS]
- __ ldr(NOTFP, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(NOTFP, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
__ add(NOTFP, NOTFP, Operand(R4, LSL, 2));
// R8 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
__ add(R4, R4, Operand(1));
@@ -774,17 +773,17 @@
// R0 = used, R1 = digits
__ ldrd(R0, R1, SP, 3 * target::kWordSize);
// R1 = &digits[0]
- __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R1, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R2 = a_used, R3 = a_digits
__ ldrd(R2, R3, SP, 1 * target::kWordSize);
// R3 = &a_digits[0]
- __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R8 = r_digits
__ ldr(R8, Address(SP, 0 * target::kWordSize));
// R8 = &r_digits[0]
- __ ldr(R8, FieldAddress(R8, target::TypedData::data_offset()));
+ __ add(R8, R8, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// NOTFP = &digits[a_used >> 1], a_used is Smi.
__ add(NOTFP, R1, Operand(R2, LSL, 1));
@@ -834,17 +833,17 @@
// R0 = used, R1 = digits
__ ldrd(R0, R1, SP, 3 * target::kWordSize);
// R1 = &digits[0]
- __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R1, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R2 = a_used, R3 = a_digits
__ ldrd(R2, R3, SP, 1 * target::kWordSize);
// R3 = &a_digits[0]
- __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R8 = r_digits
__ ldr(R8, Address(SP, 0 * target::kWordSize));
// R8 = &r_digits[0]
- __ ldr(R8, FieldAddress(R8, target::TypedData::data_offset()));
+ __ add(R8, R8, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// NOTFP = &digits[a_used >> 1], a_used is Smi.
__ add(NOTFP, R1, Operand(R2, LSL, 1));
@@ -913,8 +912,8 @@
Label done;
// R3 = x, no_op if x == 0
__ ldrd(R0, R1, SP, 5 * target::kWordSize); // R0 = xi as Smi, R1 = x_digits.
+ __ add(R1, R1, Operand(R0, LSL, 1));
__ ldr(R3, FieldAddress(R1, target::TypedData::data_offset()));
- __ ldr(R3, Address(R3, R0, LSL, 1));
__ tst(R3, Operand(R3));
__ b(&done, EQ);
@@ -925,13 +924,13 @@
// R4 = mip = &m_digits[i >> 1]
__ ldrd(R0, R1, SP, 3 * target::kWordSize); // R0 = i as Smi, R1 = m_digits.
- __ ldr(R4, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R4, R4, Operand(R0, LSL, 1));
+ __ add(R1, R1, Operand(R0, LSL, 1));
+ __ add(R4, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R9 = ajp = &a_digits[j >> 1]
__ ldrd(R0, R1, SP, 1 * target::kWordSize); // R0 = j as Smi, R1 = a_digits.
- __ ldr(R9, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R9, R9, Operand(R0, LSL, 1));
+ __ add(R1, R1, Operand(R0, LSL, 1));
+ __ add(R9, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R1 = c = 0
__ mov(R1, Operand(0));
@@ -1013,8 +1012,8 @@
// R4 = xip = &x_digits[i >> 1]
__ ldrd(R2, R3, SP, 2 * target::kWordSize); // R2 = i as Smi, R3 = x_digits
- __ ldr(R4, FieldAddress(R3, target::TypedData::data_offset()));
- __ add(R4, R4, Operand(R2, LSL, 1));
+ __ add(R3, R3, Operand(R2, LSL, 1));
+ __ add(R4, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R3 = x = *xip++, return if x == 0
Label x_zero;
@@ -1024,8 +1023,8 @@
// NOTFP = ajp = &a_digits[i]
__ ldr(R1, Address(SP, 1 * target::kWordSize)); // a_digits
- __ ldr(NOTFP, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(NOTFP, NOTFP, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
+ __ add(R1, R1, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
+ __ add(NOTFP, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R8:R0 = t = x*x + *ajp
__ ldr(R0, Address(NOTFP, 0));
@@ -1113,24 +1112,24 @@
// return 1;
// }
- // R4 = &args[0]
+ // R4 = args
__ ldr(R4, Address(SP, 2 * target::kWordSize)); // args
- __ ldr(R4, FieldAddress(R4, target::TypedData::data_offset()));
// R3 = rho = args[2]
- __ ldr(R3, Address(R4, 2 * kBytesPerBigIntDigit));
+ __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset() +
+ 2 * kBytesPerBigIntDigit));
// R2 = digits[i >> 1]
__ ldrd(R0, R1, SP, 0 * target::kWordSize); // R0 = i as Smi, R1 = digits
+ __ add(R1, R1, Operand(R0, LSL, 1));
__ ldr(R2, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R2, R2, Operand(R0, LSL, 1));
- __ ldr(R2, Address(R2));
// R1:R0 = t = rho*d
__ umull(R0, R1, R2, R3);
// args[4] = t mod DIGIT_BASE = low32(t)
- __ str(R0, Address(R4, 4 * kBytesPerBigIntDigit));
+ __ str(R0, FieldAddress(R4, target::TypedData::data_offset() +
+ 4 * kBytesPerBigIntDigit));
__ mov(R0, Operand(target::ToRawSmi(1))); // One digit processed.
__ Ret();
@@ -1496,7 +1495,6 @@
// Field '_state'.
__ ldr(R1, FieldAddress(R0, LookupFieldOffsetInBytes(state_field)));
// Addresses of _state[0] and _state[1].
- __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
const int64_t disp_0 =
target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
@@ -1504,13 +1502,13 @@
disp_0 + target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
__ LoadImmediate(R0, a_int32_value);
- __ LoadFromOffset(kWord, R2, R1, disp_0);
- __ LoadFromOffset(kWord, R3, R1, disp_1);
+ __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
+ __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
__ mov(R8, Operand(0)); // Zero extend unsigned _state[kSTATE_HI].
// Unsigned 32-bit multiply and 64-bit accumulate into R8:R3.
__ umlal(R3, R8, R0, R2); // R8:R3 <- R8:R3 + R0 * R2.
- __ StoreToOffset(kWord, R3, R1, disp_0);
- __ StoreToOffset(kWord, R8, R1, disp_1);
+ __ StoreToOffset(kWord, R3, R1, disp_0 - kHeapObjectTag);
+ __ StoreToOffset(kWord, R8, R1, disp_1 - kHeapObjectTag);
ASSERT(target::ToRawSmi(0) == 0);
__ eor(R0, R0, Operand(R0));
__ Ret();
diff --git a/runtime/vm/compiler/asm_intrinsifier_arm64.cc b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
index 0153c00..6ba42cd 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -177,8 +177,6 @@
/* data area to be initialized. */ \
__ mov(R3, ZR); \
__ AddImmediate(R2, R0, target::TypedData::InstanceSize() - 1); \
- __ StoreIntoObjectNoBarrier( \
- R0, FieldAddress(R0, target::TypedData::data_offset()), R2); \
Label init_loop, done; \
__ Bind(&init_loop); \
__ cmp(R2, Operand(R1)); \
@@ -603,12 +601,13 @@
// R0 = n ~/ (2*_DIGIT_BITS)
__ AsrImmediate(R0, R5, 6);
// R6 = &x_digits[0]
- __ ldr(R6, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R6, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R7 = &x_digits[2*R2]
__ add(R7, R6, Operand(R2, LSL, 3));
// R8 = &r_digits[2*1]
- __ ldr(R8, FieldAddress(R4, target::TypedData::data_offset()));
- __ add(R8, R8, Operand(2 * kBytesPerBigIntDigit));
+ __ add(R8, R4,
+ Operand(target::TypedData::data_offset() - kHeapObjectTag +
+ 2 * kBytesPerBigIntDigit));
// R8 = &r_digits[2*(R2 + n ~/ (2*_DIGIT_BITS) + 1)]
__ add(R0, R0, Operand(R2));
__ add(R8, R8, Operand(R0, LSL, 3));
@@ -646,9 +645,9 @@
// R0 = n ~/ (2*_DIGIT_BITS)
__ AsrImmediate(R0, R5, 6);
// R8 = &r_digits[0]
- __ ldr(R8, FieldAddress(R4, target::TypedData::data_offset()));
+ __ add(R8, R4, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R7 = &x_digits[2*(n ~/ (2*_DIGIT_BITS))]
- __ ldr(R7, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R7, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
__ add(R7, R7, Operand(R0, LSL, 3));
// R6 = &r_digits[2*(R2 - n ~/ (2*_DIGIT_BITS) - 1)]
__ add(R0, R0, Operand(1));
@@ -690,19 +689,19 @@
__ add(R2, R2, Operand(2)); // used > 0, Smi. R2 = used + 1, round up.
__ add(R2, ZR, Operand(R2, ASR, 2)); // R2 = num of digit pairs to process.
// R3 = &digits[0]
- __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R4 = a_used, R5 = a_digits
__ ldp(R4, R5, Address(SP, 1 * target::kWordSize, Address::PairOffset));
__ add(R4, R4, Operand(2)); // a_used > 0, Smi. R4 = a_used + 1, round up.
__ add(R4, ZR, Operand(R4, ASR, 2)); // R4 = num of digit pairs to process.
// R5 = &a_digits[0]
- __ ldr(R5, FieldAddress(R5, target::TypedData::data_offset()));
+ __ add(R5, R5, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R6 = r_digits
__ ldr(R6, Address(SP, 0 * target::kWordSize));
// R6 = &r_digits[0]
- __ ldr(R6, FieldAddress(R6, target::TypedData::data_offset()));
+ __ add(R6, R6, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R7 = &digits[a_used rounded up to even number].
__ add(R7, R3, Operand(R4, LSL, 3));
@@ -756,19 +755,19 @@
__ add(R2, R2, Operand(2)); // used > 0, Smi. R2 = used + 1, round up.
__ add(R2, ZR, Operand(R2, ASR, 2)); // R2 = num of digit pairs to process.
// R3 = &digits[0]
- __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R4 = a_used, R5 = a_digits
__ ldp(R4, R5, Address(SP, 1 * target::kWordSize, Address::PairOffset));
__ add(R4, R4, Operand(2)); // a_used > 0, Smi. R4 = a_used + 1, round up.
__ add(R4, ZR, Operand(R4, ASR, 2)); // R4 = num of digit pairs to process.
// R5 = &a_digits[0]
- __ ldr(R5, FieldAddress(R5, target::TypedData::data_offset()));
+ __ add(R5, R5, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R6 = r_digits
__ ldr(R6, Address(SP, 0 * target::kWordSize));
// R6 = &r_digits[0]
- __ ldr(R6, FieldAddress(R6, target::TypedData::data_offset()));
+ __ add(R6, R6, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R7 = &digits[a_used rounded up to even number].
__ add(R7, R3, Operand(R4, LSL, 3));
@@ -839,9 +838,8 @@
// R3 = x, no_op if x == 0
// R0 = xi as Smi, R1 = x_digits.
__ ldp(R0, R1, Address(SP, 5 * target::kWordSize, Address::PairOffset));
+ __ add(R1, R1, Operand(R0, LSL, 1));
__ ldr(R3, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R3, R3, Operand(R0, LSL, 1));
- __ ldr(R3, Address(R3, 0));
__ tst(R3, Operand(R3));
__ b(&done, EQ);
@@ -854,14 +852,14 @@
// R4 = mip = &m_digits[i >> 1]
// R0 = i as Smi, R1 = m_digits.
__ ldp(R0, R1, Address(SP, 3 * target::kWordSize, Address::PairOffset));
- __ ldr(R4, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R4, R4, Operand(R0, LSL, 1));
+ __ add(R1, R1, Operand(R0, LSL, 1));
+ __ add(R4, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R5 = ajp = &a_digits[j >> 1]
// R0 = j as Smi, R1 = a_digits.
__ ldp(R0, R1, Address(SP, 1 * target::kWordSize, Address::PairOffset));
- __ ldr(R5, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R5, R5, Operand(R0, LSL, 1));
+ __ add(R1, R1, Operand(R0, LSL, 1));
+ __ add(R5, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R1 = c = 0
__ mov(R1, ZR);
@@ -948,8 +946,8 @@
// R4 = xip = &x_digits[i >> 1]
// R2 = i as Smi, R3 = x_digits
__ ldp(R2, R3, Address(SP, 2 * target::kWordSize, Address::PairOffset));
- __ ldr(R4, FieldAddress(R3, target::TypedData::data_offset()));
- __ add(R4, R4, Operand(R2, LSL, 1));
+ __ add(R3, R3, Operand(R2, LSL, 1));
+ __ add(R4, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R3 = x = *xip++, return if x == 0
Label x_zero;
@@ -959,8 +957,8 @@
// R5 = ajp = &a_digits[i]
__ ldr(R1, Address(SP, 1 * target::kWordSize)); // a_digits
- __ ldr(R5, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R5, R5, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
+ __ add(R1, R1, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
+ __ add(R5, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
// R6:R1 = t = x*x + *ajp
__ ldr(R0, Address(R5, 0));
@@ -1078,19 +1076,18 @@
// return 2;
// }
- // R4 = &args[0]
+ // R4 = args
__ ldr(R4, Address(SP, 2 * target::kWordSize)); // args
- __ ldr(R4, FieldAddress(R4, target::TypedData::data_offset()));
// R3 = yt = args[0..1]
- __ ldr(R3, Address(R4, 0));
+ __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset()));
// R2 = dh = digits[(i >> 1) - 1 .. i >> 1]
// R0 = i as Smi, R1 = digits
__ ldp(R0, R1, Address(SP, 0 * target::kWordSize, Address::PairOffset));
- __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
__ add(R1, R1, Operand(R0, LSL, 1));
- __ ldr(R2, Address(R1, -kBytesPerBigIntDigit));
+ __ ldr(R2, FieldAddress(
+ R1, target::TypedData::data_offset() - kBytesPerBigIntDigit));
// R0 = qd = (DIGIT_MASK << 32) | DIGIT_MASK = -1
__ movn(R0, Immediate(0), 0);
@@ -1101,7 +1098,8 @@
__ b(&return_qd, EQ);
// R1 = dl = digits[(i >> 1) - 3 .. (i >> 1) - 2]
- __ ldr(R1, Address(R1, -3 * kBytesPerBigIntDigit));
+ __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset() -
+ 3 * kBytesPerBigIntDigit));
// R5 = yth = yt >> 32
__ orr(R5, ZR, Operand(R3, LSR, 32));
@@ -1205,7 +1203,8 @@
__ Bind(&return_qd);
// args[2..3] = qd
- __ str(R0, Address(R4, 2 * kBytesPerBigIntDigit));
+ __ str(R0, FieldAddress(R4, target::TypedData::data_offset() +
+ 2 * kBytesPerBigIntDigit));
__ LoadImmediate(R0, target::ToRawSmi(2)); // Two digits processed.
__ ret();
@@ -1222,25 +1221,25 @@
// return 2;
// }
- // R4 = &args[0]
+ // R4 = args
__ ldr(R4, Address(SP, 2 * target::kWordSize)); // args
- __ ldr(R4, FieldAddress(R4, target::TypedData::data_offset()));
// R3 = rho = args[2..3]
- __ ldr(R3, Address(R4, 2 * kBytesPerBigIntDigit));
+ __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset() +
+ 2 * kBytesPerBigIntDigit));
// R2 = digits[i >> 1 .. (i >> 1) + 1]
// R0 = i as Smi, R1 = digits
__ ldp(R0, R1, Address(SP, 0 * target::kWordSize, Address::PairOffset));
+ __ add(R1, R1, Operand(R0, LSL, 1));
__ ldr(R2, FieldAddress(R1, target::TypedData::data_offset()));
- __ add(R2, R2, Operand(R0, LSL, 1));
- __ ldr(R2, Address(R2, 0));
// R0 = rho*d mod DIGIT_BASE
__ mul(R0, R2, R3); // R0 = low64(R2*R3).
// args[4 .. 5] = R0
- __ str(R0, Address(R4, 4 * kBytesPerBigIntDigit));
+ __ str(R0, FieldAddress(R4, target::TypedData::data_offset() +
+ 4 * kBytesPerBigIntDigit));
__ LoadImmediate(R0, target::ToRawSmi(2)); // Two digits processed.
__ ret();
@@ -1558,10 +1557,10 @@
// Field '_state'.
__ ldr(R1, FieldAddress(R0, LookupFieldOffsetInBytes(state_field)));
- // Address of _state[0].
- __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
+ // Addresses of _state[0].
const int64_t disp =
- target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
+ target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid) -
+ kHeapObjectTag;
__ LoadImmediate(R0, a_int_value);
__ LoadFromOffset(R2, R1, disp);
diff --git a/runtime/vm/compiler/asm_intrinsifier_ia32.cc b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
index 88c48f9..392d129 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -167,8 +167,6 @@
/* data area to be initialized. */ \
__ xorl(ECX, ECX); /* Zero. */ \
__ leal(EDI, FieldAddress(EAX, target::TypedData::InstanceSize())); \
- __ StoreIntoObjectNoBarrier( \
- EAX, FieldAddress(EAX, target::TypedData::data_offset()), EDI); \
Label done, init_loop; \
__ Bind(&init_loop); \
__ cmpl(EDI, EBX); \
@@ -715,14 +713,14 @@
__ movl(EBX, Address(ESP, 2 * target::kWordSize)); // r_digits
__ movl(ESI, ECX);
__ sarl(ESI, Immediate(5)); // ESI = n ~/ _DIGIT_BITS.
- __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
- __ leal(EBX, Address(EBX, ESI, TIMES_4, 0));
+ __ leal(EBX,
+ FieldAddress(EBX, ESI, TIMES_4, target::TypedData::data_offset()));
__ movl(ESI, Address(ESP, 4 * target::kWordSize)); // x_used > 0, Smi.
__ SmiUntag(ESI);
__ decl(ESI);
__ xorl(EAX, EAX); // EAX = 0.
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
- __ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
+ __ movl(EDX,
+ FieldAddress(EDI, ESI, TIMES_4, target::TypedData::data_offset()));
__ shldl(EAX, EDX, ECX);
__ movl(Address(EBX, ESI, TIMES_4, kBytesPerBigIntDigit), EAX);
Label last;
@@ -731,7 +729,9 @@
Label loop;
__ Bind(&loop);
__ movl(EAX, EDX);
- __ movl(EDX, Address(EDI, ESI, TIMES_4, -kBytesPerBigIntDigit));
+ __ movl(EDX, FieldAddress(
+ EDI, ESI, TIMES_4,
+ target::TypedData::data_offset() - kBytesPerBigIntDigit));
__ shldl(EAX, EDX, ECX);
__ movl(Address(EBX, ESI, TIMES_4, 0), EAX);
__ decl(ESI);
@@ -764,12 +764,12 @@
__ SmiUntag(ESI);
__ decl(ESI);
// EDI = &x_digits[x_used - 1].
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
- __ leal(EDI, Address(EDI, ESI, TIMES_4, 0));
+ __ leal(EDI,
+ FieldAddress(EDI, ESI, TIMES_4, target::TypedData::data_offset()));
__ subl(ESI, EDX);
// EBX = &r_digits[x_used - 1 - (n ~/ 32)].
- __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
- __ leal(EBX, Address(EBX, ESI, TIMES_4, 0));
+ __ leal(EBX,
+ FieldAddress(EBX, ESI, TIMES_4, target::TypedData::data_offset()));
__ negl(ESI);
__ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
Label last;
@@ -811,10 +811,6 @@
__ SmiUntag(ECX); // a_used > 0.
__ movl(EBX, Address(ESP, 2 * target::kWordSize)); // r_digits
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
- __ movl(ESI, FieldAddress(ESI, target::TypedData::data_offset()));
- __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
-
// Precompute 'used - a_used' now so that carry flag is not lost later.
__ subl(EAX, ECX);
__ incl(EAX); // To account for the extra test between loops.
@@ -824,9 +820,12 @@
Label add_loop;
__ Bind(&add_loop);
// Loop a_used times, ECX = a_used, ECX > 0.
- __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
- __ adcl(EAX, Address(ESI, EDX, TIMES_4, 0));
- __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
+ __ movl(EAX,
+ FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+ __ adcl(EAX,
+ FieldAddress(ESI, EDX, TIMES_4, target::TypedData::data_offset()));
+ __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+ EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
@@ -839,9 +838,11 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop used - a_used times, ECX = used - a_used, ECX > 0.
- __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
+ __ movl(EAX,
+ FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
__ adcl(EAX, Immediate(0));
- __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
+ __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+ EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -849,7 +850,8 @@
__ Bind(&last_carry);
__ movl(EAX, Immediate(0));
__ adcl(EAX, Immediate(0));
- __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
+ __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+ EAX);
// Restore THR and return.
__ popl(THR);
@@ -875,10 +877,6 @@
__ SmiUntag(ECX); // a_used > 0.
__ movl(EBX, Address(ESP, 2 * target::kWordSize)); // r_digits
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
- __ movl(ESI, FieldAddress(ESI, target::TypedData::data_offset()));
- __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
-
// Precompute 'used - a_used' now so that carry flag is not lost later.
__ subl(EAX, ECX);
__ incl(EAX); // To account for the extra test between loops.
@@ -888,9 +886,12 @@
Label sub_loop;
__ Bind(&sub_loop);
// Loop a_used times, ECX = a_used, ECX > 0.
- __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
- __ sbbl(EAX, Address(ESI, EDX, TIMES_4, 0));
- __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
+ __ movl(EAX,
+ FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+ __ sbbl(EAX,
+ FieldAddress(ESI, EDX, TIMES_4, target::TypedData::data_offset()));
+ __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+ EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
@@ -903,9 +904,11 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop used - a_used times, ECX = used - a_used, ECX > 0.
- __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
+ __ movl(EAX,
+ FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
__ sbbl(EAX, Immediate(0));
- __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
+ __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
+ EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -950,8 +953,8 @@
// EBX = x, no_op if x == 0
__ movl(ECX, Address(ESP, 7 * target::kWordSize)); // x_digits
__ movl(EAX, Address(ESP, 6 * target::kWordSize)); // xi is Smi
- __ movl(EBX, FieldAddress(ECX, target::TypedData::data_offset()));
- __ movl(EBX, Address(EBX, EAX, TIMES_2, 0));
+ __ movl(EBX,
+ FieldAddress(ECX, EAX, TIMES_2, target::TypedData::data_offset()));
__ testl(EBX, EBX);
__ j(ZERO, &no_op, Assembler::kNearJump);
@@ -967,14 +970,14 @@
// EDI = mip = &m_digits[i >> 1]
__ movl(EDI, Address(ESP, 6 * target::kWordSize)); // m_digits
__ movl(EAX, Address(ESP, 5 * target::kWordSize)); // i is Smi
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
- __ leal(EDI, Address(EDI, EAX, TIMES_2, 0));
+ __ leal(EDI,
+ FieldAddress(EDI, EAX, TIMES_2, target::TypedData::data_offset()));
// ESI = ajp = &a_digits[j >> 1]
__ movl(ESI, Address(ESP, 4 * target::kWordSize)); // a_digits
__ movl(EAX, Address(ESP, 3 * target::kWordSize)); // j is Smi
- __ movl(ESI, FieldAddress(ESI, target::TypedData::data_offset()));
- __ leal(ESI, Address(ESI, EAX, TIMES_2, 0));
+ __ leal(ESI,
+ FieldAddress(ESI, EAX, TIMES_2, target::TypedData::data_offset()));
// Save n
__ pushl(EDX);
@@ -1071,8 +1074,8 @@
// EDI = xip = &x_digits[i >> 1]
__ movl(EDI, Address(ESP, 4 * target::kWordSize)); // x_digits
__ movl(EAX, Address(ESP, 3 * target::kWordSize)); // i is Smi
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
- __ leal(EDI, Address(EDI, EAX, TIMES_2, 0));
+ __ leal(EDI,
+ FieldAddress(EDI, EAX, TIMES_2, target::TypedData::data_offset()));
// EBX = x = *xip++, return if x == 0
Label x_zero;
@@ -1087,8 +1090,8 @@
// ESI = ajp = &a_digits[i]
__ movl(ESI, Address(ESP, 3 * target::kWordSize)); // a_digits
- __ movl(ESI, FieldAddress(ESI, target::TypedData::data_offset()));
- __ leal(ESI, Address(ESI, EAX, TIMES_4, 0));
+ __ leal(ESI,
+ FieldAddress(ESI, EAX, TIMES_4, target::TypedData::data_offset()));
// EDX:EAX = t = x*x + *ajp
__ movl(EAX, EBX);
@@ -1193,18 +1196,18 @@
// return 1;
// }
- // EDI = &args[0]
+ // EDI = args
__ movl(EDI, Address(ESP, 3 * target::kWordSize)); // args
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
// ECX = yt = args[1]
- __ movl(ECX, Address(EDI, kBytesPerBigIntDigit));
+ __ movl(ECX, FieldAddress(EDI, target::TypedData::data_offset() +
+ kBytesPerBigIntDigit));
// EBX = dp = &digits[i >> 1]
__ movl(EBX, Address(ESP, 2 * target::kWordSize)); // digits
__ movl(EAX, Address(ESP, 1 * target::kWordSize)); // i is Smi
- __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
- __ leal(EBX, Address(EBX, EAX, TIMES_2, 0));
+ __ leal(EBX,
+ FieldAddress(EBX, EAX, TIMES_2, target::TypedData::data_offset()));
// EDX = dh = dp[0]
__ movl(EDX, Address(EBX, 0));
@@ -1225,7 +1228,9 @@
__ Bind(&return_qd);
// args[2] = qd
- __ movl(Address(EDI, 2 * kBytesPerBigIntDigit), EAX);
+ __ movl(FieldAddress(
+ EDI, target::TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
+ EAX);
__ movl(EAX, Immediate(target::ToRawSmi(1))); // One digit processed.
__ ret();
@@ -1242,24 +1247,26 @@
// return 1;
// }
- // EDI = &args[0]
+ // EDI = args
__ movl(EDI, Address(ESP, 3 * target::kWordSize)); // args
- __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
// ECX = rho = args[2]
- __ movl(ECX, Address(EDI, 2 * kBytesPerBigIntDigit));
+ __ movl(ECX, FieldAddress(EDI, target::TypedData::data_offset() +
+ 2 * kBytesPerBigIntDigit));
// EAX = digits[i >> 1]
__ movl(EBX, Address(ESP, 2 * target::kWordSize)); // digits
__ movl(EAX, Address(ESP, 1 * target::kWordSize)); // i is Smi
- __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
- __ movl(EAX, Address(EBX, EAX, TIMES_2, 0));
+ __ movl(EAX,
+ FieldAddress(EBX, EAX, TIMES_2, target::TypedData::data_offset()));
// EDX:EAX = t = rho*d
__ mull(ECX);
// args[4] = t mod DIGIT_BASE = low32(t)
- __ movl(Address(EDI, 4 * kBytesPerBigIntDigit), EAX);
+ __ movl(FieldAddress(
+ EDI, target::TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
+ EAX);
__ movl(EAX, Immediate(target::ToRawSmi(1))); // One digit processed.
__ ret();
@@ -1589,13 +1596,12 @@
// Field '_state'.
__ movl(EBX, FieldAddress(EAX, LookupFieldOffsetInBytes(state_field)));
// Addresses of _state[0] and _state[1].
- __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
const intptr_t scale =
target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
const intptr_t offset =
target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
- Address addr_0 = Address(EBX, 0 * scale + offset);
- Address addr_1 = Address(EBX, 1 * scale + offset);
+ Address addr_0 = FieldAddress(EBX, 0 * scale + offset);
+ Address addr_1 = FieldAddress(EBX, 1 * scale + offset);
__ movl(EAX, Immediate(a_int32_value));
// 64-bit multiply EAX * value -> EDX:EAX.
__ mull(addr_0);
diff --git a/runtime/vm/compiler/asm_intrinsifier_x64.cc b/runtime/vm/compiler/asm_intrinsifier_x64.cc
index 1532070..1c34df5 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -169,8 +169,6 @@
/* data area to be initialized. */ \
__ xorq(RBX, RBX); /* Zero. */ \
__ leaq(RDI, FieldAddress(RAX, target::TypedData::InstanceSize())); \
- __ StoreIntoObjectNoBarrier( \
- RAX, FieldAddress(RAX, target::TypedData::data_offset()), RDI); \
Label done, init_loop; \
__ Bind(&init_loop); \
__ cmpq(RDI, RCX); \
@@ -686,11 +684,11 @@
__ movq(RBX, Address(RSP, 1 * target::kWordSize)); // r_digits
__ movq(RSI, RCX);
__ sarq(RSI, Immediate(6)); // RSI = n ~/ (2*_DIGIT_BITS).
- __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
- __ leaq(RBX, Address(RBX, RSI, TIMES_8, 0));
+ __ leaq(RBX,
+ FieldAddress(RBX, RSI, TIMES_8, target::TypedData::data_offset()));
__ xorq(RAX, RAX); // RAX = 0.
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
- __ movq(RDX, Address(RDI, R8, TIMES_8, 0));
+ __ movq(RDX,
+ FieldAddress(RDI, R8, TIMES_8, target::TypedData::data_offset()));
__ shldq(RAX, RDX, RCX);
__ movq(Address(RBX, R8, TIMES_8, 2 * kBytesPerBigIntDigit), RAX);
Label last;
@@ -699,7 +697,9 @@
Label loop;
__ Bind(&loop);
__ movq(RAX, RDX);
- __ movq(RDX, Address(RDI, R8, TIMES_8, -2 * kBytesPerBigIntDigit));
+ __ movq(RDX, FieldAddress(RDI, R8, TIMES_8,
+ target::TypedData::data_offset() -
+ 2 * kBytesPerBigIntDigit));
__ shldq(RAX, RDX, RCX);
__ movq(Address(RBX, R8, TIMES_8, 0), RAX);
__ decq(R8);
@@ -724,11 +724,11 @@
__ movq(RSI, Address(RSP, 3 * target::kWordSize)); // x_used is Smi
__ subq(RSI, Immediate(2)); // x_used > 0, Smi. RSI = x_used - 1, round up.
__ sarq(RSI, Immediate(2));
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
- __ leaq(RDI, Address(RDI, RSI, TIMES_8, 0));
+ __ leaq(RDI,
+ FieldAddress(RDI, RSI, TIMES_8, target::TypedData::data_offset()));
__ subq(RSI, RDX); // RSI + 1 = number of digit pairs to read.
- __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
- __ leaq(RBX, Address(RBX, RSI, TIMES_8, 0));
+ __ leaq(RBX,
+ FieldAddress(RBX, RSI, TIMES_8, target::TypedData::data_offset()));
__ negq(RSI);
__ movq(RDX, Address(RDI, RSI, TIMES_8, 0));
Label last;
@@ -765,10 +765,6 @@
__ sarq(RCX, Immediate(2)); // R8 = number of digit pairs to process.
__ movq(RBX, Address(RSP, 1 * target::kWordSize)); // r_digits
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
- __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
- __ movq(RSI, FieldAddress(RSI, target::TypedData::data_offset()));
-
// Precompute 'used - a_used' now so that carry flag is not lost later.
__ subq(R8, RCX);
__ incq(R8); // To account for the extra test between loops.
@@ -777,9 +773,12 @@
Label add_loop;
__ Bind(&add_loop);
// Loop (a_used+1)/2 times, RCX > 0.
- __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
- __ adcq(RAX, Address(RSI, RDX, TIMES_8, 0));
- __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
+ __ movq(RAX,
+ FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+ __ adcq(RAX,
+ FieldAddress(RSI, RDX, TIMES_8, target::TypedData::data_offset()));
+ __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+ RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(RCX); // Does not affect carry flag.
__ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
@@ -791,9 +790,11 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
- __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
+ __ movq(RAX,
+ FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
__ adcq(RAX, Immediate(0));
- __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
+ __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+ RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(R8); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -801,7 +802,8 @@
__ Bind(&last_carry);
Label done;
__ j(NOT_CARRY, &done);
- __ movq(Address(RBX, RDX, TIMES_8, 0), Immediate(1));
+ __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+ Immediate(1));
__ Bind(&done);
__ LoadObject(RAX, NullObject());
@@ -824,10 +826,6 @@
__ sarq(RCX, Immediate(2)); // R8 = number of digit pairs to process.
__ movq(RBX, Address(RSP, 1 * target::kWordSize)); // r_digits
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
- __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
- __ movq(RSI, FieldAddress(RSI, target::TypedData::data_offset()));
-
// Precompute 'used - a_used' now so that carry flag is not lost later.
__ subq(R8, RCX);
__ incq(R8); // To account for the extra test between loops.
@@ -836,9 +834,12 @@
Label sub_loop;
__ Bind(&sub_loop);
// Loop (a_used+1)/2 times, RCX > 0.
- __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
- __ sbbq(RAX, Address(RSI, RDX, TIMES_8, 0));
- __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
+ __ movq(RAX,
+ FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+ __ sbbq(RAX,
+ FieldAddress(RSI, RDX, TIMES_8, target::TypedData::data_offset()));
+ __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+ RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(RCX); // Does not affect carry flag.
__ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
@@ -850,9 +851,11 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
- __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
+ __ movq(RAX,
+ FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
__ sbbq(RAX, Immediate(0));
- __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
+ __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
+ RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(R8); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -896,8 +899,8 @@
// RBX = x, done if x == 0
__ movq(RCX, Address(RSP, 7 * target::kWordSize)); // x_digits
__ movq(RAX, Address(RSP, 6 * target::kWordSize)); // xi is Smi
- __ movq(RBX, FieldAddress(RCX, target::TypedData::data_offset()));
- __ movq(RBX, Address(RBX, RAX, TIMES_2, 0));
+ __ movq(RBX,
+ FieldAddress(RCX, RAX, TIMES_2, target::TypedData::data_offset()));
__ testq(RBX, RBX);
__ j(ZERO, &done, Assembler::kNearJump);
@@ -910,14 +913,14 @@
// RDI = mip = &m_digits[i >> 1]
__ movq(RDI, Address(RSP, 5 * target::kWordSize)); // m_digits
__ movq(RAX, Address(RSP, 4 * target::kWordSize)); // i is Smi
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
- __ leaq(RDI, Address(RDI, RAX, TIMES_2, 0));
+ __ leaq(RDI,
+ FieldAddress(RDI, RAX, TIMES_2, target::TypedData::data_offset()));
// RSI = ajp = &a_digits[j >> 1]
__ movq(RSI, Address(RSP, 3 * target::kWordSize)); // a_digits
__ movq(RAX, Address(RSP, 2 * target::kWordSize)); // j is Smi
- __ movq(RSI, FieldAddress(RSI, target::TypedData::data_offset()));
- __ leaq(RSI, Address(RSI, RAX, TIMES_2, 0));
+ __ leaq(RSI,
+ FieldAddress(RSI, RAX, TIMES_2, target::TypedData::data_offset()));
// RCX = c = 0
__ xorq(RCX, RCX);
@@ -1004,8 +1007,8 @@
// RDI = xip = &x_digits[i >> 1]
__ movq(RDI, Address(RSP, 4 * target::kWordSize)); // x_digits
__ movq(RAX, Address(RSP, 3 * target::kWordSize)); // i is Smi
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
- __ leaq(RDI, Address(RDI, RAX, TIMES_2, 0));
+ __ leaq(RDI,
+ FieldAddress(RDI, RAX, TIMES_2, target::TypedData::data_offset()));
// RBX = x = *xip++, return if x == 0
Label x_zero;
@@ -1016,8 +1019,8 @@
// RSI = ajp = &a_digits[i]
__ movq(RSI, Address(RSP, 2 * target::kWordSize)); // a_digits
- __ movq(RSI, FieldAddress(RSI, target::TypedData::data_offset()));
- __ leaq(RSI, Address(RSI, RAX, TIMES_4, 0));
+ __ leaq(RSI,
+ FieldAddress(RSI, RAX, TIMES_4, target::TypedData::data_offset()));
// RDX:RAX = t = x*x + *ajp
__ movq(RAX, RBX);
@@ -1113,18 +1116,18 @@
// return 2;
// }
- // RDI = &args[0]
+ // RDI = args
__ movq(RDI, Address(RSP, 3 * target::kWordSize)); // args
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
// RCX = yt = args[0..1]
- __ movq(RCX, Address(RDI, 0));
+ __ movq(RCX, FieldAddress(RDI, target::TypedData::data_offset()));
// RBX = dp = &digits[(i >> 1) - 1]
__ movq(RBX, Address(RSP, 2 * target::kWordSize)); // digits
__ movq(RAX, Address(RSP, 1 * target::kWordSize)); // i is Smi and odd.
- __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
- __ leaq(RBX, Address(RBX, RAX, TIMES_2, -kBytesPerBigIntDigit));
+ __ leaq(RBX, FieldAddress(
+ RBX, RAX, TIMES_2,
+ target::TypedData::data_offset() - kBytesPerBigIntDigit));
// RDX = dh = dp[0]
__ movq(RDX, Address(RBX, 0));
@@ -1145,7 +1148,9 @@
__ Bind(&return_qd);
// args[2..3] = qd
- __ movq(Address(RDI, 2 * kBytesPerBigIntDigit), RAX);
+ __ movq(FieldAddress(
+ RDI, target::TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
+ RAX);
__ movq(RAX, Immediate(target::ToRawSmi(2))); // Two digits processed.
__ ret();
@@ -1162,24 +1167,26 @@
// return 2;
// }
- // RDI = &args[0]
+ // RDI = args
__ movq(RDI, Address(RSP, 3 * target::kWordSize)); // args
- __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
// RCX = rho = args[2 .. 3]
- __ movq(RCX, Address(RDI, 2 * kBytesPerBigIntDigit));
+ __ movq(RCX, FieldAddress(RDI, target::TypedData::data_offset() +
+ 2 * kBytesPerBigIntDigit));
// RAX = digits[i >> 1 .. (i >> 1) + 1]
__ movq(RBX, Address(RSP, 2 * target::kWordSize)); // digits
__ movq(RAX, Address(RSP, 1 * target::kWordSize)); // i is Smi
- __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
- __ movq(RAX, Address(RBX, RAX, TIMES_2, 0));
+ __ movq(RAX,
+ FieldAddress(RBX, RAX, TIMES_2, target::TypedData::data_offset()));
// RDX:RAX = t = rho*d
__ mulq(RCX);
// args[4 .. 5] = t mod DIGIT_BASE^2 = low64(t)
- __ movq(Address(RDI, 4 * kBytesPerBigIntDigit), RAX);
+ __ movq(FieldAddress(
+ RDI, target::TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
+ RAX);
__ movq(RAX, Immediate(target::ToRawSmi(2))); // Two digits processed.
__ ret();
@@ -1496,13 +1503,12 @@
// Field '_state'.
__ movq(RBX, FieldAddress(RAX, LookupFieldOffsetInBytes(state_field)));
// Addresses of _state[0] and _state[1].
- __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
const intptr_t scale =
target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
const intptr_t offset =
target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
- Address addr_0 = Address(RBX, 0 * scale + offset);
- Address addr_1 = Address(RBX, 1 * scale + offset);
+ Address addr_0 = FieldAddress(RBX, 0 * scale + offset);
+ Address addr_1 = FieldAddress(RBX, 1 * scale + offset);
__ movq(RAX, Immediate(a_int_value));
__ movl(RCX, addr_0);
__ imulq(RCX, RAX);
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index c7b7037..d441d61 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -3446,9 +3446,7 @@
intptr_t index,
Register temp) {
const int64_t offset_base =
- ((is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
const int64_t offset =
offset_base + static_cast<int64_t>(index) * index_scale;
ASSERT(Utils::IsInt(32, offset));
@@ -3470,9 +3468,7 @@
Register array,
intptr_t index) {
const int64_t offset_base =
- ((is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
const int64_t offset =
offset_base + static_cast<int64_t>(index) * index_scale;
ASSERT(Utils::IsInt(32, offset));
@@ -3487,9 +3483,8 @@
Register index) {
// Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
- int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ int32_t offset =
+ is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
const OperandSize size = Address::OperandSizeFor(cid);
ASSERT(array != IP);
ASSERT(index != IP);
@@ -3529,9 +3524,8 @@
Register index) {
// Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
- int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ int32_t offset =
+ is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
if (shift < 0) {
ASSERT(shift == -1);
add(address, array, Operand(index, ASR, 1));
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index a7eaf8d..b41c7a4 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1566,9 +1566,7 @@
intptr_t index) const {
const int64_t offset =
index * index_scale +
- ((is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
ASSERT(Utils::IsInt(32, offset));
const OperandSize size = Address::OperandSizeFor(cid);
ASSERT(Address::CanHoldOffset(offset, Address::Offset, size));
@@ -1583,9 +1581,7 @@
intptr_t index) {
const int64_t offset =
index * index_scale +
- ((is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
AddImmediate(address, array, offset);
}
@@ -1597,9 +1593,8 @@
Register index) {
// Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
- const int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ const int32_t offset =
+ is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
ASSERT(array != TMP);
ASSERT(index != TMP);
const Register base = is_load ? TMP : index;
@@ -1625,9 +1620,8 @@
Register index) {
// Note that index is expected smi-tagged, (i.e, LSL 1) for all arrays.
const intptr_t shift = Utils::ShiftForPowerOfTwo(index_scale) - kSmiTagShift;
- const int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ const int32_t offset =
+ is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
if (shift == 0) {
add(address, array, Operand(index));
} else if (shift < 0) {
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 38c3771..f1ef6b1 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -2535,7 +2535,7 @@
Register array,
intptr_t index,
intptr_t extra_disp) {
- if (is_external || RawObject::IsTypedDataClassId(cid)) {
+ if (is_external) {
return Address(array, index * index_scale + extra_disp);
} else {
const int64_t disp = static_cast<int64_t>(index) * index_scale +
@@ -2573,7 +2573,7 @@
Register array,
Register index,
intptr_t extra_disp) {
- if (is_external || RawObject::IsTypedDataClassId(cid)) {
+ if (is_external) {
return Address(array, index, ToScaleFactor(index_scale), extra_disp);
} else {
return FieldAddress(array, index, ToScaleFactor(index_scale),
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index ebccda6..af6b564 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -2075,7 +2075,7 @@
intptr_t index_scale,
Register array,
intptr_t index) {
- if (is_external || RawObject::IsTypedDataClassId(cid)) {
+ if (is_external) {
return Address(array, index * index_scale);
} else {
const int64_t disp = static_cast<int64_t>(index) * index_scale +
@@ -2112,7 +2112,7 @@
intptr_t index_scale,
Register array,
Register index) {
- if (is_external || RawObject::IsTypedDataClassId(cid)) {
+ if (is_external) {
return Address(array, index, ToScaleFactor(index_scale), 0);
} else {
return FieldAddress(array, index, ToScaleFactor(index_scale),
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index e6766dc..bcf71bb 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -1184,9 +1184,7 @@
const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
const intptr_t scale = Instance::ElementSizeFor(cid);
const intptr_t base_offset =
- (is_external || RawObject::IsTypedDataClassId(cid)
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
const int64_t offset = index * scale + base_offset;
if (!Utils::IsAbsoluteUint(12, offset)) {
return false;
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index b10e64d..7e1de69 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1064,9 +1064,8 @@
const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
const intptr_t scale = Instance::ElementSizeFor(cid);
const int64_t offset =
- index * scale + (is_external || RawObject::IsTypedDataClassId(cid)
- ? 0
- : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ index * scale +
+ (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
if (!Utils::IsInt(32, offset)) {
return false;
}
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index a81b2cc..b53f252 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -2439,11 +2439,9 @@
// Load from the data from backing store which is a fixed-length array.
*array = elements;
array_cid = kArrayCid;
- } else if (RawObject::IsTypedDataClassId(array_cid) ||
- RawObject::IsExternalTypedDataClassId(array_cid)) {
- ASSERT(TypedData::data_offset() == ExternalTypedData::data_offset());
- LoadUntaggedInstr* elements = new (Z)
- LoadUntaggedInstr(new (Z) Value(*array), TypedData::data_offset());
+ } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+ LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr(
+ new (Z) Value(*array), ExternalTypedData::data_offset());
*cursor = flow_graph->AppendTo(*cursor, elements, NULL, FlowGraph::kValue);
*array = elements;
}
@@ -2858,6 +2856,64 @@
FlowGraph::kValue);
}
+// Emits preparatory code for a typed getter/setter.
+// Handles three cases:
+// (1) dynamic: generates a conditional on the receiver cid
+// that handles external (load untagged) and
+// internal storage at runtime.
+// (2) external: generates load untagged.
+// (3) internal: no code required.
+static void PrepareInlineByteArrayBaseOp(FlowGraph* flow_graph,
+ Instruction* call,
+ Definition* receiver,
+ intptr_t array_cid,
+ Definition** array,
+ Instruction** cursor,
+ TargetEntryInstr** block_external,
+ TargetEntryInstr** block_internal) {
+ if (array_cid == kDynamicCid) {
+ // Dynamic case: runtime resolution between external/internal typed data.
+ // cid = LoadCid
+ // if cid in [ kExternalTypedDataInt8ArrayCid,
+ // kExternalTypedDataFloat64x2ArrayCid ]
+ // block_external: LoadUntagged
+ // ..
+ // else
+ // block_internal: ..
+ //
+ // TODO(ajcbik): as suggested above, subtract + single unsigned test.
+ //
+ LoadClassIdInstr* load_cid =
+ new (Z) LoadClassIdInstr(new (Z) Value(receiver));
+ *cursor = flow_graph->AppendTo(*cursor, load_cid, NULL, FlowGraph::kValue);
+ ConstantInstr* cid_lo = flow_graph->GetConstant(
+ Smi::ZoneHandle(Smi::New(kExternalTypedDataInt8ArrayCid)));
+ RelationalOpInstr* le_lo = new (Z)
+ RelationalOpInstr(call->token_pos(), Token::kLTE, new (Z) Value(cid_lo),
+ new (Z) Value(load_cid), kSmiCid, call->deopt_id());
+ ConstantInstr* cid_hi = flow_graph->GetConstant(
+ Smi::ZoneHandle(Smi::New(kExternalTypedDataFloat64x2ArrayCid)));
+ RelationalOpInstr* le_hi = new (Z) RelationalOpInstr(
+ call->token_pos(), Token::kLTE, new (Z) Value(load_cid),
+ new (Z) Value(cid_hi), kSmiCid, call->deopt_id());
+ *cursor = flow_graph->NewDiamond(*cursor, call,
+ FlowGraph::LogicalAnd(le_lo, le_hi),
+ block_external, block_internal);
+ LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr(
+ new (Z) Value(*array), ExternalTypedData::data_offset());
+ flow_graph->InsertAfter(*block_external, elements, NULL, FlowGraph::kValue);
+ *array = elements; // return load untagged definition in array
+ } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+ // External typed data: load untagged.
+ LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr(
+ new (Z) Value(*array), ExternalTypedData::data_offset());
+ *cursor = flow_graph->AppendTo(*cursor, elements, NULL, FlowGraph::kValue);
+ *array = elements;
+ } else {
+ // Internal typed data: no action.
+ }
+}
+
static LoadIndexedInstr* NewLoad(FlowGraph* flow_graph,
Instruction* call,
Definition* array,
@@ -2909,16 +2965,44 @@
array, &index, &cursor);
}
- ASSERT(TypedData::data_offset() == ExternalTypedData::data_offset());
- LoadUntaggedInstr* elements =
- new (Z) LoadUntaggedInstr(new (Z) Value(array), TypedData::data_offset());
- cursor = flow_graph->AppendTo(cursor, elements, nullptr, FlowGraph::kValue);
+ // Generates a template for the load, either a dynamic conditional
+ // that dispatches on external and internal storage, or a single
+ // case that deals with either external or internal storage.
+ TargetEntryInstr* block_external = nullptr;
+ TargetEntryInstr* block_internal = nullptr;
+ PrepareInlineByteArrayBaseOp(flow_graph, call, receiver, array_cid, &array,
+ &cursor, &block_external, &block_internal);
- LoadIndexedInstr* load = NewLoad(flow_graph, call, elements, index, view_cid);
- flow_graph->AppendTo(
- cursor, load, call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
- FlowGraph::kValue);
- cursor = *last = load;
+ // Fill out the generated template with loads.
+ if (array_cid == kDynamicCid) {
+ ASSERT(block_external != nullptr && block_internal != nullptr);
+ // Load from external in block_external and internal in block_internal
+ // (resolves (B)). The former loads from "array", which is the returned
+ // load untagged definition. The latter loads from the original "receiver".
+ LoadIndexedInstr* load1 = NewLoad(flow_graph, call, array, index, view_cid);
+ ASSERT(block_external->next() == array);
+ flow_graph->InsertAfter(
+ block_external->next(), load1,
+ call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
+ FlowGraph::kValue);
+ LoadIndexedInstr* load2 =
+ NewLoad(flow_graph, call, receiver, index, view_cid);
+ flow_graph->InsertAfter(
+ block_internal, load2,
+ call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
+ FlowGraph::kValue);
+ // Construct phi of external and internal load.
+ *last = flow_graph->AddPhi(cursor->AsJoinEntry(), load1, load2);
+ } else {
+ ASSERT(block_external == nullptr && block_internal == nullptr);
+ // Load from either external or internal.
+ LoadIndexedInstr* load = NewLoad(flow_graph, call, array, index, view_cid);
+ flow_graph->AppendTo(
+ cursor, load,
+ call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
+ FlowGraph::kValue);
+ cursor = *last = load;
+ }
if (view_cid == kTypedDataFloat32ArrayCid) {
*last = new (Z) FloatToDoubleInstr(new (Z) Value((*last)->AsDefinition()),
@@ -3097,17 +3181,43 @@
FlowGraph::kValue);
}
- ASSERT(TypedData::data_offset() == ExternalTypedData::data_offset());
- LoadUntaggedInstr* elements =
- new (Z) LoadUntaggedInstr(new (Z) Value(array), TypedData::data_offset());
- cursor = flow_graph->AppendTo(cursor, elements, nullptr, FlowGraph::kValue);
+ // Generates a template for the store, either a dynamic conditional
+ // that dispatches on external and internal storage, or a single
+ // case that deals with either external or internal storage.
+ TargetEntryInstr* block_external = nullptr;
+ TargetEntryInstr* block_internal = nullptr;
+ PrepareInlineByteArrayBaseOp(flow_graph, call, receiver, array_cid, &array,
+ &cursor, &block_external, &block_internal);
- StoreIndexedInstr* store =
- NewStore(flow_graph, call, elements, index, stored_value, view_cid);
- flow_graph->AppendTo(
- cursor, store, call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
- FlowGraph::kEffect);
- *last = store;
+ // Fill out the generated template with stores.
+ if (array_cid == kDynamicCid) {
+ ASSERT(block_external != nullptr && block_internal != nullptr);
+ // Store to external in block_external and internal in block_internal
+ // (resolves (B)). The former stores to "array", which is the returned
+ // load untagged definition. The latter stores to the original "receiver".
+ ASSERT(block_external->next() == array);
+ flow_graph->InsertAfter(
+ block_external->next(),
+ NewStore(flow_graph, call, array, index, stored_value, view_cid),
+ call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
+ FlowGraph::kEffect);
+ flow_graph->InsertAfter(
+ block_internal,
+ NewStore(flow_graph, call, receiver, index, stored_value, view_cid),
+ call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
+ FlowGraph::kEffect);
+ *last = cursor;
+ } else {
+ ASSERT(block_external == nullptr && block_internal == nullptr);
+ // Store on either external or internal.
+ StoreIndexedInstr* store =
+ NewStore(flow_graph, call, array, index, stored_value, view_cid);
+ flow_graph->AppendTo(
+ cursor, store,
+ call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
+ FlowGraph::kEffect);
+ *last = store;
+ }
// We need a return value to replace uses of the original definition. However,
// the final instruction is a use of 'void operator[]=()', so we use null.
*result = flow_graph->constant_null();
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 85c5e6c..f49a686 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -275,9 +275,7 @@
index = PrepareIndexedOp(flow_graph, &builder, array, index,
Slot::GetLengthFieldForArrayCid(array_cid));
- if (RawObject::IsTypedDataClassId(array_cid) ||
- RawObject::IsExternalTypedDataClassId(array_cid)) {
- ASSERT(TypedData::data_offset() == ExternalTypedData::data_offset());
+ if (RawObject::IsExternalTypedDataClassId(array_cid)) {
array = builder.AddDefinition(new LoadUntaggedInstr(
new Value(array), ExternalTypedData::data_offset()));
}
@@ -423,9 +421,7 @@
UNREACHABLE();
}
- if (RawObject::IsTypedDataClassId(array_cid) ||
- RawObject::IsExternalTypedDataClassId(array_cid)) {
- ASSERT(TypedData::data_offset() == ExternalTypedData::data_offset());
+ if (RawObject::IsExternalTypedDataClassId(array_cid)) {
array = builder.AddDefinition(new LoadUntaggedInstr(
new Value(array), ExternalTypedData::data_offset()));
}
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index ba72cc1..ce66591 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -254,10 +254,6 @@
const word RawObject::kBarrierOverlapShift =
dart::RawObject::kBarrierOverlapShift;
-bool RawObject::IsTypedDataClassId(intptr_t cid) {
- return dart::RawObject::IsTypedDataClassId(cid);
-}
-
intptr_t ObjectPool::element_offset(intptr_t index) {
return dart::ObjectPool::element_offset(index);
}
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 652c1b3..8df8767 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -335,8 +335,6 @@
static const word kSizeTagMaxSizeTag;
static const word kTagBitsSizeTagPos;
static const word kBarrierOverlapShift;
-
- static bool IsTypedDataClassId(intptr_t cid);
};
class RawAbstractType : public AllStatic {
diff --git a/runtime/vm/heap/compactor.cc b/runtime/vm/heap/compactor.cc
index 91e2058..e3073a0 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -483,10 +483,6 @@
// Slide the object down.
memmove(reinterpret_cast<void*>(new_addr),
reinterpret_cast<void*>(old_addr), size);
-
- if (RawObject::IsTypedDataClassId(new_obj->GetClassId())) {
- reinterpret_cast<RawTypedData*>(new_obj)->ResetData();
- }
}
new_obj->ClearMarkBit();
new_obj->VisitPointers(compactor_);
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index 0242715..fba5def 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -208,10 +208,6 @@
new_obj->ptr()->tags_ = tags;
}
- if (RawObject::IsTypedDataClassId(new_obj->GetClassId())) {
- reinterpret_cast<RawTypedData*>(new_obj)->ResetData();
- }
-
// Remember forwarding address.
ForwardTo(raw_addr, new_addr);
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 86b63a5..496631e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1223,7 +1223,6 @@
intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
raw->StoreSmi(&(raw->ptr()->length_), Smi::New(leftover_len));
- raw->ResetData();
} else {
// Update the leftover space as a basic object.
ASSERT(leftover_size == Object::InstanceSize());
@@ -16385,11 +16384,13 @@
intptr_t Instance::DataOffsetFor(intptr_t cid) {
if (RawObject::IsExternalTypedDataClassId(cid) ||
- RawObject::IsExternalStringClassId(cid) ||
- RawObject::IsTypedDataClassId(cid)) {
- // Elements start at offset 0 of the external and typed data.
+ RawObject::IsExternalStringClassId(cid)) {
+ // Elements start at offset 0 of the external data.
return 0;
}
+ if (RawObject::IsTypedDataClassId(cid)) {
+ return TypedData::data_offset();
+ }
switch (cid) {
case kArrayCid:
case kImmutableArrayCid:
@@ -20855,11 +20856,9 @@
NoSafepointScope no_safepoint;
result ^= raw;
result.SetLength(len);
- result.ResetData();
if (len > 0) {
memset(result.DataAddr(0), 0, lengthInBytes);
}
- ASSERT(result.Length() == len);
}
return result.raw();
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 044ecc5..4129963 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -8221,9 +8221,13 @@
static intptr_t length_offset() { return OFFSET_OF(RawTypedData, length_); }
- static intptr_t data_offset() { return OFFSET_OF(RawTypedData, data_); }
+ static intptr_t data_offset() {
+ return OFFSET_OF_RETURNED_VALUE(RawTypedData, data);
+ }
static intptr_t InstanceSize() {
+ ASSERT(sizeof(RawTypedData) ==
+ OFFSET_OF_RETURNED_VALUE(RawTypedData, data));
return 0;
}
@@ -8315,13 +8319,6 @@
StoreSmi(&raw_ptr()->length_, Smi::New(value));
}
- void SetData(uint8_t* data) const {
- ASSERT(Isolate::Current()->heap()->Contains(reinterpret_cast<uword>(data)));
- StoreNonPointer(&raw_ptr()->data_, data);
- }
-
- void ResetData() { raw()->ResetData(); }
-
private:
// Provides const access to non-pointer, non-aligned data within the object.
// Such access does not need a write barrier, but it is *not* GC-safe, since
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 79372ea..6392703 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2248,31 +2248,13 @@
class RawTypedData : public RawInstance {
RAW_HEAP_OBJECT_IMPLEMENTATION(TypedData);
- public:
- // Reset data_ pointer to internal data.
- void ResetData() { ptr()->data_ = ptr()->internal_data(); }
-
protected:
VISIT_FROM(RawCompressed, length_)
RawSmi* length_;
VISIT_TO_LENGTH(RawCompressed, &ptr()->length_)
-
- uint8_t* data_;
// Variable length data follows here.
-
- uint8_t* internal_data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
- const uint8_t* internal_data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
-
- uint8_t* data() {
- // TODO(alexmarkov): revise after merging with ExternalTypedData
- ASSERT(data_ == internal_data());
- return data_;
- }
- const uint8_t* data() const {
- // TODO(alexmarkov): revise after merging with ExternalTypedData
- ASSERT(data_ == internal_data());
- return data_;
- }
+ uint8_t* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
+ const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
friend class Api;
friend class Instance;