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
ContextMeasure(Context * context)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
IsShared(HeapObject * object)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
MeasureObject(HeapObject * object)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
MeasureDeferredObjects()54 void ContextMeasure::MeasureDeferredObjects() {
55 while (deferred_objects_.length() > 0) {
56 MeasureAndRecurse(deferred_objects_.RemoveLast());
57 }
58 }
59
60
MeasureAndRecurse(HeapObject * object)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
VisitPointers(Object ** start,Object ** end)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