1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /* JS symbol tables. */
8 
9 #include "vm/ShapeZone.h"
10 
11 #include "gc/Marking-inl.h"
12 #include "vm/JSContext-inl.h"
13 #include "vm/Shape-inl.h"
14 
15 using namespace js;
16 
fixupPropMapShapeTableAfterMovingGC()17 void ShapeZone::fixupPropMapShapeTableAfterMovingGC() {
18   for (PropMapShapeSet::Enum e(propMapShapes); !e.empty(); e.popFront()) {
19     Shape* shape = MaybeForwarded(e.front().unbarrieredGet());
20     SharedPropMap* map = MaybeForwarded(shape->propMap())->asShared();
21     BaseShape* base = MaybeForwarded(shape->base());
22 
23     PropMapShapeSet::Lookup lookup(base, shape->numFixedSlots(), map,
24                                    shape->propMapLength(),
25                                    shape->objectFlags());
26     e.rekeyFront(lookup, shape);
27   }
28 }
29 
30 #ifdef JSGC_HASH_TABLE_CHECKS
checkTablesAfterMovingGC()31 void ShapeZone::checkTablesAfterMovingGC() {
32   // Assert that the moving GC worked and that nothing is left in the tables
33   // that points into the nursery, and that the hash table entries are
34   // discoverable.
35 
36   for (auto r = initialPropMaps.all(); !r.empty(); r.popFront()) {
37     SharedPropMap* map = r.front().unbarrieredGet();
38     CheckGCThingAfterMovingGC(map);
39 
40     InitialPropMapHasher::Lookup lookup(map->getKey(0),
41                                         map->getPropertyInfo(0));
42     InitialPropMapSet::Ptr ptr = initialPropMaps.lookup(lookup);
43     MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
44   }
45 
46   for (auto r = baseShapes.all(); !r.empty(); r.popFront()) {
47     BaseShape* base = r.front().unbarrieredGet();
48     CheckGCThingAfterMovingGC(base);
49 
50     BaseShapeHasher::Lookup lookup(base->clasp(), base->realm(), base->proto());
51     BaseShapeSet::Ptr ptr = baseShapes.lookup(lookup);
52     MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
53   }
54 
55   for (auto r = initialShapes.all(); !r.empty(); r.popFront()) {
56     Shape* shape = r.front().unbarrieredGet();
57     CheckGCThingAfterMovingGC(shape);
58 
59     using Lookup = InitialShapeHasher::Lookup;
60     Lookup lookup(shape->getObjectClass(), shape->realm(), shape->proto(),
61                   shape->numFixedSlots(), shape->objectFlags());
62     InitialShapeSet::Ptr ptr = initialShapes.lookup(lookup);
63     MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
64   }
65 
66   for (auto r = propMapShapes.all(); !r.empty(); r.popFront()) {
67     Shape* shape = r.front().unbarrieredGet();
68     CheckGCThingAfterMovingGC(shape);
69 
70     using Lookup = PropMapShapeHasher::Lookup;
71     Lookup lookup(shape->base(), shape->numFixedSlots(), shape->sharedPropMap(),
72                   shape->propMapLength(), shape->objectFlags());
73     PropMapShapeSet::Ptr ptr = propMapShapes.lookup(lookup);
74     MOZ_RELEASE_ASSERT(ptr.found() && &*ptr == &r.front());
75   }
76 }
77 #endif  // JSGC_HASH_TABLE_CHECKS
78 
ShapeZone(Zone * zone)79 ShapeZone::ShapeZone(Zone* zone)
80     : baseShapes(zone),
81       initialPropMaps(zone),
82       initialShapes(zone),
83       propMapShapes(zone) {}
84 
clearTables(JSFreeOp * fop)85 void ShapeZone::clearTables(JSFreeOp* fop) {
86   baseShapes.clear();
87   initialPropMaps.clear();
88   initialShapes.clear();
89   propMapShapes.clear();
90   purgeShapeCaches(fop);
91 }
92 
purgeShapeCaches(JSFreeOp * fop)93 void ShapeZone::purgeShapeCaches(JSFreeOp* fop) {
94   for (Shape* shape : shapesWithCache) {
95     MaybeForwarded(shape)->purgeCache(fop);
96   }
97   shapesWithCache.clearAndFree();
98 }
99 
addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,size_t * initialPropMapTable,size_t * shapeTables)100 void ShapeZone::addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
101                                        size_t* initialPropMapTable,
102                                        size_t* shapeTables) {
103   *shapeTables += baseShapes.sizeOfExcludingThis(mallocSizeOf);
104   *initialPropMapTable += initialPropMaps.sizeOfExcludingThis(mallocSizeOf);
105   *shapeTables += initialShapes.sizeOfExcludingThis(mallocSizeOf);
106   *shapeTables += propMapShapes.sizeOfExcludingThis(mallocSizeOf);
107   *shapeTables += shapesWithCache.sizeOfExcludingThis(mallocSizeOf);
108 }
109