// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/context-measure.h" #include "src/base/logging.h" #include "src/contexts.h" #include "src/objects-inl.h" namespace v8 { namespace internal { ContextMeasure::ContextMeasure(Context* context) : context_(context), root_index_map_(context->GetIsolate()), recursion_depth_(0), count_(0), size_(0) { DCHECK(context_->IsNativeContext()); Object* next_link = context_->next_context_link(); MeasureObject(context_); MeasureDeferredObjects(); context_->set(Context::NEXT_CONTEXT_LINK, next_link); } bool ContextMeasure::IsShared(HeapObject* object) { if (object->IsScript()) return true; if (object->IsSharedFunctionInfo()) return true; if (object->IsScopeInfo()) return true; if (object->IsCode() && !Code::cast(object)->is_optimized_code()) return true; if (object->IsAccessorInfo()) return true; if (object->IsWeakCell()) return true; return false; } void ContextMeasure::MeasureObject(HeapObject* object) { if (reference_map_.Lookup(object).is_valid()) return; if (root_index_map_.Lookup(object) != RootIndexMap::kInvalidRootIndex) return; if (IsShared(object)) return; reference_map_.Add(object, SerializerReference::DummyReference()); recursion_depth_++; if (recursion_depth_ > kMaxRecursion) { deferred_objects_.Add(object); } else { MeasureAndRecurse(object); } recursion_depth_--; } void ContextMeasure::MeasureDeferredObjects() { while (deferred_objects_.length() > 0) { MeasureAndRecurse(deferred_objects_.RemoveLast()); } } void ContextMeasure::MeasureAndRecurse(HeapObject* object) { int size = object->Size(); count_++; size_ += size; Map* map = object->map(); MeasureObject(map); object->IterateBody(map->instance_type(), size, this); } void ContextMeasure::VisitPointers(Object** start, Object** end) { for (Object** current = start; current < end; current++) { if ((*current)->IsSmi()) continue; MeasureObject(HeapObject::cast(*current)); } } } // namespace internal } // namespace v8