[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>
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 126d193..972d93e 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -3372,7 +3372,8 @@
Deserializer::InitializeHeader(
data, cid_, TypedData::InstanceSize(length_in_bytes), is_canonical);
data->ptr()->length_ = Smi::New(length);
- uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
+ data->ResetData();
+ uint8_t* cdata = 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 c00607e..cf5264e 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm.cc
@@ -165,6 +165,8 @@
__ 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); \
@@ -693,13 +695,12 @@
// R4 = n ~/ _DIGIT_BITS
__ Asr(R4, R3, Operand(5));
// R8 = &x_digits[0]
- __ add(R8, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R8, FieldAddress(R1, target::TypedData::data_offset()));
// NOTFP = &x_digits[x_used]
__ add(NOTFP, R8, Operand(R0, LSL, 1));
// R6 = &r_digits[1]
- __ add(R6, R2,
- Operand(target::TypedData::data_offset() - kHeapObjectTag +
- kBytesPerBigIntDigit));
+ __ ldr(R6, FieldAddress(R2, target::TypedData::data_offset()));
+ __ add(R6, R6, Operand(kBytesPerBigIntDigit));
// R6 = &r_digits[x_used + n ~/ _DIGIT_BITS + 1]
__ add(R4, R4, Operand(R0, ASR, 1));
__ add(R6, R6, Operand(R4, LSL, 2));
@@ -733,9 +734,9 @@
// R4 = n ~/ _DIGIT_BITS
__ Asr(R4, R3, Operand(5));
// R6 = &r_digits[0]
- __ add(R6, R2, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R6, FieldAddress(R2, target::TypedData::data_offset()));
// NOTFP = &x_digits[n ~/ _DIGIT_BITS]
- __ add(NOTFP, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(NOTFP, FieldAddress(R1, target::TypedData::data_offset()));
__ add(NOTFP, NOTFP, Operand(R4, LSL, 2));
// R8 = &r_digits[x_used - n ~/ _DIGIT_BITS - 1]
__ add(R4, R4, Operand(1));
@@ -773,17 +774,17 @@
// R0 = used, R1 = digits
__ ldrd(R0, R1, SP, 3 * target::kWordSize);
// R1 = &digits[0]
- __ add(R1, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
// R2 = a_used, R3 = a_digits
__ ldrd(R2, R3, SP, 1 * target::kWordSize);
// R3 = &a_digits[0]
- __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
// R8 = r_digits
__ ldr(R8, Address(SP, 0 * target::kWordSize));
// R8 = &r_digits[0]
- __ add(R8, R8, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R8, FieldAddress(R8, target::TypedData::data_offset()));
// NOTFP = &digits[a_used >> 1], a_used is Smi.
__ add(NOTFP, R1, Operand(R2, LSL, 1));
@@ -833,17 +834,17 @@
// R0 = used, R1 = digits
__ ldrd(R0, R1, SP, 3 * target::kWordSize);
// R1 = &digits[0]
- __ add(R1, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
// R2 = a_used, R3 = a_digits
__ ldrd(R2, R3, SP, 1 * target::kWordSize);
// R3 = &a_digits[0]
- __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
// R8 = r_digits
__ ldr(R8, Address(SP, 0 * target::kWordSize));
// R8 = &r_digits[0]
- __ add(R8, R8, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R8, FieldAddress(R8, target::TypedData::data_offset()));
// NOTFP = &digits[a_used >> 1], a_used is Smi.
__ add(NOTFP, R1, Operand(R2, LSL, 1));
@@ -912,8 +913,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);
@@ -924,13 +925,13 @@
// R4 = mip = &m_digits[i >> 1]
__ ldrd(R0, R1, SP, 3 * target::kWordSize); // R0 = i as Smi, R1 = m_digits.
- __ add(R1, R1, Operand(R0, LSL, 1));
- __ add(R4, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R4, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R4, R4, Operand(R0, LSL, 1));
// R9 = ajp = &a_digits[j >> 1]
__ ldrd(R0, R1, SP, 1 * target::kWordSize); // R0 = j as Smi, R1 = a_digits.
- __ add(R1, R1, Operand(R0, LSL, 1));
- __ add(R9, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R9, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R9, R9, Operand(R0, LSL, 1));
// R1 = c = 0
__ mov(R1, Operand(0));
@@ -1012,8 +1013,8 @@
// R4 = xip = &x_digits[i >> 1]
__ ldrd(R2, R3, SP, 2 * target::kWordSize); // R2 = i as Smi, R3 = x_digits
- __ add(R3, R3, Operand(R2, LSL, 1));
- __ add(R4, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R4, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R4, R4, Operand(R2, LSL, 1));
// R3 = x = *xip++, return if x == 0
Label x_zero;
@@ -1023,8 +1024,8 @@
// NOTFP = ajp = &a_digits[i]
__ ldr(R1, Address(SP, 1 * target::kWordSize)); // a_digits
- __ add(R1, R1, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
- __ add(NOTFP, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(NOTFP, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(NOTFP, NOTFP, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
// R8:R0 = t = x*x + *ajp
__ ldr(R0, Address(NOTFP, 0));
@@ -1112,24 +1113,24 @@
// return 1;
// }
- // R4 = args
+ // R4 = &args[0]
__ ldr(R4, Address(SP, 2 * target::kWordSize)); // args
+ __ ldr(R4, FieldAddress(R4, target::TypedData::data_offset()));
// R3 = rho = args[2]
- __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset() +
- 2 * kBytesPerBigIntDigit));
+ __ ldr(R3, Address(R4, 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, FieldAddress(R4, target::TypedData::data_offset() +
- 4 * kBytesPerBigIntDigit));
+ __ str(R0, Address(R4, 4 * kBytesPerBigIntDigit));
__ mov(R0, Operand(target::ToRawSmi(1))); // One digit processed.
__ Ret();
@@ -1495,6 +1496,7 @@
// 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);
@@ -1502,13 +1504,13 @@
disp_0 + target::Instance::ElementSizeFor(kTypedDataUint32ArrayCid);
__ LoadImmediate(R0, a_int32_value);
- __ LoadFromOffset(kWord, R2, R1, disp_0 - kHeapObjectTag);
- __ LoadFromOffset(kWord, R3, R1, disp_1 - kHeapObjectTag);
+ __ LoadFromOffset(kWord, R2, R1, disp_0);
+ __ LoadFromOffset(kWord, R3, R1, disp_1);
__ 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 - kHeapObjectTag);
- __ StoreToOffset(kWord, R8, R1, disp_1 - kHeapObjectTag);
+ __ StoreToOffset(kWord, R3, R1, disp_0);
+ __ StoreToOffset(kWord, R8, R1, disp_1);
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 6ba42cd..0153c00 100644
--- a/runtime/vm/compiler/asm_intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_arm64.cc
@@ -177,6 +177,8 @@
/* 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)); \
@@ -601,13 +603,12 @@
// R0 = n ~/ (2*_DIGIT_BITS)
__ AsrImmediate(R0, R5, 6);
// R6 = &x_digits[0]
- __ add(R6, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R6, FieldAddress(R3, target::TypedData::data_offset()));
// R7 = &x_digits[2*R2]
__ add(R7, R6, Operand(R2, LSL, 3));
// R8 = &r_digits[2*1]
- __ add(R8, R4,
- Operand(target::TypedData::data_offset() - kHeapObjectTag +
- 2 * kBytesPerBigIntDigit));
+ __ ldr(R8, FieldAddress(R4, target::TypedData::data_offset()));
+ __ add(R8, R8, Operand(2 * kBytesPerBigIntDigit));
// R8 = &r_digits[2*(R2 + n ~/ (2*_DIGIT_BITS) + 1)]
__ add(R0, R0, Operand(R2));
__ add(R8, R8, Operand(R0, LSL, 3));
@@ -645,9 +646,9 @@
// R0 = n ~/ (2*_DIGIT_BITS)
__ AsrImmediate(R0, R5, 6);
// R8 = &r_digits[0]
- __ add(R8, R4, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R8, FieldAddress(R4, target::TypedData::data_offset()));
// R7 = &x_digits[2*(n ~/ (2*_DIGIT_BITS))]
- __ add(R7, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R7, FieldAddress(R3, target::TypedData::data_offset()));
__ add(R7, R7, Operand(R0, LSL, 3));
// R6 = &r_digits[2*(R2 - n ~/ (2*_DIGIT_BITS) - 1)]
__ add(R0, R0, Operand(1));
@@ -689,19 +690,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]
- __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
// 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]
- __ add(R5, R5, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R5, FieldAddress(R5, target::TypedData::data_offset()));
// R6 = r_digits
__ ldr(R6, Address(SP, 0 * target::kWordSize));
// R6 = &r_digits[0]
- __ add(R6, R6, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R6, FieldAddress(R6, target::TypedData::data_offset()));
// R7 = &digits[a_used rounded up to even number].
__ add(R7, R3, Operand(R4, LSL, 3));
@@ -755,19 +756,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]
- __ add(R3, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R3, FieldAddress(R3, target::TypedData::data_offset()));
// 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]
- __ add(R5, R5, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R5, FieldAddress(R5, target::TypedData::data_offset()));
// R6 = r_digits
__ ldr(R6, Address(SP, 0 * target::kWordSize));
// R6 = &r_digits[0]
- __ add(R6, R6, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R6, FieldAddress(R6, target::TypedData::data_offset()));
// R7 = &digits[a_used rounded up to even number].
__ add(R7, R3, Operand(R4, LSL, 3));
@@ -838,8 +839,9 @@
// 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);
@@ -852,14 +854,14 @@
// R4 = mip = &m_digits[i >> 1]
// R0 = i as Smi, R1 = m_digits.
__ ldp(R0, R1, Address(SP, 3 * target::kWordSize, Address::PairOffset));
- __ add(R1, R1, Operand(R0, LSL, 1));
- __ add(R4, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R4, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R4, R4, Operand(R0, LSL, 1));
// R5 = ajp = &a_digits[j >> 1]
// R0 = j as Smi, R1 = a_digits.
__ ldp(R0, R1, Address(SP, 1 * target::kWordSize, Address::PairOffset));
- __ add(R1, R1, Operand(R0, LSL, 1));
- __ add(R5, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R5, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R5, R5, Operand(R0, LSL, 1));
// R1 = c = 0
__ mov(R1, ZR);
@@ -946,8 +948,8 @@
// R4 = xip = &x_digits[i >> 1]
// R2 = i as Smi, R3 = x_digits
__ ldp(R2, R3, Address(SP, 2 * target::kWordSize, Address::PairOffset));
- __ add(R3, R3, Operand(R2, LSL, 1));
- __ add(R4, R3, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R4, FieldAddress(R3, target::TypedData::data_offset()));
+ __ add(R4, R4, Operand(R2, LSL, 1));
// R3 = x = *xip++, return if x == 0
Label x_zero;
@@ -957,8 +959,8 @@
// R5 = ajp = &a_digits[i]
__ ldr(R1, Address(SP, 1 * target::kWordSize)); // a_digits
- __ add(R1, R1, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
- __ add(R5, R1, Operand(target::TypedData::data_offset() - kHeapObjectTag));
+ __ ldr(R5, FieldAddress(R1, target::TypedData::data_offset()));
+ __ add(R5, R5, Operand(R2, LSL, 2)); // j == 2*i, i is Smi.
// R6:R1 = t = x*x + *ajp
__ ldr(R0, Address(R5, 0));
@@ -1076,18 +1078,19 @@
// return 2;
// }
- // R4 = args
+ // R4 = &args[0]
__ ldr(R4, Address(SP, 2 * target::kWordSize)); // args
+ __ ldr(R4, FieldAddress(R4, target::TypedData::data_offset()));
// R3 = yt = args[0..1]
- __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset()));
+ __ ldr(R3, Address(R4, 0));
// 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, FieldAddress(
- R1, target::TypedData::data_offset() - kBytesPerBigIntDigit));
+ __ ldr(R2, Address(R1, -kBytesPerBigIntDigit));
// R0 = qd = (DIGIT_MASK << 32) | DIGIT_MASK = -1
__ movn(R0, Immediate(0), 0);
@@ -1098,8 +1101,7 @@
__ b(&return_qd, EQ);
// R1 = dl = digits[(i >> 1) - 3 .. (i >> 1) - 2]
- __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset() -
- 3 * kBytesPerBigIntDigit));
+ __ ldr(R1, Address(R1, -3 * kBytesPerBigIntDigit));
// R5 = yth = yt >> 32
__ orr(R5, ZR, Operand(R3, LSR, 32));
@@ -1203,8 +1205,7 @@
__ Bind(&return_qd);
// args[2..3] = qd
- __ str(R0, FieldAddress(R4, target::TypedData::data_offset() +
- 2 * kBytesPerBigIntDigit));
+ __ str(R0, Address(R4, 2 * kBytesPerBigIntDigit));
__ LoadImmediate(R0, target::ToRawSmi(2)); // Two digits processed.
__ ret();
@@ -1221,25 +1222,25 @@
// return 2;
// }
- // R4 = args
+ // R4 = &args[0]
__ ldr(R4, Address(SP, 2 * target::kWordSize)); // args
+ __ ldr(R4, FieldAddress(R4, target::TypedData::data_offset()));
// R3 = rho = args[2..3]
- __ ldr(R3, FieldAddress(R4, target::TypedData::data_offset() +
- 2 * kBytesPerBigIntDigit));
+ __ ldr(R3, Address(R4, 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, FieldAddress(R4, target::TypedData::data_offset() +
- 4 * kBytesPerBigIntDigit));
+ __ str(R0, Address(R4, 4 * kBytesPerBigIntDigit));
__ LoadImmediate(R0, target::ToRawSmi(2)); // Two digits processed.
__ ret();
@@ -1557,10 +1558,10 @@
// Field '_state'.
__ ldr(R1, FieldAddress(R0, LookupFieldOffsetInBytes(state_field)));
- // Addresses of _state[0].
+ // Address of _state[0].
+ __ ldr(R1, FieldAddress(R1, target::TypedData::data_offset()));
const int64_t disp =
- target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid) -
- kHeapObjectTag;
+ target::Instance::DataOffsetFor(kTypedDataUint32ArrayCid);
__ 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 392d129..88c48f9 100644
--- a/runtime/vm/compiler/asm_intrinsifier_ia32.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_ia32.cc
@@ -167,6 +167,8 @@
/* 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); \
@@ -713,14 +715,14 @@
__ movl(EBX, Address(ESP, 2 * target::kWordSize)); // r_digits
__ movl(ESI, ECX);
__ sarl(ESI, Immediate(5)); // ESI = n ~/ _DIGIT_BITS.
- __ leal(EBX,
- FieldAddress(EBX, ESI, TIMES_4, target::TypedData::data_offset()));
+ __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
+ __ leal(EBX, Address(EBX, ESI, TIMES_4, 0));
__ movl(ESI, Address(ESP, 4 * target::kWordSize)); // x_used > 0, Smi.
__ SmiUntag(ESI);
__ decl(ESI);
__ xorl(EAX, EAX); // EAX = 0.
- __ movl(EDX,
- FieldAddress(EDI, ESI, TIMES_4, target::TypedData::data_offset()));
+ __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
+ __ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
__ shldl(EAX, EDX, ECX);
__ movl(Address(EBX, ESI, TIMES_4, kBytesPerBigIntDigit), EAX);
Label last;
@@ -729,9 +731,7 @@
Label loop;
__ Bind(&loop);
__ movl(EAX, EDX);
- __ movl(EDX, FieldAddress(
- EDI, ESI, TIMES_4,
- target::TypedData::data_offset() - kBytesPerBigIntDigit));
+ __ movl(EDX, Address(EDI, ESI, TIMES_4, -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].
- __ leal(EDI,
- FieldAddress(EDI, ESI, TIMES_4, target::TypedData::data_offset()));
+ __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
+ __ leal(EDI, Address(EDI, ESI, TIMES_4, 0));
__ subl(ESI, EDX);
// EBX = &r_digits[x_used - 1 - (n ~/ 32)].
- __ leal(EBX,
- FieldAddress(EBX, ESI, TIMES_4, target::TypedData::data_offset()));
+ __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
+ __ leal(EBX, Address(EBX, ESI, TIMES_4, 0));
__ negl(ESI);
__ movl(EDX, Address(EDI, ESI, TIMES_4, 0));
Label last;
@@ -811,6 +811,10 @@
__ 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.
@@ -820,12 +824,9 @@
Label add_loop;
__ Bind(&add_loop);
// Loop a_used times, ECX = a_used, ECX > 0.
- __ 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);
+ __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
+ __ adcl(EAX, Address(ESI, EDX, TIMES_4, 0));
+ __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
@@ -838,11 +839,9 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop used - a_used times, ECX = used - a_used, ECX > 0.
- __ movl(EAX,
- FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+ __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
__ adcl(EAX, Immediate(0));
- __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
- EAX);
+ __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -850,8 +849,7 @@
__ Bind(&last_carry);
__ movl(EAX, Immediate(0));
__ adcl(EAX, Immediate(0));
- __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
- EAX);
+ __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
// Restore THR and return.
__ popl(THR);
@@ -877,6 +875,10 @@
__ 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.
@@ -886,12 +888,9 @@
Label sub_loop;
__ Bind(&sub_loop);
// Loop a_used times, ECX = a_used, ECX > 0.
- __ 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);
+ __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
+ __ sbbl(EAX, Address(ESI, EDX, TIMES_4, 0));
+ __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
@@ -904,11 +903,9 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop used - a_used times, ECX = used - a_used, ECX > 0.
- __ movl(EAX,
- FieldAddress(EDI, EDX, TIMES_4, target::TypedData::data_offset()));
+ __ movl(EAX, Address(EDI, EDX, TIMES_4, 0));
__ sbbl(EAX, Immediate(0));
- __ movl(FieldAddress(EBX, EDX, TIMES_4, target::TypedData::data_offset()),
- EAX);
+ __ movl(Address(EBX, EDX, TIMES_4, 0), EAX);
__ incl(EDX); // Does not affect carry flag.
__ decl(ECX); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -953,8 +950,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, EAX, TIMES_2, target::TypedData::data_offset()));
+ __ movl(EBX, FieldAddress(ECX, target::TypedData::data_offset()));
+ __ movl(EBX, Address(EBX, EAX, TIMES_2, 0));
__ testl(EBX, EBX);
__ j(ZERO, &no_op, Assembler::kNearJump);
@@ -970,14 +967,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
- __ leal(EDI,
- FieldAddress(EDI, EAX, TIMES_2, target::TypedData::data_offset()));
+ __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
+ __ leal(EDI, Address(EDI, EAX, TIMES_2, 0));
// 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
- __ leal(ESI,
- FieldAddress(ESI, EAX, TIMES_2, target::TypedData::data_offset()));
+ __ movl(ESI, FieldAddress(ESI, target::TypedData::data_offset()));
+ __ leal(ESI, Address(ESI, EAX, TIMES_2, 0));
// Save n
__ pushl(EDX);
@@ -1074,8 +1071,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
- __ leal(EDI,
- FieldAddress(EDI, EAX, TIMES_2, target::TypedData::data_offset()));
+ __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
+ __ leal(EDI, Address(EDI, EAX, TIMES_2, 0));
// EBX = x = *xip++, return if x == 0
Label x_zero;
@@ -1090,8 +1087,8 @@
// ESI = ajp = &a_digits[i]
__ movl(ESI, Address(ESP, 3 * target::kWordSize)); // a_digits
- __ leal(ESI,
- FieldAddress(ESI, EAX, TIMES_4, target::TypedData::data_offset()));
+ __ movl(ESI, FieldAddress(ESI, target::TypedData::data_offset()));
+ __ leal(ESI, Address(ESI, EAX, TIMES_4, 0));
// EDX:EAX = t = x*x + *ajp
__ movl(EAX, EBX);
@@ -1196,18 +1193,18 @@
// return 1;
// }
- // EDI = args
+ // EDI = &args[0]
__ movl(EDI, Address(ESP, 3 * target::kWordSize)); // args
+ __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
// ECX = yt = args[1]
- __ movl(ECX, FieldAddress(EDI, target::TypedData::data_offset() +
- kBytesPerBigIntDigit));
+ __ movl(ECX, Address(EDI, kBytesPerBigIntDigit));
// EBX = dp = &digits[i >> 1]
__ movl(EBX, Address(ESP, 2 * target::kWordSize)); // digits
__ movl(EAX, Address(ESP, 1 * target::kWordSize)); // i is Smi
- __ leal(EBX,
- FieldAddress(EBX, EAX, TIMES_2, target::TypedData::data_offset()));
+ __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
+ __ leal(EBX, Address(EBX, EAX, TIMES_2, 0));
// EDX = dh = dp[0]
__ movl(EDX, Address(EBX, 0));
@@ -1228,9 +1225,7 @@
__ Bind(&return_qd);
// args[2] = qd
- __ movl(FieldAddress(
- EDI, target::TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
- EAX);
+ __ movl(Address(EDI, 2 * kBytesPerBigIntDigit), EAX);
__ movl(EAX, Immediate(target::ToRawSmi(1))); // One digit processed.
__ ret();
@@ -1247,26 +1242,24 @@
// return 1;
// }
- // EDI = args
+ // EDI = &args[0]
__ movl(EDI, Address(ESP, 3 * target::kWordSize)); // args
+ __ movl(EDI, FieldAddress(EDI, target::TypedData::data_offset()));
// ECX = rho = args[2]
- __ movl(ECX, FieldAddress(EDI, target::TypedData::data_offset() +
- 2 * kBytesPerBigIntDigit));
+ __ movl(ECX, Address(EDI, 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(EAX,
- FieldAddress(EBX, EAX, TIMES_2, target::TypedData::data_offset()));
+ __ movl(EBX, FieldAddress(EBX, target::TypedData::data_offset()));
+ __ movl(EAX, Address(EBX, EAX, TIMES_2, 0));
// EDX:EAX = t = rho*d
__ mull(ECX);
// args[4] = t mod DIGIT_BASE = low32(t)
- __ movl(FieldAddress(
- EDI, target::TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
- EAX);
+ __ movl(Address(EDI, 4 * kBytesPerBigIntDigit), EAX);
__ movl(EAX, Immediate(target::ToRawSmi(1))); // One digit processed.
__ ret();
@@ -1596,12 +1589,13 @@
// 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 = FieldAddress(EBX, 0 * scale + offset);
- Address addr_1 = FieldAddress(EBX, 1 * scale + offset);
+ Address addr_0 = Address(EBX, 0 * scale + offset);
+ Address addr_1 = Address(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 1c34df5..1532070 100644
--- a/runtime/vm/compiler/asm_intrinsifier_x64.cc
+++ b/runtime/vm/compiler/asm_intrinsifier_x64.cc
@@ -169,6 +169,8 @@
/* 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); \
@@ -684,11 +686,11 @@
__ movq(RBX, Address(RSP, 1 * target::kWordSize)); // r_digits
__ movq(RSI, RCX);
__ sarq(RSI, Immediate(6)); // RSI = n ~/ (2*_DIGIT_BITS).
- __ leaq(RBX,
- FieldAddress(RBX, RSI, TIMES_8, target::TypedData::data_offset()));
+ __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
+ __ leaq(RBX, Address(RBX, RSI, TIMES_8, 0));
__ xorq(RAX, RAX); // RAX = 0.
- __ movq(RDX,
- FieldAddress(RDI, R8, TIMES_8, target::TypedData::data_offset()));
+ __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
+ __ movq(RDX, Address(RDI, R8, TIMES_8, 0));
__ shldq(RAX, RDX, RCX);
__ movq(Address(RBX, R8, TIMES_8, 2 * kBytesPerBigIntDigit), RAX);
Label last;
@@ -697,9 +699,7 @@
Label loop;
__ Bind(&loop);
__ movq(RAX, RDX);
- __ movq(RDX, FieldAddress(RDI, R8, TIMES_8,
- target::TypedData::data_offset() -
- 2 * kBytesPerBigIntDigit));
+ __ movq(RDX, Address(RDI, R8, TIMES_8, -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));
- __ leaq(RDI,
- FieldAddress(RDI, RSI, TIMES_8, target::TypedData::data_offset()));
+ __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
+ __ leaq(RDI, Address(RDI, RSI, TIMES_8, 0));
__ subq(RSI, RDX); // RSI + 1 = number of digit pairs to read.
- __ leaq(RBX,
- FieldAddress(RBX, RSI, TIMES_8, target::TypedData::data_offset()));
+ __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
+ __ leaq(RBX, Address(RBX, RSI, TIMES_8, 0));
__ negq(RSI);
__ movq(RDX, Address(RDI, RSI, TIMES_8, 0));
Label last;
@@ -765,6 +765,10 @@
__ 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.
@@ -773,12 +777,9 @@
Label add_loop;
__ Bind(&add_loop);
// Loop (a_used+1)/2 times, RCX > 0.
- __ 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);
+ __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
+ __ adcq(RAX, Address(RSI, RDX, TIMES_8, 0));
+ __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(RCX); // Does not affect carry flag.
__ j(NOT_ZERO, &add_loop, Assembler::kNearJump);
@@ -790,11 +791,9 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
- __ movq(RAX,
- FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+ __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
__ adcq(RAX, Immediate(0));
- __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
- RAX);
+ __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(R8); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -802,8 +801,7 @@
__ Bind(&last_carry);
Label done;
__ j(NOT_CARRY, &done);
- __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
- Immediate(1));
+ __ movq(Address(RBX, RDX, TIMES_8, 0), Immediate(1));
__ Bind(&done);
__ LoadObject(RAX, NullObject());
@@ -826,6 +824,10 @@
__ 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.
@@ -834,12 +836,9 @@
Label sub_loop;
__ Bind(&sub_loop);
// Loop (a_used+1)/2 times, RCX > 0.
- __ 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);
+ __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
+ __ sbbq(RAX, Address(RSI, RDX, TIMES_8, 0));
+ __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(RCX); // Does not affect carry flag.
__ j(NOT_ZERO, &sub_loop, Assembler::kNearJump);
@@ -851,11 +850,9 @@
Label carry_loop;
__ Bind(&carry_loop);
// Loop (used+1)/2 - (a_used+1)/2 times, R8 > 0.
- __ movq(RAX,
- FieldAddress(RDI, RDX, TIMES_8, target::TypedData::data_offset()));
+ __ movq(RAX, Address(RDI, RDX, TIMES_8, 0));
__ sbbq(RAX, Immediate(0));
- __ movq(FieldAddress(RBX, RDX, TIMES_8, target::TypedData::data_offset()),
- RAX);
+ __ movq(Address(RBX, RDX, TIMES_8, 0), RAX);
__ incq(RDX); // Does not affect carry flag.
__ decq(R8); // Does not affect carry flag.
__ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
@@ -899,8 +896,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, RAX, TIMES_2, target::TypedData::data_offset()));
+ __ movq(RBX, FieldAddress(RCX, target::TypedData::data_offset()));
+ __ movq(RBX, Address(RBX, RAX, TIMES_2, 0));
__ testq(RBX, RBX);
__ j(ZERO, &done, Assembler::kNearJump);
@@ -913,14 +910,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
- __ leaq(RDI,
- FieldAddress(RDI, RAX, TIMES_2, target::TypedData::data_offset()));
+ __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
+ __ leaq(RDI, Address(RDI, RAX, TIMES_2, 0));
// 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
- __ leaq(RSI,
- FieldAddress(RSI, RAX, TIMES_2, target::TypedData::data_offset()));
+ __ movq(RSI, FieldAddress(RSI, target::TypedData::data_offset()));
+ __ leaq(RSI, Address(RSI, RAX, TIMES_2, 0));
// RCX = c = 0
__ xorq(RCX, RCX);
@@ -1007,8 +1004,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
- __ leaq(RDI,
- FieldAddress(RDI, RAX, TIMES_2, target::TypedData::data_offset()));
+ __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
+ __ leaq(RDI, Address(RDI, RAX, TIMES_2, 0));
// RBX = x = *xip++, return if x == 0
Label x_zero;
@@ -1019,8 +1016,8 @@
// RSI = ajp = &a_digits[i]
__ movq(RSI, Address(RSP, 2 * target::kWordSize)); // a_digits
- __ leaq(RSI,
- FieldAddress(RSI, RAX, TIMES_4, target::TypedData::data_offset()));
+ __ movq(RSI, FieldAddress(RSI, target::TypedData::data_offset()));
+ __ leaq(RSI, Address(RSI, RAX, TIMES_4, 0));
// RDX:RAX = t = x*x + *ajp
__ movq(RAX, RBX);
@@ -1116,18 +1113,18 @@
// return 2;
// }
- // RDI = args
+ // RDI = &args[0]
__ movq(RDI, Address(RSP, 3 * target::kWordSize)); // args
+ __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
// RCX = yt = args[0..1]
- __ movq(RCX, FieldAddress(RDI, target::TypedData::data_offset()));
+ __ movq(RCX, Address(RDI, 0));
// 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.
- __ leaq(RBX, FieldAddress(
- RBX, RAX, TIMES_2,
- target::TypedData::data_offset() - kBytesPerBigIntDigit));
+ __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
+ __ leaq(RBX, Address(RBX, RAX, TIMES_2, -kBytesPerBigIntDigit));
// RDX = dh = dp[0]
__ movq(RDX, Address(RBX, 0));
@@ -1148,9 +1145,7 @@
__ Bind(&return_qd);
// args[2..3] = qd
- __ movq(FieldAddress(
- RDI, target::TypedData::data_offset() + 2 * kBytesPerBigIntDigit),
- RAX);
+ __ movq(Address(RDI, 2 * kBytesPerBigIntDigit), RAX);
__ movq(RAX, Immediate(target::ToRawSmi(2))); // Two digits processed.
__ ret();
@@ -1167,26 +1162,24 @@
// return 2;
// }
- // RDI = args
+ // RDI = &args[0]
__ movq(RDI, Address(RSP, 3 * target::kWordSize)); // args
+ __ movq(RDI, FieldAddress(RDI, target::TypedData::data_offset()));
// RCX = rho = args[2 .. 3]
- __ movq(RCX, FieldAddress(RDI, target::TypedData::data_offset() +
- 2 * kBytesPerBigIntDigit));
+ __ movq(RCX, Address(RDI, 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(RAX,
- FieldAddress(RBX, RAX, TIMES_2, target::TypedData::data_offset()));
+ __ movq(RBX, FieldAddress(RBX, target::TypedData::data_offset()));
+ __ movq(RAX, Address(RBX, RAX, TIMES_2, 0));
// RDX:RAX = t = rho*d
__ mulq(RCX);
// args[4 .. 5] = t mod DIGIT_BASE^2 = low64(t)
- __ movq(FieldAddress(
- RDI, target::TypedData::data_offset() + 4 * kBytesPerBigIntDigit),
- RAX);
+ __ movq(Address(RDI, 4 * kBytesPerBigIntDigit), RAX);
__ movq(RAX, Immediate(target::ToRawSmi(2))); // Two digits processed.
__ ret();
@@ -1503,12 +1496,13 @@
// 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 = FieldAddress(RBX, 0 * scale + offset);
- Address addr_1 = FieldAddress(RBX, 1 * scale + offset);
+ Address addr_0 = Address(RBX, 0 * scale + offset);
+ Address addr_1 = Address(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 d441d61..c7b7037 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -3446,7 +3446,9 @@
intptr_t index,
Register temp) {
const int64_t offset_base =
- (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ ((is_external || RawObject::IsTypedDataClassId(cid))
+ ? 0
+ : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
const int64_t offset =
offset_base + static_cast<int64_t>(index) * index_scale;
ASSERT(Utils::IsInt(32, offset));
@@ -3468,7 +3470,9 @@
Register array,
intptr_t index) {
const int64_t offset_base =
- (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ ((is_external || RawObject::IsTypedDataClassId(cid))
+ ? 0
+ : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
const int64_t offset =
offset_base + static_cast<int64_t>(index) * index_scale;
ASSERT(Utils::IsInt(32, offset));
@@ -3483,8 +3487,9 @@
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 ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
+ ? 0
+ : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
const OperandSize size = Address::OperandSizeFor(cid);
ASSERT(array != IP);
ASSERT(index != IP);
@@ -3524,8 +3529,9 @@
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 ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
+ ? 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 b41c7a4..a7eaf8d 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1566,7 +1566,9 @@
intptr_t index) const {
const int64_t offset =
index * index_scale +
- (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ ((is_external || RawObject::IsTypedDataClassId(cid))
+ ? 0
+ : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
ASSERT(Utils::IsInt(32, offset));
const OperandSize size = Address::OperandSizeFor(cid);
ASSERT(Address::CanHoldOffset(offset, Address::Offset, size));
@@ -1581,7 +1583,9 @@
intptr_t index) {
const int64_t offset =
index * index_scale +
- (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ ((is_external || RawObject::IsTypedDataClassId(cid))
+ ? 0
+ : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
AddImmediate(address, array, offset);
}
@@ -1593,8 +1597,9 @@
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 ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ const int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
+ ? 0
+ : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
ASSERT(array != TMP);
ASSERT(index != TMP);
const Register base = is_load ? TMP : index;
@@ -1620,8 +1625,9 @@
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 ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag);
+ const int32_t offset = (is_external || RawObject::IsTypedDataClassId(cid))
+ ? 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 f1ef6b1..38c3771 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) {
+ if (is_external || RawObject::IsTypedDataClassId(cid)) {
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) {
+ if (is_external || RawObject::IsTypedDataClassId(cid)) {
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 af6b564..ebccda6 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) {
+ if (is_external || RawObject::IsTypedDataClassId(cid)) {
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) {
+ if (is_external || RawObject::IsTypedDataClassId(cid)) {
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 bcf71bb..e6766dc 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -1184,7 +1184,9 @@
const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
const intptr_t scale = Instance::ElementSizeFor(cid);
const intptr_t base_offset =
- (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ (is_external || RawObject::IsTypedDataClassId(cid)
+ ? 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 7e1de69..b10e64d 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1064,8 +1064,9 @@
const int64_t index = Smi::Cast(constant->value()).AsInt64Value();
const intptr_t scale = Instance::ElementSizeFor(cid);
const int64_t offset =
- index * scale +
- (is_external ? 0 : (Instance::DataOffsetFor(cid) - kHeapObjectTag));
+ index * scale + (is_external || RawObject::IsTypedDataClassId(cid)
+ ? 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 afde064..9920c06 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -2436,9 +2436,11 @@
// Load from the data from backing store which is a fixed-length array.
*array = elements;
array_cid = kArrayCid;
- } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
- LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr(
- new (Z) Value(*array), ExternalTypedData::data_offset());
+ } 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());
*cursor = flow_graph->AppendTo(*cursor, elements, NULL, FlowGraph::kValue);
*array = elements;
}
@@ -2853,64 +2855,6 @@
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,
@@ -2962,44 +2906,16 @@
array, &index, &cursor);
}
- // 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);
+ 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);
- // 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;
- }
+ 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;
if (view_cid == kTypedDataFloat32ArrayCid) {
*last = new (Z) FloatToDoubleInstr(new (Z) Value((*last)->AsDefinition()),
@@ -3178,43 +3094,17 @@
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);
+ 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);
- // 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;
- }
+ 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;
// 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 f49a686..85c5e6c 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -275,7 +275,9 @@
index = PrepareIndexedOp(flow_graph, &builder, array, index,
Slot::GetLengthFieldForArrayCid(array_cid));
- if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+ if (RawObject::IsTypedDataClassId(array_cid) ||
+ RawObject::IsExternalTypedDataClassId(array_cid)) {
+ ASSERT(TypedData::data_offset() == ExternalTypedData::data_offset());
array = builder.AddDefinition(new LoadUntaggedInstr(
new Value(array), ExternalTypedData::data_offset()));
}
@@ -421,7 +423,9 @@
UNREACHABLE();
}
- if (RawObject::IsExternalTypedDataClassId(array_cid)) {
+ if (RawObject::IsTypedDataClassId(array_cid) ||
+ RawObject::IsExternalTypedDataClassId(array_cid)) {
+ ASSERT(TypedData::data_offset() == ExternalTypedData::data_offset());
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 ce66591..ba72cc1 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -254,6 +254,10 @@
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 8df8767..652c1b3 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -335,6 +335,8 @@
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 e3073a0..91e2058 100644
--- a/runtime/vm/heap/compactor.cc
+++ b/runtime/vm/heap/compactor.cc
@@ -483,6 +483,10 @@
// 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 fba5def..0242715 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -208,6 +208,10 @@
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 cf4d4a1..06faf7f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1223,6 +1223,7 @@
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());
@@ -16380,13 +16381,11 @@
intptr_t Instance::DataOffsetFor(intptr_t cid) {
if (RawObject::IsExternalTypedDataClassId(cid) ||
- RawObject::IsExternalStringClassId(cid)) {
- // Elements start at offset 0 of the external data.
+ RawObject::IsExternalStringClassId(cid) ||
+ RawObject::IsTypedDataClassId(cid)) {
+ // Elements start at offset 0 of the external and typed data.
return 0;
}
- if (RawObject::IsTypedDataClassId(cid)) {
- return TypedData::data_offset();
- }
switch (cid) {
case kArrayCid:
case kImmutableArrayCid:
@@ -20852,9 +20851,11 @@
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 0b999b4..da18f6a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -8221,13 +8221,9 @@
static intptr_t length_offset() { return OFFSET_OF(RawTypedData, length_); }
- static intptr_t data_offset() {
- return OFFSET_OF_RETURNED_VALUE(RawTypedData, data);
- }
+ static intptr_t data_offset() { return OFFSET_OF(RawTypedData, data_); }
static intptr_t InstanceSize() {
- ASSERT(sizeof(RawTypedData) ==
- OFFSET_OF_RETURNED_VALUE(RawTypedData, data));
return 0;
}
@@ -8319,6 +8315,13 @@
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 94d3351..09df2e30 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -2228,13 +2228,31 @@
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* data() { OPEN_ARRAY_START(uint8_t, uint8_t); }
- const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, uint8_t); }
+
+ 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_;
+ }
friend class Api;
friend class Instance;