Home | History | Annotate | Download | only in src
      1 // Copyright 2015 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "src/context-measure.h"
      6 
      7 #include "src/base/logging.h"
      8 #include "src/contexts.h"
      9 #include "src/objects-inl.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 
     14 ContextMeasure::ContextMeasure(Context* context)
     15     : context_(context),
     16       root_index_map_(context->GetIsolate()),
     17       recursion_depth_(0),
     18       count_(0),
     19       size_(0) {
     20   DCHECK(context_->IsNativeContext());
     21   Object* next_link = context_->get(Context::NEXT_CONTEXT_LINK);
     22   MeasureObject(context_);
     23   MeasureDeferredObjects();
     24   context_->set(Context::NEXT_CONTEXT_LINK, next_link);
     25 }
     26 
     27 
     28 bool ContextMeasure::IsShared(HeapObject* object) {
     29   if (object->IsScript()) return true;
     30   if (object->IsSharedFunctionInfo()) return true;
     31   if (object->IsScopeInfo()) return true;
     32   if (object->IsCode() && !Code::cast(object)->is_optimized_code()) return true;
     33   if (object->IsExecutableAccessorInfo()) return true;
     34   if (object->IsWeakCell()) return true;
     35   return false;
     36 }
     37 
     38 
     39 void ContextMeasure::MeasureObject(HeapObject* object) {
     40   if (back_reference_map_.Lookup(object).is_valid()) return;
     41   if (root_index_map_.Lookup(object) != RootIndexMap::kInvalidRootIndex) return;
     42   if (IsShared(object)) return;
     43   back_reference_map_.Add(object, BackReference::DummyReference());
     44   recursion_depth_++;
     45   if (recursion_depth_ > kMaxRecursion) {
     46     deferred_objects_.Add(object);
     47   } else {
     48     MeasureAndRecurse(object);
     49   }
     50   recursion_depth_--;
     51 }
     52 
     53 
     54 void ContextMeasure::MeasureDeferredObjects() {
     55   while (deferred_objects_.length() > 0) {
     56     MeasureAndRecurse(deferred_objects_.RemoveLast());
     57   }
     58 }
     59 
     60 
     61 void ContextMeasure::MeasureAndRecurse(HeapObject* object) {
     62   int size = object->Size();
     63   count_++;
     64   size_ += size;
     65   Map* map = object->map();
     66   MeasureObject(map);
     67   object->IterateBody(map->instance_type(), size, this);
     68 }
     69 
     70 
     71 void ContextMeasure::VisitPointers(Object** start, Object** end) {
     72   for (Object** current = start; current < end; current++) {
     73     if ((*current)->IsSmi()) continue;
     74     MeasureObject(HeapObject::cast(*current));
     75   }
     76 }
     77 }  // namespace internal
     78 }  // namespace v8
     79