• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_->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->IsAccessorInfo()) 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 (reference_map_.Lookup(object).is_valid()) return;
41   if (root_index_map_.Lookup(object) != RootIndexMap::kInvalidRootIndex) return;
42   if (IsShared(object)) return;
43   reference_map_.Add(object, SerializerReference::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