js/src/jit/arm/Simulator-arm.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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 // Copyright 2012 the V8 project authors. All rights reserved.
michael@0 3 // Redistribution and use in source and binary forms, with or without
michael@0 4 // modification, are permitted provided that the following conditions are
michael@0 5 // met:
michael@0 6 //
michael@0 7 // * Redistributions of source code must retain the above copyright
michael@0 8 // notice, this list of conditions and the following disclaimer.
michael@0 9 // * Redistributions in binary form must reproduce the above
michael@0 10 // copyright notice, this list of conditions and the following
michael@0 11 // disclaimer in the documentation and/or other materials provided
michael@0 12 // with the distribution.
michael@0 13 // * Neither the name of Google Inc. nor the names of its
michael@0 14 // contributors may be used to endorse or promote products derived
michael@0 15 // from this software without specific prior written permission.
michael@0 16 //
michael@0 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 28
michael@0 29 #ifndef jit_arm_Simulator_arm_h
michael@0 30 #define jit_arm_Simulator_arm_h
michael@0 31
michael@0 32 #ifdef JS_ARM_SIMULATOR
michael@0 33
michael@0 34 #include "jit/arm/Architecture-arm.h"
michael@0 35 #include "jit/IonTypes.h"
michael@0 36
michael@0 37 namespace js {
michael@0 38 namespace jit {
michael@0 39
michael@0 40 class SimulatorRuntime;
michael@0 41 SimulatorRuntime *CreateSimulatorRuntime();
michael@0 42 void DestroySimulatorRuntime(SimulatorRuntime *srt);
michael@0 43
michael@0 44 // VFP rounding modes. See ARM DDI 0406B Page A2-29.
michael@0 45 enum VFPRoundingMode {
michael@0 46 SimRN = 0 << 22, // Round to Nearest.
michael@0 47 SimRP = 1 << 22, // Round towards Plus Infinity.
michael@0 48 SimRM = 2 << 22, // Round towards Minus Infinity.
michael@0 49 SimRZ = 3 << 22, // Round towards zero.
michael@0 50
michael@0 51 // Aliases.
michael@0 52 kRoundToNearest = SimRN,
michael@0 53 kRoundToPlusInf = SimRP,
michael@0 54 kRoundToMinusInf = SimRM,
michael@0 55 kRoundToZero = SimRZ
michael@0 56 };
michael@0 57
michael@0 58 const uint32_t kVFPRoundingModeMask = 3 << 22;
michael@0 59
michael@0 60 typedef int32_t Instr;
michael@0 61 class SimInstruction;
michael@0 62
michael@0 63 class Simulator
michael@0 64 {
michael@0 65 friend class Redirection;
michael@0 66
michael@0 67 public:
michael@0 68 friend class ArmDebugger;
michael@0 69 enum Register {
michael@0 70 no_reg = -1,
michael@0 71 r0 = 0, r1, r2, r3, r4, r5, r6, r7,
michael@0 72 r8, r9, r10, r11, r12, r13, r14, r15,
michael@0 73 num_registers,
michael@0 74 sp = 13,
michael@0 75 lr = 14,
michael@0 76 pc = 15,
michael@0 77 s0 = 0, s1, s2, s3, s4, s5, s6, s7,
michael@0 78 s8, s9, s10, s11, s12, s13, s14, s15,
michael@0 79 s16, s17, s18, s19, s20, s21, s22, s23,
michael@0 80 s24, s25, s26, s27, s28, s29, s30, s31,
michael@0 81 num_s_registers = 32,
michael@0 82 d0 = 0, d1, d2, d3, d4, d5, d6, d7,
michael@0 83 d8, d9, d10, d11, d12, d13, d14, d15,
michael@0 84 d16, d17, d18, d19, d20, d21, d22, d23,
michael@0 85 d24, d25, d26, d27, d28, d29, d30, d31,
michael@0 86 num_d_registers = 32,
michael@0 87 q0 = 0, q1, q2, q3, q4, q5, q6, q7,
michael@0 88 q8, q9, q10, q11, q12, q13, q14, q15,
michael@0 89 num_q_registers = 16
michael@0 90 };
michael@0 91
michael@0 92 explicit Simulator(SimulatorRuntime *srt);
michael@0 93 ~Simulator();
michael@0 94
michael@0 95 // The currently executing Simulator instance. Potentially there can be one
michael@0 96 // for each native thread.
michael@0 97 static Simulator *Current();
michael@0 98
michael@0 99 static inline uintptr_t StackLimit() {
michael@0 100 return Simulator::Current()->stackLimit();
michael@0 101 }
michael@0 102
michael@0 103 // Accessors for register state. Reading the pc value adheres to the ARM
michael@0 104 // architecture specification and is off by a 8 from the currently executing
michael@0 105 // instruction.
michael@0 106 void set_register(int reg, int32_t value);
michael@0 107 int32_t get_register(int reg) const;
michael@0 108 double get_double_from_register_pair(int reg);
michael@0 109 void set_register_pair_from_double(int reg, double* value);
michael@0 110 void set_dw_register(int dreg, const int* dbl);
michael@0 111
michael@0 112 // Support for VFP.
michael@0 113 void get_d_register(int dreg, uint64_t* value);
michael@0 114 void set_d_register(int dreg, const uint64_t* value);
michael@0 115 void get_d_register(int dreg, uint32_t* value);
michael@0 116 void set_d_register(int dreg, const uint32_t* value);
michael@0 117 void get_q_register(int qreg, uint64_t* value);
michael@0 118 void set_q_register(int qreg, const uint64_t* value);
michael@0 119 void get_q_register(int qreg, uint32_t* value);
michael@0 120 void set_q_register(int qreg, const uint32_t* value);
michael@0 121 void set_s_register(int reg, unsigned int value);
michael@0 122 unsigned int get_s_register(int reg) const;
michael@0 123
michael@0 124 void set_d_register_from_double(int dreg, const double& dbl) {
michael@0 125 setVFPRegister<double, 2>(dreg, dbl);
michael@0 126 }
michael@0 127 double get_double_from_d_register(int dreg) {
michael@0 128 return getFromVFPRegister<double, 2>(dreg);
michael@0 129 }
michael@0 130 void set_s_register_from_float(int sreg, const float flt) {
michael@0 131 setVFPRegister<float, 1>(sreg, flt);
michael@0 132 }
michael@0 133 float get_float_from_s_register(int sreg) {
michael@0 134 return getFromVFPRegister<float, 1>(sreg);
michael@0 135 }
michael@0 136 void set_s_register_from_sinteger(int sreg, const int sint) {
michael@0 137 setVFPRegister<int, 1>(sreg, sint);
michael@0 138 }
michael@0 139 int get_sinteger_from_s_register(int sreg) {
michael@0 140 return getFromVFPRegister<int, 1>(sreg);
michael@0 141 }
michael@0 142
michael@0 143 // Special case of set_register and get_register to access the raw PC value.
michael@0 144 void set_pc(int32_t value);
michael@0 145 int32_t get_pc() const;
michael@0 146
michael@0 147 void set_resume_pc(int32_t value) {
michael@0 148 resume_pc_ = value;
michael@0 149 }
michael@0 150
michael@0 151 uintptr_t stackLimit() const;
michael@0 152 bool overRecursed(uintptr_t newsp = 0) const;
michael@0 153 bool overRecursedWithExtra(uint32_t extra) const;
michael@0 154
michael@0 155 // Executes ARM instructions until the PC reaches end_sim_pc.
michael@0 156 template<bool EnableStopSimAt>
michael@0 157 void execute();
michael@0 158
michael@0 159 // Sets up the simulator state and grabs the result on return.
michael@0 160 int64_t call(uint8_t* entry, int argument_count, ...);
michael@0 161
michael@0 162 // Debugger input.
michael@0 163 void setLastDebuggerInput(char *input);
michael@0 164 char *lastDebuggerInput() { return lastDebuggerInput_; }
michael@0 165
michael@0 166 // Returns true if pc register contains one of the 'special_values' defined
michael@0 167 // below (bad_lr, end_sim_pc).
michael@0 168 bool has_bad_pc() const;
michael@0 169
michael@0 170 private:
michael@0 171 enum special_values {
michael@0 172 // Known bad pc value to ensure that the simulator does not execute
michael@0 173 // without being properly setup.
michael@0 174 bad_lr = -1,
michael@0 175 // A pc value used to signal the simulator to stop execution. Generally
michael@0 176 // the lr is set to this value on transition from native C code to
michael@0 177 // simulated execution, so that the simulator can "return" to the native
michael@0 178 // C code.
michael@0 179 end_sim_pc = -2
michael@0 180 };
michael@0 181
michael@0 182 // Checks if the current instruction should be executed based on its
michael@0 183 // condition bits.
michael@0 184 inline bool conditionallyExecute(SimInstruction* instr);
michael@0 185
michael@0 186 // Helper functions to set the conditional flags in the architecture state.
michael@0 187 void setNZFlags(int32_t val);
michael@0 188 void setCFlag(bool val);
michael@0 189 void setVFlag(bool val);
michael@0 190 bool carryFrom(int32_t left, int32_t right, int32_t carry = 0);
michael@0 191 bool borrowFrom(int32_t left, int32_t right);
michael@0 192 bool overflowFrom(int32_t alu_out, int32_t left, int32_t right, bool addition);
michael@0 193
michael@0 194 inline int getCarry() { return c_flag_ ? 1 : 0; };
michael@0 195
michael@0 196 // Support for VFP.
michael@0 197 void compute_FPSCR_Flags(double val1, double val2);
michael@0 198 void copy_FPSCR_to_APSR();
michael@0 199 inline double canonicalizeNaN(double value);
michael@0 200
michael@0 201 // Helper functions to decode common "addressing" modes
michael@0 202 int32_t getShiftRm(SimInstruction *instr, bool* carry_out);
michael@0 203 int32_t getImm(SimInstruction *instr, bool* carry_out);
michael@0 204 int32_t processPU(SimInstruction *instr, int num_regs, int operand_size,
michael@0 205 intptr_t *start_address, intptr_t *end_address);
michael@0 206 void handleRList(SimInstruction *instr, bool load);
michael@0 207 void handleVList(SimInstruction *inst);
michael@0 208 void softwareInterrupt(SimInstruction *instr);
michael@0 209
michael@0 210 // Stop helper functions.
michael@0 211 inline bool isStopInstruction(SimInstruction *instr);
michael@0 212 inline bool isWatchedStop(uint32_t bkpt_code);
michael@0 213 inline bool isEnabledStop(uint32_t bkpt_code);
michael@0 214 inline void enableStop(uint32_t bkpt_code);
michael@0 215 inline void disableStop(uint32_t bkpt_code);
michael@0 216 inline void increaseStopCounter(uint32_t bkpt_code);
michael@0 217 void printStopInfo(uint32_t code);
michael@0 218
michael@0 219 // Read and write memory.
michael@0 220 inline uint8_t readBU(int32_t addr);
michael@0 221 inline int8_t readB(int32_t addr);
michael@0 222 inline void writeB(int32_t addr, uint8_t value);
michael@0 223 inline void writeB(int32_t addr, int8_t value);
michael@0 224
michael@0 225 inline uint16_t readHU(int32_t addr, SimInstruction *instr);
michael@0 226 inline int16_t readH(int32_t addr, SimInstruction *instr);
michael@0 227 // Note: Overloaded on the sign of the value.
michael@0 228 inline void writeH(int32_t addr, uint16_t value, SimInstruction *instr);
michael@0 229 inline void writeH(int32_t addr, int16_t value, SimInstruction *instr);
michael@0 230
michael@0 231 inline int readW(int32_t addr, SimInstruction *instr);
michael@0 232 inline void writeW(int32_t addr, int value, SimInstruction *instr);
michael@0 233
michael@0 234 int32_t *readDW(int32_t addr);
michael@0 235 void writeDW(int32_t addr, int32_t value1, int32_t value2);
michael@0 236
michael@0 237 // Executing is handled based on the instruction type.
michael@0 238 // Both type 0 and type 1 rolled into one.
michael@0 239 void decodeType01(SimInstruction *instr);
michael@0 240 void decodeType2(SimInstruction *instr);
michael@0 241 void decodeType3(SimInstruction *instr);
michael@0 242 void decodeType4(SimInstruction *instr);
michael@0 243 void decodeType5(SimInstruction *instr);
michael@0 244 void decodeType6(SimInstruction *instr);
michael@0 245 void decodeType7(SimInstruction *instr);
michael@0 246
michael@0 247 // Support for VFP.
michael@0 248 void decodeTypeVFP(SimInstruction *instr);
michael@0 249 void decodeType6CoprocessorIns(SimInstruction *instr);
michael@0 250 void decodeSpecialCondition(SimInstruction *instr);
michael@0 251
michael@0 252 void decodeVMOVBetweenCoreAndSinglePrecisionRegisters(SimInstruction *instr);
michael@0 253 void decodeVCMP(SimInstruction *instr);
michael@0 254 void decodeVCVTBetweenDoubleAndSingle(SimInstruction *instr);
michael@0 255 void decodeVCVTBetweenFloatingPointAndInteger(SimInstruction *instr);
michael@0 256 void decodeVCVTBetweenFloatingPointAndIntegerFrac(SimInstruction *instr);
michael@0 257
michael@0 258 // Executes one instruction.
michael@0 259 void instructionDecode(SimInstruction *instr);
michael@0 260
michael@0 261 public:
michael@0 262 static bool ICacheCheckingEnabled;
michael@0 263 static void FlushICache(void *start, size_t size);
michael@0 264
michael@0 265 static int64_t StopSimAt;
michael@0 266
michael@0 267 // Runtime call support.
michael@0 268 static void *RedirectNativeFunction(void *nativeFunction, ABIFunctionType type);
michael@0 269
michael@0 270 private:
michael@0 271 // Handle arguments and return value for runtime FP functions.
michael@0 272 void getFpArgs(double *x, double *y, int32_t *z);
michael@0 273 void setCallResultDouble(double result);
michael@0 274 void setCallResultFloat(float result);
michael@0 275 void setCallResult(int64_t res);
michael@0 276 void scratchVolatileRegisters(bool scratchFloat = true);
michael@0 277
michael@0 278 template<class ReturnType, int register_size>
michael@0 279 ReturnType getFromVFPRegister(int reg_index);
michael@0 280
michael@0 281 template<class InputType, int register_size>
michael@0 282 void setVFPRegister(int reg_index, const InputType& value);
michael@0 283
michael@0 284 void callInternal(uint8_t* entry);
michael@0 285
michael@0 286 // Architecture state.
michael@0 287 // Saturating instructions require a Q flag to indicate saturation.
michael@0 288 // There is currently no way to read the CPSR directly, and thus read the Q
michael@0 289 // flag, so this is left unimplemented.
michael@0 290 int32_t registers_[16];
michael@0 291 bool n_flag_;
michael@0 292 bool z_flag_;
michael@0 293 bool c_flag_;
michael@0 294 bool v_flag_;
michael@0 295
michael@0 296 // VFP architecture state.
michael@0 297 uint32_t vfp_registers_[num_d_registers * 2];
michael@0 298 bool n_flag_FPSCR_;
michael@0 299 bool z_flag_FPSCR_;
michael@0 300 bool c_flag_FPSCR_;
michael@0 301 bool v_flag_FPSCR_;
michael@0 302
michael@0 303 // VFP rounding mode. See ARM DDI 0406B Page A2-29.
michael@0 304 VFPRoundingMode FPSCR_rounding_mode_;
michael@0 305 bool FPSCR_default_NaN_mode_;
michael@0 306
michael@0 307 // VFP FP exception flags architecture state.
michael@0 308 bool inv_op_vfp_flag_;
michael@0 309 bool div_zero_vfp_flag_;
michael@0 310 bool overflow_vfp_flag_;
michael@0 311 bool underflow_vfp_flag_;
michael@0 312 bool inexact_vfp_flag_;
michael@0 313
michael@0 314 // Simulator support.
michael@0 315 char *stack_;
michael@0 316 bool pc_modified_;
michael@0 317 int64_t icount_;
michael@0 318
michael@0 319 int32_t resume_pc_;
michael@0 320
michael@0 321 // Debugger input.
michael@0 322 char *lastDebuggerInput_;
michael@0 323
michael@0 324 // Registered breakpoints.
michael@0 325 SimInstruction *break_pc_;
michael@0 326 Instr break_instr_;
michael@0 327
michael@0 328 SimulatorRuntime *srt_;
michael@0 329
michael@0 330 // A stop is watched if its code is less than kNumOfWatchedStops.
michael@0 331 // Only watched stops support enabling/disabling and the counter feature.
michael@0 332 static const uint32_t kNumOfWatchedStops = 256;
michael@0 333
michael@0 334 // Breakpoint is disabled if bit 31 is set.
michael@0 335 static const uint32_t kStopDisabledBit = 1 << 31;
michael@0 336
michael@0 337 // A stop is enabled, meaning the simulator will stop when meeting the
michael@0 338 // instruction, if bit 31 of watched_stops_[code].count is unset.
michael@0 339 // The value watched_stops_[code].count & ~(1 << 31) indicates how many times
michael@0 340 // the breakpoint was hit or gone through.
michael@0 341 struct StopCountAndDesc {
michael@0 342 uint32_t count;
michael@0 343 char *desc;
michael@0 344 };
michael@0 345 StopCountAndDesc watched_stops_[kNumOfWatchedStops];
michael@0 346
michael@0 347 public:
michael@0 348 int64_t icount() {
michael@0 349 return icount_;
michael@0 350 }
michael@0 351
michael@0 352 };
michael@0 353
michael@0 354 #define JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, extra, onerror) \
michael@0 355 JS_BEGIN_MACRO \
michael@0 356 if (cx->mainThread().simulator()->overRecursedWithExtra(extra)) { \
michael@0 357 js_ReportOverRecursed(cx); \
michael@0 358 onerror; \
michael@0 359 } \
michael@0 360 JS_END_MACRO
michael@0 361
michael@0 362 } // namespace jit
michael@0 363 } // namespace js
michael@0 364
michael@0 365 #endif /* JS_ARM_SIMULATOR */
michael@0 366
michael@0 367 #endif /* jit_arm_Simulator_arm_h */

mercurial