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 #ifndef jit_BaselineCacheIRCompiler_h
8 #define jit_BaselineCacheIRCompiler_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/Maybe.h"
18 #include "jit/CacheIR.h"
19 #include "jit/CacheIRCompiler.h"
20 #include "jit/CacheIROpsGenerated.h"
21 #include "jit/CacheIRReader.h"
23 struct JS_PUBLIC_API JSContext
;
40 enum class ICAttachResult
{ Attached
, DuplicateStub
, TooLarge
, OOM
};
42 bool TryFoldingStubs(JSContext
* cx
, ICFallbackStub
* fallback
, JSScript
* script
,
45 ICAttachResult
AttachBaselineCacheIRStub(JSContext
* cx
,
46 const CacheIRWriter
& writer
,
47 CacheKind kind
, JSScript
* outerScript
,
52 // BaselineCacheIRCompiler compiles CacheIR to BaselineIC native code.
53 class MOZ_RAII BaselineCacheIRCompiler
: public CacheIRCompiler
{
55 uint8_t localTracingSlots_
= 0;
56 Register baselineFrameReg_
= FramePointer
;
58 // This register points to the baseline frame of the caller. It should only
59 // be used before we enter a stub frame. This is normally the frame pointer
60 // register, but with --enable-ic-frame-pointers we have to allocate a
62 inline Register
baselineFrameReg() {
63 MOZ_ASSERT(!enteredStubFrame_
);
64 return baselineFrameReg_
;
67 [[nodiscard
]] bool emitStoreSlotShared(bool isFixed
, ObjOperandId objId
,
68 uint32_t offsetOffset
,
70 [[nodiscard
]] bool emitAddAndStoreSlotShared(
71 CacheOp op
, ObjOperandId objId
, uint32_t offsetOffset
, ValOperandId rhsId
,
72 uint32_t newShapeOffset
, mozilla::Maybe
<uint32_t> numNewSlotsOffset
);
74 bool updateArgc(CallFlags flags
, Register argcReg
, Register scratch
);
75 void loadStackObject(ArgumentKind kind
, CallFlags flags
, Register argcReg
,
77 void pushArguments(Register argcReg
, Register calleeReg
, Register scratch
,
78 Register scratch2
, CallFlags flags
, uint32_t argcFixed
,
80 void pushStandardArguments(Register argcReg
, Register scratch
,
81 Register scratch2
, uint32_t argcFixed
,
82 bool isJitCall
, bool isConstructing
);
83 void pushArrayArguments(Register argcReg
, Register scratch
, Register scratch2
,
84 bool isJitCall
, bool isConstructing
);
85 void pushFunCallArguments(Register argcReg
, Register calleeReg
,
86 Register scratch
, Register scratch2
,
87 uint32_t argcFixed
, bool isJitCall
);
88 void pushFunApplyArgsObj(Register argcReg
, Register calleeReg
,
89 Register scratch
, Register scratch2
, bool isJitCall
);
90 void pushFunApplyNullUndefinedArguments(Register calleeReg
, bool isJitCall
);
91 void pushBoundFunctionArguments(Register argcReg
, Register calleeReg
,
92 Register scratch
, Register scratch2
,
93 CallFlags flags
, uint32_t numBoundArgs
,
95 void createThis(Register argcReg
, Register calleeReg
, Register scratch
,
96 CallFlags flags
, bool isBoundFunction
);
98 void storeThis(const T
& newThis
, Register argcReg
, CallFlags flags
);
99 void updateReturnValue();
101 enum class NativeCallType
{ Native
, ClassHook
};
102 bool emitCallNativeShared(NativeCallType callType
, ObjOperandId calleeId
,
103 Int32OperandId argcId
, CallFlags flags
,
105 mozilla::Maybe
<bool> ignoresReturnValue
,
106 mozilla::Maybe
<uint32_t> targetOffset
);
108 enum class StringCode
{ CodeUnit
, CodePoint
};
109 bool emitStringFromCodeResult(Int32OperandId codeId
, StringCode stringCode
);
111 enum class StringCharOutOfBounds
{ Failure
, EmptyString
, UndefinedValue
};
112 bool emitLoadStringCharResult(StringOperandId strId
, Int32OperandId indexId
,
113 StringCharOutOfBounds outOfBounds
);
115 void emitAtomizeString(Register str
, Register temp
, Label
* failure
);
117 bool emitCallScriptedGetterShared(ValOperandId receiverId
,
118 uint32_t getterOffset
, bool sameRealm
,
119 uint32_t nargsAndFlagsOffset
,
120 mozilla::Maybe
<uint32_t> icScriptOffset
);
121 bool emitCallScriptedSetterShared(ObjOperandId receiverId
,
122 uint32_t setterOffset
, ValOperandId rhsId
,
124 uint32_t nargsAndFlagsOffset
,
125 mozilla::Maybe
<uint32_t> icScriptOffset
);
127 template <typename IdType
>
128 bool emitCallScriptedProxyGetShared(ValOperandId targetId
,
129 ObjOperandId receiverId
,
130 ObjOperandId handlerId
,
131 uint32_t trapOffset
, IdType id
,
132 uint32_t nargsAndFlags
);
134 BaselineICPerfSpewer perfSpewer_
;
137 BaselineICPerfSpewer
& perfSpewer() { return perfSpewer_
; }
139 friend class AutoStubFrame
;
141 BaselineCacheIRCompiler(JSContext
* cx
, TempAllocator
& alloc
,
142 const CacheIRWriter
& writer
, uint32_t stubDataOffset
);
144 [[nodiscard
]] bool init(CacheKind kind
);
146 template <typename Fn
, Fn fn
>
147 void callVM(MacroAssembler
& masm
);
151 bool makesGCCalls() const;
152 bool localTracingSlots() const { return localTracingSlots_
; }
154 Address
stubAddress(uint32_t offset
) const;
157 CACHE_IR_COMPILER_UNSHARED_GENERATED
160 // Special object used for storing a list of shapes to guard against. These are
161 // only used in the fields of CacheIR stubs and do not escape.
162 class ShapeListObject
: public ListObject
{
164 static const JSClass class_
;
165 static const JSClassOps classOps_
;
166 static ShapeListObject
* create(JSContext
* cx
);
167 static void trace(JSTracer
* trc
, JSObject
* obj
);
169 Shape
* get(uint32_t index
);
170 bool traceWeak(JSTracer
* trc
);
176 #endif /* jit_BaselineCacheIRCompiler_h */