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 #ifndef vm_Caches_inl_h
8 #define vm_Caches_inl_h
9 
10 #include "vm/Caches.h"
11 
12 #include "gc/Allocator.h"
13 #include "gc/GCProbes.h"
14 #include "vm/Probes.h"
15 #include "vm/Realm.h"
16 
17 #include "vm/JSObject-inl.h"
18 
19 namespace js {
20 
lookupProto(const JSClass * clasp,JSObject * proto,gc::AllocKind kind,EntryIndex * pentry)21 inline bool NewObjectCache::lookupProto(const JSClass* clasp, JSObject* proto,
22                                         gc::AllocKind kind,
23                                         EntryIndex* pentry) {
24   MOZ_ASSERT(!proto->is<GlobalObject>());
25   return lookup(clasp, proto, kind, pentry);
26 }
27 
lookupGlobal(const JSClass * clasp,GlobalObject * global,gc::AllocKind kind,EntryIndex * pentry)28 inline bool NewObjectCache::lookupGlobal(const JSClass* clasp,
29                                          GlobalObject* global,
30                                          gc::AllocKind kind,
31                                          EntryIndex* pentry) {
32   return lookup(clasp, global, kind, pentry);
33 }
34 
fillGlobal(EntryIndex entry,const JSClass * clasp,GlobalObject * global,gc::AllocKind kind,NativeObject * obj)35 inline void NewObjectCache::fillGlobal(EntryIndex entry, const JSClass* clasp,
36                                        GlobalObject* global, gc::AllocKind kind,
37                                        NativeObject* obj) {
38   // MOZ_ASSERT(global == obj->getGlobal());
39   return fill(entry, clasp, global, kind, obj);
40 }
41 
newObjectFromHit(JSContext * cx,EntryIndex entryIndex,gc::InitialHeap heap)42 inline NativeObject* NewObjectCache::newObjectFromHit(JSContext* cx,
43                                                       EntryIndex entryIndex,
44                                                       gc::InitialHeap heap) {
45   MOZ_ASSERT(unsigned(entryIndex) < mozilla::ArrayLength(entries));
46   Entry* entry = &entries[entryIndex];
47 
48   NativeObject* templateObj =
49       reinterpret_cast<NativeObject*>(&entry->templateObject);
50 
51   // Do an end run around JSObject::group() to avoid doing AutoUnprotectCell
52   // on the templateObj, which is not a GC thing and can't use
53   // runtimeFromAnyThread.
54   ObjectGroup* group = templateObj->groupRaw();
55 
56   // If we did the lookup based on the proto we might have a group/object from a
57   // different (same-compartment) realm, so we have to do a realm check.
58   if (group->realm() != cx->realm()) {
59     return nullptr;
60   }
61 
62   MOZ_ASSERT(!group->hasUnanalyzedPreliminaryObjects());
63 
64   {
65     AutoSweepObjectGroup sweepGroup(group);
66     if (group->shouldPreTenure(sweepGroup)) {
67       heap = gc::TenuredHeap;
68     }
69   }
70 
71   if (cx->runtime()->gc.upcomingZealousGC()) {
72     return nullptr;
73   }
74 
75   NativeObject* obj = static_cast<NativeObject*>(AllocateObject<NoGC>(
76       cx, entry->kind, /* nDynamicSlots = */ 0, heap, group->clasp()));
77   if (!obj) {
78     return nullptr;
79   }
80 
81   copyCachedToObject(obj, templateObj, entry->kind);
82 
83   if (group->clasp()->shouldDelayMetadataBuilder()) {
84     cx->realm()->setObjectPendingMetadata(cx, obj);
85   } else {
86     obj = static_cast<NativeObject*>(SetNewObjectMetadata(cx, obj));
87   }
88 
89   probes::CreateObject(cx, obj);
90   gc::gcprobes::CreateObject(obj);
91   return obj;
92 }
93 
94 } /* namespace js */
95 
96 #endif /* vm_Caches_inl_h */
97