Chromium Code Reviews| Index: src/mark-compact.cc |
| diff --git a/src/mark-compact.cc b/src/mark-compact.cc |
| index 6c16f61d25f0f1c80f5a62af7121230698b5835c..9594f34ad8275f74e16675c5d5c6e894b065c69b 100644 |
| --- a/src/mark-compact.cc |
| +++ b/src/mark-compact.cc |
| @@ -223,6 +223,97 @@ static void VerifyEvacuation(Heap* heap) { |
| VerifyEvacuationVisitor visitor; |
| heap->IterateStrongRoots(&visitor, VISIT_ALL); |
| } |
| + |
| + |
| +class VerifyGlobalContextSeparationVisitor: public ObjectVisitor { |
| + public: |
| + VerifyGlobalContextSeparationVisitor() : current_global_context_(NULL) {} |
| + |
| + void VisitPointers(Object** start, Object** end) { |
| + for (Object** current = start; current < end; current++) { |
| + if ((*current)->IsHeapObject()) { |
| + HeapObject* object = HeapObject::cast(*current); |
| + if (object->IsString()) continue; |
| + switch (object->map()->instance_type()) { |
| + case JS_FUNCTION_TYPE: |
| + CheckContext(JSFunction::cast(object)->context()); |
| + break; |
| + case JS_GLOBAL_PROXY_TYPE: |
| + CheckContext(JSGlobalProxy::cast(object)->context()); |
| + break; |
| + case JS_GLOBAL_OBJECT_TYPE: |
| + case JS_BUILTINS_OBJECT_TYPE: |
| + CheckContext(GlobalObject::cast(object)->global_context()); |
| + break; |
| + case JS_ARRAY_TYPE: |
| + case JS_DATE_TYPE: |
| + case JS_OBJECT_TYPE: |
| + case JS_REGEXP_TYPE: |
| + VisitPointer(HeapObject::RawField(object, JSObject::kMapOffset)); |
| + break; |
| + case MAP_TYPE: |
| + VisitPointer(HeapObject::RawField(object, Map::kPrototypeOffset)); |
| + VisitPointer(HeapObject::RawField(object, Map::kConstructorOffset)); |
| + break; |
| + case FIXED_ARRAY_TYPE: |
| + if (object->IsContext()) { |
| + CheckContext(object); |
| + } else { |
| + FixedArray* array = FixedArray::cast(object); |
| + int length = array->length(); |
| + array->set_length(0); |
|
Toon Verwaest
2012/07/30 10:09:38
Adding a comment here is probably useful. Why do w
Michael Starzinger
2012/07/30 10:44:32
Done. For JSObjects we don't have the problem, bec
|
| + array->IterateBody( |
| + FIXED_ARRAY_TYPE, FixedArray::SizeFor(length), this); |
| + array->set_length(length); |
| + } |
| + break; |
| + case JS_GLOBAL_PROPERTY_CELL_TYPE: |
| + case JS_PROXY_TYPE: |
| + case JS_VALUE_TYPE: |
| + case TYPE_FEEDBACK_INFO_TYPE: |
| + object->Iterate(this); |
| + break; |
| + case ACCESSOR_INFO_TYPE: |
| + case BYTE_ARRAY_TYPE: |
| + case CALL_HANDLER_INFO_TYPE: |
| + case CODE_TYPE: |
| + case FIXED_DOUBLE_ARRAY_TYPE: |
| + case HEAP_NUMBER_TYPE: |
| + case INTERCEPTOR_INFO_TYPE: |
| + case ODDBALL_TYPE: |
| + case SCRIPT_TYPE: |
| + case SHARED_FUNCTION_INFO_TYPE: |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| + } |
| + } |
| + } |
| + |
| + private: |
| + void CheckContext(Object* context) { |
| + if (!context->IsContext()) return; |
| + Context* global_context = Context::cast(context)->global_context(); |
| + if (current_global_context_ == NULL) { |
| + current_global_context_ = global_context; |
| + } else { |
| + CHECK_EQ(current_global_context_, global_context); |
| + } |
| + } |
| + |
| + Context* current_global_context_; |
| +}; |
| + |
| + |
| +static void VerifyGlobalContextSeparation(Heap* heap) { |
| + HeapObjectIterator it(heap->code_space()); |
| + |
| + for (Object* object = it.Next(); object != NULL; object = it.Next()) { |
| + VerifyGlobalContextSeparationVisitor visitor; |
| + Code::cast(object)->CodeIterateBody(&visitor); |
| + } |
| +} |
| #endif |
| @@ -296,6 +387,12 @@ void MarkCompactCollector::CollectGarbage() { |
| if (!FLAG_collect_maps) ReattachInitialMaps(); |
| +#ifdef DEBUG |
| + if (FLAG_verify_global_context_separation) { |
| + VerifyGlobalContextSeparation(heap_); |
| + } |
| +#endif |
| + |
| Finish(); |
| tracer_ = NULL; |