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