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

Unified Diff: src/objects.cc

Issue 8831: Remove unused maps during marking garbage collections. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years, 2 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 | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
===================================================================
--- src/objects.cc (revision 636)
+++ src/objects.cc (working copy)
@@ -333,7 +333,7 @@
// Check if we're allowed to read from the current object. Note
// that even though we may not actually end up loading the named
// property from the current object, we still check that we have
- // access to the it.
+ // access to it.
JSObject* checked = JSObject::cast(current);
if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) {
return checked->GetPropertyWithFailedAccessCheck(receiver,
@@ -4052,6 +4052,67 @@
}
+void Map::CreateBackPointers() {
+ DescriptorArray* descriptors = instance_descriptors();
+ for (DescriptorReader r(descriptors); !r.eos(); r.advance()) {
+ if (r.type() == MAP_TRANSITION) {
+ // Get target.
+ Map* target = Map::cast(r.GetValue());
+#ifdef DEBUG
+ // Verify target.
+ Object* source_prototype = prototype();
+ Object* target_prototype = target->prototype();
+ ASSERT(source_prototype->IsJSObject() ||
+ source_prototype->IsMap() ||
+ source_prototype->IsNull());
+ ASSERT(target_prototype->IsJSObject() ||
+ target_prototype->IsNull());
+ ASSERT(source_prototype->IsMap() ||
+ source_prototype == target_prototype);
+#endif
+ // Point target back to source. set_prototype() will not let us set
+ // the prototype to a map, as we do here.
+ *RawField(target, kPrototypeOffset) = this;
+ }
+ }
+}
+
+
+void Map::ClearNonLiveTransitions(Object* real_prototype) {
+ // Live DescriptorArray objects will be marked, so we must use
+ // low-level accessors to get and modify their data.
+ DescriptorArray* d = reinterpret_cast<DescriptorArray*>(
+ *RawField(this, Map::kInstanceDescriptorsOffset));
+ if (d == Heap::empty_descriptor_array()) return;
+ Smi* NullDescriptorDetails =
+ PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi();
+ FixedArray* contents = reinterpret_cast<FixedArray*>(
+ d->get(DescriptorArray::kContentArrayIndex));
+ ASSERT(contents->length() >= 2);
+ for (int i = 0; i < contents->length(); i += 2) {
+ // If the pair (value, details) is a map transition,
+ // check if the target is live. If not, null the descriptor.
+ // Also drop the back pointer for that map transition, so that this
+ // map is not reached again by following a back pointer from a
+ // non-live object.
+ PropertyDetails details(Smi::cast(contents->get(i + 1)));
+ if (details.type() == MAP_TRANSITION) {
+ Map* target = reinterpret_cast<Map*>(contents->get(i));
+ ASSERT(target->IsHeapObject());
+ if (!target->IsMarked()) {
+ ASSERT(target->IsMap());
+ contents->set(i + 1, NullDescriptorDetails, SKIP_WRITE_BARRIER);
+ contents->set(i, Heap::null_value(), SKIP_WRITE_BARRIER);
+ ASSERT(target->prototype() == this ||
+ target->prototype() == real_prototype);
+ // Getter prototype() is read-only, set_prototype() has side effects.
+ *RawField(target, Map::kPrototypeOffset) = real_prototype;
+ }
+ }
+ }
+}
+
+
void Map::MapIterateBody(ObjectVisitor* v) {
// Assumes all Object* members are contiguously allocated!
IteratePointers(v, kPrototypeOffset, kCodeCacheOffset + kPointerSize);
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698