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.

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

mercurial