Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Unified Diff: runtime/vm/assembler_arm.cc

Issue 841343002: ARM port of r42723. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/flow_graph_compiler_arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm.cc
===================================================================
--- runtime/vm/assembler_arm.cc (revision 42713)
+++ runtime/vm/assembler_arm.cc (working copy)
@@ -1700,36 +1700,76 @@
}
-void Assembler::VerifiedWrite(const Address& address, Register new_value) {
+void Assembler::VerifiedWrite(const Address& address,
+ Register new_value,
+ FieldContent old_content) {
+#if defined(DEBUG)
+ ASSERT(address.mode() == Address::Offset ||
+ address.mode() == Address::NegOffset);
+ // Allocate temporary registers (and check for register collisions).
+ RegList used = 0;
+ UseRegister(new_value, &used);
+ Register base = UseRegister(address.rn(), &used);
+ if (address.rm() != kNoRegister) {
+ UseRegister(address.rm(), &used);
+ }
+ Register old_value = AllocateRegister(&used);
+ Register temp = AllocateRegister(&used);
+ PushList(used);
+ ldr(old_value, address);
+ // First check that 'old_value' contains 'old_content'.
+ // Smi test.
+ tst(old_value, Operand(kHeapObjectTag));
+ Label ok;
+ switch (old_content) {
+ case kOnlySmi:
+ b(&ok, EQ); // Smi is OK.
+ Stop("Expected smi.");
+ break;
+ case kHeapObjectOrSmi:
+ b(&ok, EQ); // Smi is OK.
+ // Non-smi case: Verify object pointer is word-aligned when untagged.
+ COMPILE_ASSERT(kHeapObjectTag == 1);
+ tst(old_value, Operand((kWordSize - 1) - kHeapObjectTag));
+ b(&ok, EQ);
+ Stop("Expected heap object or Smi");
+ break;
+ case kEmptyOrSmiOrNull:
+ b(&ok, EQ); // Smi is OK.
+ // Non-smi case: Check for the special zap word or null.
+ // Note: Cannot use CompareImmediate, since IP may be in use.
+ LoadImmediate(temp, Heap::kZap32Bits);
+ cmp(old_value, Operand(temp));
+ b(&ok, EQ);
+ LoadImmediate(temp, reinterpret_cast<uint32_t>(Object::null()));
+ cmp(old_value, Operand(temp));
+ b(&ok, EQ);
+ Stop("Expected zapped, Smi or null");
+ break;
+ default:
+ UNREACHABLE();
+ }
+ Bind(&ok);
if (VerifiedMemory::enabled()) {
- ASSERT(address.mode() == Address::Offset ||
- address.mode() == Address::NegOffset);
- // Allocate temporary registers (and check for register collisions).
- RegList used = 0;
- UseRegister(new_value, &used);
- Register base = UseRegister(address.rn(), &used);
- if (address.rm() != kNoRegister) UseRegister(address.rm(), &used);
- Register old_value = AllocateRegister(&used);
- Register shadow_value = AllocateRegister(&used);
- PushList(used);
- // Verify old value.
- ldr(old_value, address);
Operand shadow_offset(GetVerifiedMemoryShadow());
+ // Adjust the address to shadow.
add(base, base, shadow_offset);
- ldr(shadow_value, address);
- cmp(old_value, Operand(shadow_value));
- Label ok;
- b(&ok);
+ ldr(temp, address);
+ cmp(old_value, Operand(temp));
+ Label match;
+ b(&match, EQ);
Stop("Write barrier verification failed");
- Bind(&ok);
- // Write new value.
+ Bind(&match);
+ // Write new value in shadow.
str(new_value, address);
+ // Restore original address.
sub(base, base, shadow_offset);
- str(new_value, address);
- PopList(used);
- } else {
- str(new_value, address);
}
+ str(new_value, address);
+ PopList(used);
+#else
+ str(new_value, address);
+#endif // DEBUG
}
@@ -1738,7 +1778,7 @@
Register value,
bool can_value_be_smi) {
ASSERT(object != value);
- VerifiedWrite(dest, value);
+ VerifiedWrite(dest, value, kHeapObjectOrSmi);
Label done;
if (can_value_be_smi) {
StoreIntoObjectFilter(object, value, &done);
@@ -1778,8 +1818,9 @@
void Assembler::StoreIntoObjectNoBarrier(Register object,
const Address& dest,
- Register value) {
- VerifiedWrite(dest, value);
+ Register value,
+ FieldContent old_content) {
+ VerifiedWrite(dest, value, old_content);
#if defined(DEBUG)
Label done;
StoreIntoObjectFilter(object, value, &done);
@@ -1792,13 +1833,15 @@
void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
int32_t offset,
- Register value) {
+ Register value,
+ FieldContent old_content) {
int32_t ignored = 0;
if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
- StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
+ StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
+ old_content);
} else {
AddImmediate(IP, object, offset - kHeapObjectTag);
- StoreIntoObjectNoBarrier(object, Address(IP), value);
+ StoreIntoObjectNoBarrier(object, Address(IP), value, old_content);
}
}
@@ -1805,24 +1848,27 @@
void Assembler::StoreIntoObjectNoBarrier(Register object,
const Address& dest,
- const Object& value) {
+ const Object& value,
+ FieldContent old_content) {
ASSERT(value.IsSmi() || value.InVMHeap() ||
(value.IsOld() && value.IsNotTemporaryScopedHandle()));
// No store buffer update.
LoadObject(IP, value);
- VerifiedWrite(dest, IP);
+ VerifiedWrite(dest, IP, old_content);
}
void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
int32_t offset,
- const Object& value) {
+ const Object& value,
+ FieldContent old_content) {
int32_t ignored = 0;
if (Address::CanHoldStoreOffset(kWord, offset - kHeapObjectTag, &ignored)) {
- StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value);
+ StoreIntoObjectNoBarrier(object, FieldAddress(object, offset), value,
+ old_content);
} else {
AddImmediate(IP, object, offset - kHeapObjectTag);
- StoreIntoObjectNoBarrier(object, Address(IP), value);
+ StoreIntoObjectNoBarrier(object, Address(IP), value, old_content);
}
}
@@ -1879,15 +1925,14 @@
void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
- // TODO(koda): Verify previous value was Smi.
- VerifiedWrite(dest, value);
#if defined(DEBUG)
Label done;
tst(value, Operand(kHeapObjectTag));
b(&done, EQ);
- Stop("Smi expected");
+ Stop("New value must be Smi.");
Bind(&done);
#endif // defined(DEBUG)
+ VerifiedWrite(dest, value, kOnlySmi);
}
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/flow_graph_compiler_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698