Bug 1890750 - Part 1: Include NATIVE_JIT_ENTRY in FunctionFlags::HasJitEntryFlags...
[gecko.git] / js / src / jit / JitHints.cpp
blob6b3783ea8a03ff2ae6d59de6d41927dc40bc7f2b
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/. */
7 #include "jit/JitHints-inl.h"
8 #include "vm/BytecodeLocation-inl.h"
9 #include "vm/JSScript-inl.h"
11 using namespace js;
12 using namespace js::jit;
14 JitHintsMap::~JitHintsMap() {
15 while (!ionHintQueue_.isEmpty()) {
16 IonHint* e = ionHintQueue_.popFirst();
17 js_delete(e);
19 ionHintMap_.clear();
22 JitHintsMap::IonHint* JitHintsMap::addIonHint(ScriptKey key,
23 ScriptToHintMap::AddPtr& p) {
24 UniquePtr<IonHint> hint = MakeUnique<IonHint>(key);
25 if (!hint) {
26 return nullptr;
29 if (!ionHintMap_.add(p, key, hint.get())) {
30 return nullptr;
33 ionHintQueue_.insertBack(hint.get());
35 if (ionHintMap_.count() > IonHintMaxEntries) {
36 IonHint* h = ionHintQueue_.popFirst();
37 ionHintMap_.remove(h->key());
38 js_delete(h);
41 return hint.release();
44 void JitHintsMap::updateAsRecentlyUsed(IonHint* hint) {
45 hint->remove();
46 ionHintQueue_.insertBack(hint);
49 bool JitHintsMap::recordIonCompilation(JSScript* script) {
50 ScriptKey key = getScriptKey(script);
51 if (!key) {
52 return true;
55 // Only add hints for scripts that will be eager baseline compiled.
56 if (!baselineHintMap_.mightContain(key)) {
57 return true;
60 auto p = ionHintMap_.lookupForAdd(key);
61 IonHint* hint = nullptr;
62 if (p) {
63 // Don't modify existing threshold values.
64 hint = p->value();
65 updateAsRecentlyUsed(hint);
66 } else {
67 hint = addIonHint(key, p);
68 if (!hint) {
69 return false;
73 hint->initThreshold(script->warmUpCountAtLastICStub());
74 return true;
77 bool JitHintsMap::getIonThresholdHint(JSScript* script,
78 uint32_t& thresholdOut) {
79 ScriptKey key = getScriptKey(script);
80 if (key) {
81 auto p = ionHintMap_.lookup(key);
82 if (p) {
83 IonHint* hint = p->value();
84 // If the threshold is 0, the hint only contains
85 // monomorphic inlining location information and
86 // may not have entered Ion before.
87 if (hint->threshold() != 0) {
88 updateAsRecentlyUsed(hint);
89 thresholdOut = hint->threshold();
90 return true;
94 return false;
97 void JitHintsMap::recordInvalidation(JSScript* script) {
98 ScriptKey key = getScriptKey(script);
99 if (key) {
100 auto p = ionHintMap_.lookup(key);
101 if (p) {
102 p->value()->incThreshold(InvalidationThresholdIncrement);
107 bool JitHintsMap::addMonomorphicInlineLocation(JSScript* script,
108 BytecodeLocation loc) {
109 ScriptKey key = getScriptKey(script);
110 if (!key) {
111 return true;
114 // Only add inline hints for scripts that will be eager baseline compiled.
115 if (!baselineHintMap_.mightContain(key)) {
116 return true;
119 auto p = ionHintMap_.lookupForAdd(key);
120 IonHint* hint = nullptr;
121 if (p) {
122 hint = p->value();
123 } else {
124 hint = addIonHint(key, p);
125 if (!hint) {
126 return false;
130 if (!hint->hasSpaceForMonomorphicInlineEntry()) {
131 return true;
134 uint32_t offset = loc.bytecodeToOffset(script);
135 return hint->addMonomorphicInlineOffset(offset);
138 bool JitHintsMap::hasMonomorphicInlineHintAtOffset(JSScript* script,
139 uint32_t offset) {
140 ScriptKey key = getScriptKey(script);
141 if (!key) {
142 return false;
145 auto p = ionHintMap_.lookup(key);
146 if (p) {
147 return p->value()->hasMonomorphicInlineOffset(offset);
150 return false;