js/src/jit/BaselineFrameInfo.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     7 #include "jit/BaselineFrameInfo.h"
     9 #ifdef DEBUG
    10 # include "jit/BytecodeAnalysis.h"
    11 #endif
    13 using namespace js;
    14 using namespace js::jit;
    16 bool
    17 FrameInfo::init(TempAllocator &alloc)
    18 {
    19     // One slot is always needed for this/arguments type checks.
    20     size_t nstack = Max(script->nslots() - script->nfixed(), size_t(1));
    21     if (!stack.init(alloc, nstack))
    22         return false;
    24     return true;
    25 }
    27 void
    28 FrameInfo::sync(StackValue *val)
    29 {
    30     switch (val->kind()) {
    31       case StackValue::Stack:
    32         break;
    33       case StackValue::LocalSlot:
    34         masm.pushValue(addressOfLocal(val->localSlot()));
    35         break;
    36       case StackValue::ArgSlot:
    37         masm.pushValue(addressOfArg(val->argSlot()));
    38         break;
    39       case StackValue::ThisSlot:
    40         masm.pushValue(addressOfThis());
    41         break;
    42       case StackValue::Register:
    43         masm.pushValue(val->reg());
    44         break;
    45       case StackValue::Constant:
    46         masm.pushValue(val->constant());
    47         break;
    48       default:
    49         MOZ_ASSUME_UNREACHABLE("Invalid kind");
    50     }
    52     val->setStack();
    53 }
    55 void
    56 FrameInfo::syncStack(uint32_t uses)
    57 {
    58     JS_ASSERT(uses <= stackDepth());
    60     uint32_t depth = stackDepth() - uses;
    62     for (uint32_t i = 0; i < depth; i++) {
    63         StackValue *current = &stack[i];
    64         sync(current);
    65     }
    66 }
    68 uint32_t
    69 FrameInfo::numUnsyncedSlots()
    70 {
    71     // Start at the bottom, find the first value that's not synced.
    72     uint32_t i = 0;
    73     for (; i < stackDepth(); i++) {
    74         if (peek(-int32_t(i + 1))->kind() == StackValue::Stack)
    75             break;
    76     }
    77     return i;
    78 }
    80 void
    81 FrameInfo::popValue(ValueOperand dest)
    82 {
    83     StackValue *val = peek(-1);
    85     switch (val->kind()) {
    86       case StackValue::Constant:
    87         masm.moveValue(val->constant(), dest);
    88         break;
    89       case StackValue::LocalSlot:
    90         masm.loadValue(addressOfLocal(val->localSlot()), dest);
    91         break;
    92       case StackValue::ArgSlot:
    93         masm.loadValue(addressOfArg(val->argSlot()), dest);
    94         break;
    95       case StackValue::ThisSlot:
    96         masm.loadValue(addressOfThis(), dest);
    97         break;
    98       case StackValue::Stack:
    99         masm.popValue(dest);
   100         break;
   101       case StackValue::Register:
   102         masm.moveValue(val->reg(), dest);
   103         break;
   104       default:
   105         MOZ_ASSUME_UNREACHABLE("Invalid kind");
   106     }
   108     // masm.popValue already adjusted the stack pointer, don't do it twice.
   109     pop(DontAdjustStack);
   110 }
   112 void
   113 FrameInfo::popRegsAndSync(uint32_t uses)
   114 {
   115     // x86 has only 3 Value registers. Only support 2 regs here for now,
   116     // so that there's always a scratch Value register for reg -> reg
   117     // moves.
   118     JS_ASSERT(uses > 0);
   119     JS_ASSERT(uses <= 2);
   120     JS_ASSERT(uses <= stackDepth());
   122     syncStack(uses);
   124     switch (uses) {
   125       case 1:
   126         popValue(R0);
   127         break;
   128       case 2: {
   129         // If the second value is in R1, move it to R2 so that it's not
   130         // clobbered by the first popValue.
   131         StackValue *val = peek(-2);
   132         if (val->kind() == StackValue::Register && val->reg() == R1) {
   133             masm.moveValue(R1, R2);
   134             val->setRegister(R2);
   135         }
   136         popValue(R1);
   137         popValue(R0);
   138         break;
   139       }
   140       default:
   141         MOZ_ASSUME_UNREACHABLE("Invalid uses");
   142     }
   143 }
   145 #ifdef DEBUG
   146 void
   147 FrameInfo::assertValidState(const BytecodeInfo &info)
   148 {
   149     // Check stack depth.
   150     JS_ASSERT(stackDepth() == info.stackDepth);
   152     // Start at the bottom, find the first value that's not synced.
   153     uint32_t i = 0;
   154     for (; i < stackDepth(); i++) {
   155         if (stack[i].kind() != StackValue::Stack)
   156             break;
   157     }
   159     // Assert all values on top of it are also not synced.
   160     for (; i < stackDepth(); i++)
   161         JS_ASSERT(stack[i].kind() != StackValue::Stack);
   163     // Assert every Value register is used by at most one StackValue.
   164     // R2 is used as scratch register by the compiler and FrameInfo,
   165     // so it shouldn't be used for StackValues.
   166     bool usedR0 = false, usedR1 = false;
   168     for (i = 0; i < stackDepth(); i++) {
   169         if (stack[i].kind() == StackValue::Register) {
   170             ValueOperand reg = stack[i].reg();
   171             if (reg == R0) {
   172                 JS_ASSERT(!usedR0);
   173                 usedR0 = true;
   174             } else if (reg == R1) {
   175                 JS_ASSERT(!usedR1);
   176                 usedR1 = true;
   177             } else {
   178                 MOZ_ASSUME_UNREACHABLE("Invalid register");
   179             }
   180         }
   181     }
   182 }
   183 #endif

mercurial