da4aae498b668eed85afb4dd4b38948ca34e1b02
[platform/upstream/v8.git] / src / context-measure.cc
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 }
78 }  // namespace v8::internal