Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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 : #include "gc/ZoneGroup.h"
8 :
9 : #include "jscntxt.h"
10 :
11 : #include "jit/IonBuilder.h"
12 : #include "jit/JitCompartment.h"
13 :
14 : namespace js {
15 :
16 21 : ZoneGroup::ZoneGroup(JSRuntime* runtime)
17 : : runtime(runtime),
18 42 : ownerContext_(TlsContext.get()),
19 : enterCount(1),
20 : zones_(this),
21 : usedByHelperThread(false),
22 : #ifdef DEBUG
23 : ionBailAfter_(this, 0),
24 : #endif
25 : jitZoneGroup(this, nullptr),
26 : debuggerList_(this),
27 : numFinishedBuilders(0),
28 63 : ionLazyLinkListSize_(0)
29 21 : {}
30 :
31 : bool
32 21 : ZoneGroup::init()
33 : {
34 42 : AutoLockGC lock(runtime);
35 :
36 21 : jitZoneGroup = js_new<jit::JitZoneGroup>(this);
37 21 : if (!jitZoneGroup)
38 0 : return false;
39 :
40 21 : return true;
41 : }
42 :
43 0 : ZoneGroup::~ZoneGroup()
44 : {
45 : #ifdef DEBUG
46 : {
47 0 : AutoLockHelperThreadState lock;
48 0 : MOZ_ASSERT(ionLazyLinkListSize_ == 0);
49 0 : MOZ_ASSERT(ionLazyLinkList().isEmpty());
50 : }
51 : #endif
52 :
53 0 : js_delete(jitZoneGroup.ref());
54 :
55 0 : if (this == runtime->gc.systemZoneGroup)
56 0 : runtime->gc.systemZoneGroup = nullptr;
57 0 : }
58 :
59 : void
60 83695 : ZoneGroup::enter(JSContext* cx)
61 : {
62 83695 : if (ownerContext().context() == cx) {
63 81086 : MOZ_ASSERT(enterCount);
64 : } else {
65 2609 : if (useExclusiveLocking) {
66 2233 : MOZ_ASSERT(!usedByHelperThread);
67 0 : while (ownerContext().context() != nullptr) {
68 0 : cx->yieldToEmbedding();
69 : }
70 : }
71 2609 : MOZ_RELEASE_ASSERT(ownerContext().context() == nullptr);
72 2609 : MOZ_ASSERT(enterCount == 0);
73 2609 : ownerContext_ = CooperatingContext(cx);
74 2609 : if (cx->generationalDisabled)
75 6 : nursery().disable();
76 :
77 : // Finish any Ion compilations in this zone group, in case compilation
78 : // finished for some script in this group while no thread was in this
79 : // group.
80 2609 : jit::AttachFinishedCompilations(this, nullptr);
81 : }
82 83695 : enterCount++;
83 83695 : }
84 :
85 : void
86 83706 : ZoneGroup::leave()
87 : {
88 83706 : MOZ_ASSERT(ownedByCurrentThread());
89 83706 : MOZ_ASSERT(enterCount);
90 83706 : if (--enterCount == 0)
91 2627 : ownerContext_ = CooperatingContext(nullptr);
92 83706 : }
93 :
94 : bool
95 937183 : ZoneGroup::ownedByCurrentThread()
96 : {
97 937183 : MOZ_ASSERT(TlsContext.get());
98 937194 : return ownerContext().context() == TlsContext.get();
99 : }
100 :
101 : ZoneGroup::IonBuilderList&
102 513 : ZoneGroup::ionLazyLinkList()
103 : {
104 513 : MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
105 : "Should only be mutated by the active thread.");
106 513 : return ionLazyLinkList_.ref();
107 : }
108 :
109 : void
110 8 : ZoneGroup::ionLazyLinkListRemove(jit::IonBuilder* builder)
111 : {
112 8 : MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
113 : "Should only be mutated by the active thread.");
114 8 : MOZ_ASSERT(this == builder->script()->zone()->group());
115 8 : MOZ_ASSERT(ionLazyLinkListSize_ > 0);
116 :
117 8 : builder->removeFrom(ionLazyLinkList());
118 8 : ionLazyLinkListSize_--;
119 :
120 8 : MOZ_ASSERT(ionLazyLinkList().isEmpty() == (ionLazyLinkListSize_ == 0));
121 8 : }
122 :
123 : void
124 8 : ZoneGroup::ionLazyLinkListAdd(jit::IonBuilder* builder)
125 : {
126 8 : MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime),
127 : "Should only be mutated by the active thread.");
128 8 : MOZ_ASSERT(this == builder->script()->zone()->group());
129 8 : ionLazyLinkList().insertFront(builder);
130 8 : ionLazyLinkListSize_++;
131 8 : }
132 :
133 9 : } // namespace js
|