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 <iterator>
13 
14 #include "gc/Allocator.h"
15 #include "gc/GCProbes.h"
16 #include "vm/Probes.h"
17 #include "vm/Realm.h"
18 
19 #include "vm/JSObject-inl.h"
20 
21 namespace js {
22 
lookupProto(const JSClass * clasp,JSObject * proto,gc::AllocKind kind,EntryIndex * pentry)23 inline bool NewObjectCache::lookupProto(const JSClass* clasp, JSObject* proto,
24                                         gc::AllocKind kind,
25                                         EntryIndex* pentry) {
26   MOZ_ASSERT(!proto->is<GlobalObject>());
27   return lookup(clasp, proto, kind, pentry);
28 }
29 
lookupGlobal(const JSClass * clasp,GlobalObject * global,gc::AllocKind kind,EntryIndex * pentry)30 inline bool NewObjectCache::lookupGlobal(const JSClass* clasp,
31                                          GlobalObject* global,
32                                          gc::AllocKind kind,
33                                          EntryIndex* pentry) {
34   return lookup(clasp, global, kind, pentry);
35 }
36 
fillGlobal(EntryIndex entry,const JSClass * clasp,GlobalObject * global,gc::AllocKind kind,NativeObject * obj)37 inline void NewObjectCache::fillGlobal(EntryIndex entry, const JSClass* clasp,
38                                        GlobalObject* global, gc::AllocKind kind,
39                                        NativeObject* obj) {
40   // MOZ_ASSERT(global == obj->getGlobal());
41   return fill(entry, clasp, global, kind, obj);
42 }
43 
newObjectFromHit(JSContext * cx,EntryIndex entryIndex,gc::InitialHeap heap,gc::AllocSite * site)44 inline NativeObject* NewObjectCache::newObjectFromHit(JSContext* cx,
45                                                       EntryIndex entryIndex,
46                                                       gc::InitialHeap heap,
47                                                       gc::AllocSite* site) {
48   MOZ_ASSERT(unsigned(entryIndex) < std::size(entries));
49   Entry* entry = &entries[entryIndex];
50 
51   NativeObject* templateObj =
52       reinterpret_cast<NativeObject*>(&entry->templateObject);
53 
54   // If we did the lookup based on the proto we might have a shape/object from a
55   // different (same-compartment) realm, so we have to do a realm check.
56   if (templateObj->shape()->realm() != cx->realm()) {
57     return nullptr;
58   }
59 
60   if (cx->runtime()->gc.upcomingZealousGC()) {
61     return nullptr;
62   }
63 
64   const JSClass* clasp = templateObj->getClass();
65   NativeObject* obj = static_cast<NativeObject*>(AllocateObject<NoGC>(
66       cx, entry->kind, /* nDynamicSlots = */ 0, heap, clasp, site));
67   if (!obj) {
68     return nullptr;
69   }
70 
71   copyCachedToObject(obj, templateObj, entry->kind);
72 
73   if (clasp->shouldDelayMetadataBuilder()) {
74     cx->realm()->setObjectPendingMetadata(cx, obj);
75   } else {
76     obj = static_cast<NativeObject*>(SetNewObjectMetadata(cx, obj));
77   }
78 
79   probes::CreateObject(cx, obj);
80   gc::gcprobes::CreateObject(obj);
81   return obj;
82 }
83 
84 } /* namespace js */
85 
86 #endif /* vm_Caches_inl_h */
87