Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
michael@0 | 2 | * vim: set ts=8 sts=4 et sw=4 tw=99: |
michael@0 | 3 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #ifndef jit_arm_CodeGenerator_arm_h |
michael@0 | 8 | #define jit_arm_CodeGenerator_arm_h |
michael@0 | 9 | |
michael@0 | 10 | #include "jit/arm/Assembler-arm.h" |
michael@0 | 11 | #include "jit/shared/CodeGenerator-shared.h" |
michael@0 | 12 | |
michael@0 | 13 | namespace js { |
michael@0 | 14 | namespace jit { |
michael@0 | 15 | |
michael@0 | 16 | class OutOfLineBailout; |
michael@0 | 17 | class OutOfLineTableSwitch; |
michael@0 | 18 | |
michael@0 | 19 | class CodeGeneratorARM : public CodeGeneratorShared |
michael@0 | 20 | { |
michael@0 | 21 | friend class MoveResolverARM; |
michael@0 | 22 | |
michael@0 | 23 | CodeGeneratorARM *thisFromCtor() {return this;} |
michael@0 | 24 | |
michael@0 | 25 | protected: |
michael@0 | 26 | // Label for the common return path. |
michael@0 | 27 | NonAssertingLabel returnLabel_; |
michael@0 | 28 | NonAssertingLabel deoptLabel_; |
michael@0 | 29 | // ugh. this is not going to be pretty to move over. |
michael@0 | 30 | // stack slotted variables are not useful on arm. |
michael@0 | 31 | // it looks like this will need to return one of two types. |
michael@0 | 32 | inline Operand ToOperand(const LAllocation &a) { |
michael@0 | 33 | if (a.isGeneralReg()) |
michael@0 | 34 | return Operand(a.toGeneralReg()->reg()); |
michael@0 | 35 | if (a.isFloatReg()) |
michael@0 | 36 | return Operand(a.toFloatReg()->reg()); |
michael@0 | 37 | return Operand(StackPointer, ToStackOffset(&a)); |
michael@0 | 38 | } |
michael@0 | 39 | inline Operand ToOperand(const LAllocation *a) { |
michael@0 | 40 | return ToOperand(*a); |
michael@0 | 41 | } |
michael@0 | 42 | inline Operand ToOperand(const LDefinition *def) { |
michael@0 | 43 | return ToOperand(def->output()); |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | MoveOperand toMoveOperand(const LAllocation *a) const; |
michael@0 | 47 | |
michael@0 | 48 | bool bailoutIf(Assembler::Condition condition, LSnapshot *snapshot); |
michael@0 | 49 | bool bailoutFrom(Label *label, LSnapshot *snapshot); |
michael@0 | 50 | bool bailout(LSnapshot *snapshot); |
michael@0 | 51 | |
michael@0 | 52 | template <typename T1, typename T2> |
michael@0 | 53 | bool bailoutCmpPtr(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) { |
michael@0 | 54 | masm.cmpPtr(lhs, rhs); |
michael@0 | 55 | return bailoutIf(c, snapshot); |
michael@0 | 56 | } |
michael@0 | 57 | bool bailoutTestPtr(Assembler::Condition c, Register lhs, Register rhs, LSnapshot *snapshot) { |
michael@0 | 58 | masm.testPtr(lhs, rhs); |
michael@0 | 59 | return bailoutIf(c, snapshot); |
michael@0 | 60 | } |
michael@0 | 61 | template <typename T1, typename T2> |
michael@0 | 62 | bool bailoutCmp32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) { |
michael@0 | 63 | masm.cmp32(lhs, rhs); |
michael@0 | 64 | return bailoutIf(c, snapshot); |
michael@0 | 65 | } |
michael@0 | 66 | template <typename T1, typename T2> |
michael@0 | 67 | bool bailoutTest32(Assembler::Condition c, T1 lhs, T2 rhs, LSnapshot *snapshot) { |
michael@0 | 68 | masm.test32(lhs, rhs); |
michael@0 | 69 | return bailoutIf(c, snapshot); |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | protected: |
michael@0 | 73 | bool generatePrologue(); |
michael@0 | 74 | bool generateAsmJSPrologue(Label *stackOverflowLabel); |
michael@0 | 75 | bool generateEpilogue(); |
michael@0 | 76 | bool generateOutOfLineCode(); |
michael@0 | 77 | |
michael@0 | 78 | void emitRoundDouble(const FloatRegister &src, const Register &dest, Label *fail); |
michael@0 | 79 | |
michael@0 | 80 | // Emits a branch that directs control flow to the true block if |cond| is |
michael@0 | 81 | // true, and the false block if |cond| is false. |
michael@0 | 82 | void emitBranch(Assembler::Condition cond, MBasicBlock *ifTrue, MBasicBlock *ifFalse); |
michael@0 | 83 | |
michael@0 | 84 | void testNullEmitBranch(Assembler::Condition cond, const ValueOperand &value, |
michael@0 | 85 | MBasicBlock *ifTrue, MBasicBlock *ifFalse) |
michael@0 | 86 | { |
michael@0 | 87 | cond = masm.testNull(cond, value); |
michael@0 | 88 | emitBranch(cond, ifTrue, ifFalse); |
michael@0 | 89 | } |
michael@0 | 90 | void testUndefinedEmitBranch(Assembler::Condition cond, const ValueOperand &value, |
michael@0 | 91 | MBasicBlock *ifTrue, MBasicBlock *ifFalse) |
michael@0 | 92 | { |
michael@0 | 93 | cond = masm.testUndefined(cond, value); |
michael@0 | 94 | emitBranch(cond, ifTrue, ifFalse); |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | bool emitTableSwitchDispatch(MTableSwitch *mir, const Register &index, const Register &base); |
michael@0 | 98 | |
michael@0 | 99 | public: |
michael@0 | 100 | // Instruction visitors. |
michael@0 | 101 | virtual bool visitMinMaxD(LMinMaxD *ins); |
michael@0 | 102 | virtual bool visitAbsD(LAbsD *ins); |
michael@0 | 103 | virtual bool visitAbsF(LAbsF *ins); |
michael@0 | 104 | virtual bool visitSqrtD(LSqrtD *ins); |
michael@0 | 105 | virtual bool visitSqrtF(LSqrtF *ins); |
michael@0 | 106 | virtual bool visitAddI(LAddI *ins); |
michael@0 | 107 | virtual bool visitSubI(LSubI *ins); |
michael@0 | 108 | virtual bool visitBitNotI(LBitNotI *ins); |
michael@0 | 109 | virtual bool visitBitOpI(LBitOpI *ins); |
michael@0 | 110 | |
michael@0 | 111 | virtual bool visitMulI(LMulI *ins); |
michael@0 | 112 | |
michael@0 | 113 | virtual bool visitDivI(LDivI *ins); |
michael@0 | 114 | virtual bool visitSoftDivI(LSoftDivI *ins); |
michael@0 | 115 | virtual bool visitDivPowTwoI(LDivPowTwoI *ins); |
michael@0 | 116 | virtual bool visitModI(LModI *ins); |
michael@0 | 117 | virtual bool visitSoftModI(LSoftModI *ins); |
michael@0 | 118 | virtual bool visitModPowTwoI(LModPowTwoI *ins); |
michael@0 | 119 | virtual bool visitModMaskI(LModMaskI *ins); |
michael@0 | 120 | virtual bool visitPowHalfD(LPowHalfD *ins); |
michael@0 | 121 | virtual bool visitShiftI(LShiftI *ins); |
michael@0 | 122 | virtual bool visitUrshD(LUrshD *ins); |
michael@0 | 123 | |
michael@0 | 124 | virtual bool visitTestIAndBranch(LTestIAndBranch *test); |
michael@0 | 125 | virtual bool visitCompare(LCompare *comp); |
michael@0 | 126 | virtual bool visitCompareAndBranch(LCompareAndBranch *comp); |
michael@0 | 127 | virtual bool visitTestDAndBranch(LTestDAndBranch *test); |
michael@0 | 128 | virtual bool visitTestFAndBranch(LTestFAndBranch *test); |
michael@0 | 129 | virtual bool visitCompareD(LCompareD *comp); |
michael@0 | 130 | virtual bool visitCompareF(LCompareF *comp); |
michael@0 | 131 | virtual bool visitCompareDAndBranch(LCompareDAndBranch *comp); |
michael@0 | 132 | virtual bool visitCompareFAndBranch(LCompareFAndBranch *comp); |
michael@0 | 133 | virtual bool visitCompareB(LCompareB *lir); |
michael@0 | 134 | virtual bool visitCompareBAndBranch(LCompareBAndBranch *lir); |
michael@0 | 135 | virtual bool visitCompareV(LCompareV *lir); |
michael@0 | 136 | virtual bool visitCompareVAndBranch(LCompareVAndBranch *lir); |
michael@0 | 137 | virtual bool visitBitAndAndBranch(LBitAndAndBranch *baab); |
michael@0 | 138 | virtual bool visitAsmJSUInt32ToDouble(LAsmJSUInt32ToDouble *lir); |
michael@0 | 139 | virtual bool visitAsmJSUInt32ToFloat32(LAsmJSUInt32ToFloat32 *lir); |
michael@0 | 140 | virtual bool visitNotI(LNotI *ins); |
michael@0 | 141 | virtual bool visitNotD(LNotD *ins); |
michael@0 | 142 | virtual bool visitNotF(LNotF *ins); |
michael@0 | 143 | |
michael@0 | 144 | virtual bool visitMathD(LMathD *math); |
michael@0 | 145 | virtual bool visitMathF(LMathF *math); |
michael@0 | 146 | virtual bool visitFloor(LFloor *lir); |
michael@0 | 147 | virtual bool visitFloorF(LFloorF *lir); |
michael@0 | 148 | virtual bool visitRound(LRound *lir); |
michael@0 | 149 | virtual bool visitRoundF(LRoundF *lir); |
michael@0 | 150 | virtual bool visitTruncateDToInt32(LTruncateDToInt32 *ins); |
michael@0 | 151 | virtual bool visitTruncateFToInt32(LTruncateFToInt32 *ins); |
michael@0 | 152 | |
michael@0 | 153 | // Out of line visitors. |
michael@0 | 154 | bool visitOutOfLineBailout(OutOfLineBailout *ool); |
michael@0 | 155 | bool visitOutOfLineTableSwitch(OutOfLineTableSwitch *ool); |
michael@0 | 156 | |
michael@0 | 157 | protected: |
michael@0 | 158 | ValueOperand ToValue(LInstruction *ins, size_t pos); |
michael@0 | 159 | ValueOperand ToOutValue(LInstruction *ins); |
michael@0 | 160 | ValueOperand ToTempValue(LInstruction *ins, size_t pos); |
michael@0 | 161 | |
michael@0 | 162 | // Functions for LTestVAndBranch. |
michael@0 | 163 | Register splitTagForTest(const ValueOperand &value); |
michael@0 | 164 | |
michael@0 | 165 | void storeElementTyped(const LAllocation *value, MIRType valueType, MIRType elementType, |
michael@0 | 166 | const Register &elements, const LAllocation *index); |
michael@0 | 167 | |
michael@0 | 168 | bool divICommon(MDiv *mir, Register lhs, Register rhs, Register output, LSnapshot *snapshot, |
michael@0 | 169 | Label &done); |
michael@0 | 170 | bool modICommon(MMod *mir, Register lhs, Register rhs, Register output, LSnapshot *snapshot, |
michael@0 | 171 | Label &done); |
michael@0 | 172 | |
michael@0 | 173 | public: |
michael@0 | 174 | CodeGeneratorARM(MIRGenerator *gen, LIRGraph *graph, MacroAssembler *masm); |
michael@0 | 175 | |
michael@0 | 176 | public: |
michael@0 | 177 | bool visitBox(LBox *box); |
michael@0 | 178 | bool visitBoxFloatingPoint(LBoxFloatingPoint *box); |
michael@0 | 179 | bool visitUnbox(LUnbox *unbox); |
michael@0 | 180 | bool visitValue(LValue *value); |
michael@0 | 181 | bool visitDouble(LDouble *ins); |
michael@0 | 182 | bool visitFloat32(LFloat32 *ins); |
michael@0 | 183 | |
michael@0 | 184 | bool visitLoadSlotV(LLoadSlotV *load); |
michael@0 | 185 | bool visitLoadSlotT(LLoadSlotT *load); |
michael@0 | 186 | bool visitStoreSlotT(LStoreSlotT *load); |
michael@0 | 187 | |
michael@0 | 188 | bool visitLoadElementT(LLoadElementT *load); |
michael@0 | 189 | |
michael@0 | 190 | bool visitGuardShape(LGuardShape *guard); |
michael@0 | 191 | bool visitGuardObjectType(LGuardObjectType *guard); |
michael@0 | 192 | bool visitGuardClass(LGuardClass *guard); |
michael@0 | 193 | bool visitImplicitThis(LImplicitThis *lir); |
michael@0 | 194 | |
michael@0 | 195 | bool visitInterruptCheck(LInterruptCheck *lir); |
michael@0 | 196 | |
michael@0 | 197 | bool visitNegI(LNegI *lir); |
michael@0 | 198 | bool visitNegD(LNegD *lir); |
michael@0 | 199 | bool visitNegF(LNegF *lir); |
michael@0 | 200 | bool visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic *ins); |
michael@0 | 201 | bool visitStoreTypedArrayElementStatic(LStoreTypedArrayElementStatic *ins); |
michael@0 | 202 | bool visitAsmJSLoadHeap(LAsmJSLoadHeap *ins); |
michael@0 | 203 | bool visitAsmJSStoreHeap(LAsmJSStoreHeap *ins); |
michael@0 | 204 | bool visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar *ins); |
michael@0 | 205 | bool visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar *ins); |
michael@0 | 206 | bool visitAsmJSLoadFuncPtr(LAsmJSLoadFuncPtr *ins); |
michael@0 | 207 | bool visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc *ins); |
michael@0 | 208 | bool visitAsmJSPassStackArg(LAsmJSPassStackArg *ins); |
michael@0 | 209 | |
michael@0 | 210 | bool visitForkJoinGetSlice(LForkJoinGetSlice *ins); |
michael@0 | 211 | |
michael@0 | 212 | bool generateInvalidateEpilogue(); |
michael@0 | 213 | protected: |
michael@0 | 214 | void postAsmJSCall(LAsmJSCall *lir) { |
michael@0 | 215 | if (!useHardFpABI() && lir->mir()->callee().which() == MAsmJSCall::Callee::Builtin) { |
michael@0 | 216 | switch (lir->mir()->type()) { |
michael@0 | 217 | case MIRType_Double: |
michael@0 | 218 | masm.ma_vxfer(r0, r1, d0); |
michael@0 | 219 | break; |
michael@0 | 220 | case MIRType_Float32: |
michael@0 | 221 | masm.as_vxfer(r0, InvalidReg, VFPRegister(d0).singleOverlay(), |
michael@0 | 222 | Assembler::CoreToFloat); |
michael@0 | 223 | break; |
michael@0 | 224 | default: |
michael@0 | 225 | break; |
michael@0 | 226 | } |
michael@0 | 227 | } |
michael@0 | 228 | } |
michael@0 | 229 | |
michael@0 | 230 | bool visitEffectiveAddress(LEffectiveAddress *ins); |
michael@0 | 231 | bool visitUDiv(LUDiv *ins); |
michael@0 | 232 | bool visitUMod(LUMod *ins); |
michael@0 | 233 | bool visitSoftUDivOrMod(LSoftUDivOrMod *ins); |
michael@0 | 234 | }; |
michael@0 | 235 | |
michael@0 | 236 | typedef CodeGeneratorARM CodeGeneratorSpecific; |
michael@0 | 237 | |
michael@0 | 238 | // An out-of-line bailout thunk. |
michael@0 | 239 | class OutOfLineBailout : public OutOfLineCodeBase<CodeGeneratorARM> |
michael@0 | 240 | { |
michael@0 | 241 | protected: // Silence Clang warning. |
michael@0 | 242 | LSnapshot *snapshot_; |
michael@0 | 243 | uint32_t frameSize_; |
michael@0 | 244 | |
michael@0 | 245 | public: |
michael@0 | 246 | OutOfLineBailout(LSnapshot *snapshot, uint32_t frameSize) |
michael@0 | 247 | : snapshot_(snapshot), |
michael@0 | 248 | frameSize_(frameSize) |
michael@0 | 249 | { } |
michael@0 | 250 | |
michael@0 | 251 | bool accept(CodeGeneratorARM *codegen); |
michael@0 | 252 | |
michael@0 | 253 | LSnapshot *snapshot() const { |
michael@0 | 254 | return snapshot_; |
michael@0 | 255 | } |
michael@0 | 256 | }; |
michael@0 | 257 | |
michael@0 | 258 | } // namespace jit |
michael@0 | 259 | } // namespace js |
michael@0 | 260 | |
michael@0 | 261 | #endif /* jit_arm_CodeGenerator_arm_h */ |