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

Unified Diff: runtime/vm/object.cc

Issue 529823002: - Add AtomicOperations::CompareAndSwapWord (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 39714)
+++ runtime/vm/object.cc (working copy)
@@ -813,13 +813,20 @@
uword addr = RawObject::ToAddr(obj.raw()) + used_size;
if (leftover_size >= TypedData::InstanceSize(0)) {
- // Update the leftover space as an TypedDataInt8Array object.
+ // Update the leftover space as a TypedDataInt8Array object.
RawTypedData* raw =
reinterpret_cast<RawTypedData*>(RawObject::FromAddr(addr));
- uword tags = 0;
- tags = RawObject::SizeTag::update(leftover_size, tags);
- tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, tags);
- raw->ptr()->tags_ = tags;
+ uword new_tags = RawObject::ClassIdTag::update(kTypedDataInt8ArrayCid, 0);
+ new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
+ uword tags = raw->ptr()->tags_;
+ uword old_tags;
+ // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
koda 2014/09/02 04:18:31 As long as this update happens strictly before the
+ do {
+ old_tags = tags;
+ tags = AtomicOperations::CompareAndSwapWord(
+ &raw->ptr()->tags_, old_tags, new_tags);
+ } while (tags != old_tags);
+
intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0));
ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size);
raw->ptr()->length_ = Smi::New(leftover_len);
@@ -827,10 +834,16 @@
// Update the leftover space as a basic object.
ASSERT(leftover_size == Object::InstanceSize());
RawObject* raw = reinterpret_cast<RawObject*>(RawObject::FromAddr(addr));
- uword tags = 0;
- tags = RawObject::SizeTag::update(leftover_size, tags);
- tags = RawObject::ClassIdTag::update(kInstanceCid, tags);
- raw->ptr()->tags_ = tags;
+ uword new_tags = RawObject::ClassIdTag::update(kInstanceCid, 0);
+ new_tags = RawObject::SizeTag::update(leftover_size, new_tags);
+ uword tags = raw->ptr()->tags_;
+ uword old_tags;
+ // TODO(iposva): Investigate whether CompareAndSwapWord is necessary.
+ do {
+ old_tags = tags;
+ tags = AtomicOperations::CompareAndSwapWord(
+ &raw->ptr()->tags_, old_tags, new_tags);
+ } while (tags != old_tags);
}
}
}
@@ -17194,14 +17207,11 @@
intptr_t str_length = this->Length();
ASSERT(length >= (str_length * this->CharSize()));
intptr_t class_id = raw()->GetClassId();
- intptr_t used_size = 0;
- intptr_t original_size = 0;
- uword tags = raw_ptr()->tags_;
ASSERT(!InVMHeap());
if (class_id == kOneByteStringCid) {
- used_size = ExternalOneByteString::InstanceSize();
- original_size = OneByteString::InstanceSize(str_length);
+ intptr_t used_size = ExternalOneByteString::InstanceSize();
+ intptr_t original_size = OneByteString::InstanceSize(str_length);
ASSERT(original_size >= used_size);
// Copy the data into the external array.
@@ -17209,11 +17219,22 @@
memmove(array, OneByteString::CharAddr(*this, 0), str_length);
}
+ // If there is any left over space fill it with either an Array object or
koda 2014/09/02 04:18:31 is -> will be
+ // just a plain object (depending on the amount of left over space) so
+ // that it can be traversed over successfully during garbage collection.
+ Object::MakeUnusedSpaceTraversable(*this, original_size, used_size);
+
// Update the class information of the object.
const intptr_t class_id = kExternalOneByteStringCid;
- tags = RawObject::SizeTag::update(used_size, tags);
- tags = RawObject::ClassIdTag::update(class_id, tags);
- raw_ptr()->tags_ = tags;
+ uword tags = raw_ptr()->tags_;
+ uword old_tags;
+ do {
+ old_tags = tags;
+ uword new_tags = RawObject::SizeTag::update(used_size, old_tags);
+ new_tags = RawObject::ClassIdTag::update(class_id, new_tags);
+ tags = AtomicOperations::CompareAndSwapWord(
+ &raw_ptr()->tags_, old_tags, new_tags);
+ } while (tags != old_tags);
result = this->raw();
const uint8_t* ext_array = reinterpret_cast<const uint8_t*>(array);
ExternalStringData<uint8_t>* ext_data = new ExternalStringData<uint8_t>(
@@ -17226,8 +17247,8 @@
finalizer = ExternalOneByteString::Finalize;
} else {
ASSERT(class_id == kTwoByteStringCid);
- used_size = ExternalTwoByteString::InstanceSize();
- original_size = TwoByteString::InstanceSize(str_length);
+ intptr_t used_size = ExternalTwoByteString::InstanceSize();
+ intptr_t original_size = TwoByteString::InstanceSize(str_length);
ASSERT(original_size >= used_size);
// Copy the data into the external array.
@@ -17237,11 +17258,22 @@
(str_length * kTwoByteChar));
}
+ // If there is any left over space fill it with either an Array object or
koda 2014/09/02 04:18:31 Ditto.
+ // just a plain object (depending on the amount of left over space) so
+ // that it can be traversed over successfully during garbage collection.
+ Object::MakeUnusedSpaceTraversable(*this, original_size, used_size);
+
// Update the class information of the object.
const intptr_t class_id = kExternalTwoByteStringCid;
- tags = RawObject::SizeTag::update(used_size, tags);
- tags = RawObject::ClassIdTag::update(class_id, tags);
- raw_ptr()->tags_ = tags;
+ uword tags = raw_ptr()->tags_;
+ uword old_tags;
+ do {
+ old_tags = tags;
+ uword new_tags = RawObject::SizeTag::update(used_size, old_tags);
+ new_tags = RawObject::ClassIdTag::update(class_id, new_tags);
+ tags = AtomicOperations::CompareAndSwapWord(
+ &raw_ptr()->tags_, old_tags, new_tags);
+ } while (tags != old_tags);
result = this->raw();
const uint16_t* ext_array = reinterpret_cast<const uint16_t*>(array);
ExternalStringData<uint16_t>* ext_data = new ExternalStringData<uint16_t>(
@@ -17253,11 +17285,6 @@
external_data = ext_data;
finalizer = ExternalTwoByteString::Finalize;
}
-
- // If there is any left over space fill it with either an Array object or
- // just a plain object (depending on the amount of left over space) so
- // that it can be traversed over successfully during garbage collection.
- Object::MakeUnusedSpaceTraversable(*this, original_size, used_size);
} // NoGCScope
AddFinalizer(result, external_data, finalizer);
return this->raw();
@@ -18073,8 +18100,14 @@
void Array::MakeImmutable() const {
NoGCScope no_gc;
uword tags = raw_ptr()->tags_;
- tags = RawObject::ClassIdTag::update(kImmutableArrayCid, tags);
- raw_ptr()->tags_ = tags;
+ uword old_tags;
+ do {
+ old_tags = tags;
+ uword new_tags = RawObject::ClassIdTag::update(kImmutableArrayCid,
+ old_tags);
+ tags = AtomicOperations::CompareAndSwapWord(
+ &raw_ptr()->tags_, old_tags, new_tags);
+ } while (tags != old_tags);
}
@@ -18155,22 +18188,27 @@
intptr_t used_size = Array::InstanceSize(used_len);
NoGCScope no_gc;
+ // If there is any left over space fill it with either an Array object or
koda 2014/09/02 04:18:31 Ditto.
+ // just a plain object (depending on the amount of left over space) so
+ // that it can be traversed over successfully during garbage collection.
+ Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size);
+
// Update the size in the header field and length of the array object.
uword tags = array.raw_ptr()->tags_;
ASSERT(kArrayCid == RawObject::ClassIdTag::decode(tags));
- tags = RawObject::SizeTag::update(used_size, tags);
- array.raw_ptr()->tags_ = tags;
+ uword old_tags;
+ do {
+ old_tags = tags;
+ uword new_tags = RawObject::SizeTag::update(used_size, old_tags);
+ tags = AtomicOperations::CompareAndSwapWord(
+ &array.raw_ptr()->tags_, old_tags, new_tags);
+ } while (tags != old_tags);
array.SetLength(used_len);
// Null the GrowableObjectArray, we are removing it's backing array.
growable_array.SetLength(0);
growable_array.SetData(Object::empty_array());
- // If there is any left over space fill it with either an Array object or
- // just a plain object (depending on the amount of left over space) so
- // that it can be traversed over successfully during garbage collection.
- Object::MakeUnusedSpaceTraversable(array, capacity_size, used_size);
-
return array.raw();
}

Powered by Google App Engine
This is Rietveld 408576698