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