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 : #ifndef jit_BaselineInspector_h
8 : #define jit_BaselineInspector_h
9 :
10 : #include "jit/BaselineIC.h"
11 : #include "jit/BaselineJIT.h"
12 : #include "jit/MIR.h"
13 :
14 : namespace js {
15 : namespace jit {
16 :
17 : class BaselineInspector;
18 :
19 : class ICInspector
20 : {
21 : protected:
22 : BaselineInspector* inspector_;
23 : jsbytecode* pc_;
24 : ICEntry* icEntry_;
25 :
26 0 : ICInspector(BaselineInspector* inspector, jsbytecode* pc, ICEntry* icEntry)
27 0 : : inspector_(inspector), pc_(pc), icEntry_(icEntry)
28 0 : { }
29 : };
30 :
31 : class SetElemICInspector : public ICInspector
32 : {
33 : public:
34 0 : SetElemICInspector(BaselineInspector* inspector, jsbytecode* pc, ICEntry* icEntry)
35 0 : : ICInspector(inspector, pc, icEntry)
36 0 : { }
37 :
38 : bool sawOOBDenseWrite() const;
39 : bool sawOOBTypedArrayWrite() const;
40 : };
41 :
42 : class BaselineInspector
43 : {
44 : private:
45 : JSScript* script;
46 : BaselineICEntry* prevLookedUpEntry;
47 :
48 : public:
49 179 : explicit BaselineInspector(JSScript* script)
50 179 : : script(script), prevLookedUpEntry(nullptr)
51 : {
52 179 : MOZ_ASSERT(script);
53 179 : }
54 :
55 1664 : bool hasBaselineScript() const {
56 1664 : return script->hasBaselineScript();
57 : }
58 :
59 278 : BaselineScript* baselineScript() const {
60 278 : return script->baselineScript();
61 : }
62 :
63 : private:
64 : #ifdef DEBUG
65 302 : bool isValidPC(jsbytecode* pc) {
66 302 : return script->containsPC(pc);
67 : }
68 : #endif
69 :
70 274 : BaselineICEntry& icEntryFromPC(jsbytecode* pc) {
71 274 : MOZ_ASSERT(hasBaselineScript());
72 274 : MOZ_ASSERT(isValidPC(pc));
73 : BaselineICEntry& ent =
74 274 : baselineScript()->icEntryFromPCOffset(script->pcToOffset(pc), prevLookedUpEntry);
75 274 : MOZ_ASSERT(ent.isForOp());
76 274 : prevLookedUpEntry = &ent;
77 274 : return ent;
78 : }
79 :
80 : template <typename ICInspectorType>
81 0 : ICInspectorType makeICInspector(jsbytecode* pc, ICStub::Kind expectedFallbackKind) {
82 0 : BaselineICEntry* ent = nullptr;
83 0 : if (hasBaselineScript()) {
84 0 : ent = &icEntryFromPC(pc);
85 0 : MOZ_ASSERT(ent->fallbackStub()->kind() == expectedFallbackKind);
86 : }
87 0 : return ICInspectorType(this, pc, ent);
88 : }
89 :
90 : ICStub* monomorphicStub(jsbytecode* pc);
91 : MOZ_MUST_USE bool dimorphicStub(jsbytecode* pc, ICStub** pfirst, ICStub** psecond);
92 :
93 : public:
94 : typedef Vector<ReceiverGuard, 4, JitAllocPolicy> ReceiverVector;
95 : typedef Vector<ObjectGroup*, 4, JitAllocPolicy> ObjectGroupVector;
96 : MOZ_MUST_USE bool maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers,
97 : ObjectGroupVector& convertUnboxedGroups);
98 :
99 0 : SetElemICInspector setElemICInspector(jsbytecode* pc) {
100 0 : return makeICInspector<SetElemICInspector>(pc, ICStub::SetElem_Fallback);
101 : }
102 :
103 : MIRType expectedResultType(jsbytecode* pc);
104 : MCompare::CompareType expectedCompareType(jsbytecode* pc);
105 : MIRType expectedBinaryArithSpecialization(jsbytecode* pc);
106 : MIRType expectedPropertyAccessInputType(jsbytecode* pc);
107 :
108 : bool hasSeenNegativeIndexGetElement(jsbytecode* pc);
109 : bool hasSeenAccessedGetter(jsbytecode* pc);
110 : bool hasSeenDoubleResult(jsbytecode* pc);
111 : bool hasSeenNonStringIterMore(jsbytecode* pc);
112 :
113 : MOZ_MUST_USE bool isOptimizableConstStringSplit(jsbytecode* pc, JSString** strOut,
114 : JSString** sepOut, JSObject** objOut);
115 : JSObject* getTemplateObject(jsbytecode* pc);
116 : JSObject* getTemplateObjectForNative(jsbytecode* pc, Native native);
117 : JSObject* getTemplateObjectForClassHook(jsbytecode* pc, const Class* clasp);
118 : JSObject* getTemplateObjectForSimdCtor(jsbytecode* pc, SimdType simdType);
119 :
120 : // Sometimes the group a template object will have is known, even if the
121 : // object itself isn't.
122 : ObjectGroup* getTemplateObjectGroup(jsbytecode* pc);
123 :
124 : JSFunction* getSingleCallee(jsbytecode* pc);
125 :
126 : LexicalEnvironmentObject* templateNamedLambdaObject();
127 : CallObject* templateCallObject();
128 :
129 : // If |innerized| is true, we're doing a GETPROP on a WindowProxy and
130 : // IonBuilder unwrapped/innerized it to do the lookup on the Window (the
131 : // global object) instead. In this case we should only look for Baseline
132 : // stubs that performed the same optimization.
133 : MOZ_MUST_USE bool commonGetPropFunction(jsbytecode* pc, bool innerized,
134 : JSObject** holder, Shape** holderShape,
135 : JSFunction** commonGetter, Shape** globalShape,
136 : bool* isOwnProperty, ReceiverVector& receivers,
137 : ObjectGroupVector& convertUnboxedGroups);
138 :
139 : MOZ_MUST_USE bool megamorphicGetterSetterFunction(jsbytecode* pc, bool isGetter,
140 : JSFunction** getterOrSetter);
141 :
142 : MOZ_MUST_USE bool commonSetPropFunction(jsbytecode* pc, JSObject** holder, Shape** holderShape,
143 : JSFunction** commonSetter, bool* isOwnProperty,
144 : ReceiverVector& receivers,
145 : ObjectGroupVector& convertUnboxedGroups);
146 :
147 : MOZ_MUST_USE bool instanceOfData(jsbytecode* pc, Shape** shape, uint32_t* slot,
148 : JSObject** prototypeObject);
149 : };
150 :
151 : } // namespace jit
152 : } // namespace js
153 :
154 : #endif /* jit_BaselineInspector_h */
|