blob: 00c11eebc2cf40a548d16270c4173242f0e78322 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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
11namespace v8 {
12namespace internal {
13
14ContextMeasure::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());
Ben Murdochc5610432016-08-08 18:44:38 +010021 Object* next_link = context_->next_context_link();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022 MeasureObject(context_);
23 MeasureDeferredObjects();
24 context_->set(Context::NEXT_CONTEXT_LINK, next_link);
25}
26
27
28bool 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;
Ben Murdoch097c5b22016-05-18 11:27:45 +010033 if (object->IsAccessorInfo()) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034 if (object->IsWeakCell()) return true;
35 return false;
36}
37
38
39void ContextMeasure::MeasureObject(HeapObject* object) {
Ben Murdochc5610432016-08-08 18:44:38 +010040 if (reference_map_.Lookup(object).is_valid()) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000041 if (root_index_map_.Lookup(object) != RootIndexMap::kInvalidRootIndex) return;
42 if (IsShared(object)) return;
Ben Murdochc5610432016-08-08 18:44:38 +010043 reference_map_.Add(object, SerializerReference::DummyReference());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 recursion_depth_++;
45 if (recursion_depth_ > kMaxRecursion) {
46 deferred_objects_.Add(object);
47 } else {
48 MeasureAndRecurse(object);
49 }
50 recursion_depth_--;
51}
52
53
54void ContextMeasure::MeasureDeferredObjects() {
55 while (deferred_objects_.length() > 0) {
56 MeasureAndRecurse(deferred_objects_.RemoveLast());
57 }
58}
59
60
61void 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
71void 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