LCOV - code coverage report
Current view: directory - js/src/methodjit - ImmutableSync.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 147 146 99.3 %
Date: 2012-04-07 Functions: 15 15 100.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2                 :  * vim: set ts=4 sw=4 et tw=99:
       3                 :  *
       4                 :  * ***** BEGIN LICENSE BLOCK *****
       5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       6                 :  *
       7                 :  * The contents of this file are subject to the Mozilla Public License Version
       8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       9                 :  * the License. You may obtain a copy of the License at
      10                 :  * http://www.mozilla.org/MPL/
      11                 :  *
      12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      14                 :  * for the specific language governing rights and limitations under the
      15                 :  * License.
      16                 :  *
      17                 :  * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
      18                 :  * May 28, 2008.
      19                 :  *
      20                 :  * The Initial Developer of the Original Code is
      21                 :  *   Brendan Eich <brendan@mozilla.org>
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   David Anderson <danderson@mozilla.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #if defined JS_NUNBOX32
      41                 : 
      42                 : #include "FrameEntry.h"
      43                 : #include "FrameState.h"
      44                 : #include "FrameState-inl.h"
      45                 : #include "ImmutableSync.h"
      46                 : 
      47                 : using namespace js;
      48                 : using namespace js::mjit;
      49                 : 
      50           95862 : ImmutableSync::ImmutableSync()
      51           95862 :   : cx(NULL), entries(NULL), frame(NULL), avail(Registers::AvailRegs), generation(0)
      52                 : {
      53           95862 : }
      54                 : 
      55           95862 : ImmutableSync::~ImmutableSync()
      56                 : {
      57           95862 :     if (cx)
      58           93731 :         cx->free_(entries);
      59           95862 : }
      60                 : 
      61                 : bool
      62           93731 : ImmutableSync::init(JSContext *cx, const FrameState &frame, uint32_t nentries)
      63                 : {
      64           93731 :     this->cx = cx;
      65           93731 :     this->frame = &frame;
      66                 : 
      67           93731 :     entries = (SyncEntry *)OffTheBooks::calloc_(sizeof(SyncEntry) * nentries);
      68           93731 :     return !!entries;
      69                 : }
      70                 : 
      71                 : void
      72           75565 : ImmutableSync::reset(Assembler *masm, Registers avail, FrameEntry *top, FrameEntry *bottom)
      73                 : {
      74           75565 :     this->avail = avail;
      75           75565 :     this->masm = masm;
      76           75565 :     this->top = top;
      77           75565 :     this->bottom = bottom;
      78           75565 :     this->generation++;
      79           75565 :     memset(regs, 0, sizeof(regs));
      80           75565 : }
      81                 : 
      82                 : inline JSC::MacroAssembler::RegisterID
      83          133392 : ImmutableSync::doAllocReg()
      84                 : {
      85          133392 :     if (!avail.empty())
      86          108228 :         return avail.takeAnyReg().reg();
      87                 : 
      88           25164 :     uint32_t lastResort = FrameState::InvalidIndex;
      89           25164 :     uint32_t evictFromFrame = FrameState::InvalidIndex;
      90                 : 
      91                 :     /* Find something to evict. */
      92           64247 :     for (uint32_t i = 0; i < Registers::TotalRegisters; i++) {
      93           62147 :         RegisterID reg = RegisterID(i);
      94           62147 :         if (!(Registers::maskReg(reg) & Registers::AvailRegs))
      95            5442 :             continue;
      96                 : 
      97           56705 :         if (frame->regstate(reg).isPinned())
      98            2305 :             continue;
      99                 : 
     100           54400 :         lastResort = i;
     101                 : 
     102           54400 :         if (!regs[i]) {
     103                 :             /* If the frame does not own this register, take it! */
     104           30532 :             FrameEntry *fe = frame->regstate(reg).usedBy();
     105           30532 :             if (!fe)
     106           11151 :                 return reg;
     107                 : 
     108           19381 :             evictFromFrame = i;
     109                 : 
     110                 :             /*
     111                 :              * If not copied, we can sync and not have to load again later.
     112                 :              * That's about as good as it gets, so just break out now.
     113                 :              */
     114           19381 :             if (!fe->isCopied())
     115           11913 :                 break;
     116                 :         }
     117                 :     }
     118                 : 
     119           14013 :     if (evictFromFrame != FrameState::InvalidIndex) {
     120           13416 :         RegisterID evict = RegisterID(evictFromFrame);
     121           13416 :         FrameEntry *fe = frame->regstate(evict).usedBy();
     122           13416 :         SyncEntry &e = entryFor(fe);
     123           13416 :         if (frame->regstate(evict).type() == RematInfo::TYPE) {
     124            6994 :             JS_ASSERT(!e.typeClobbered);
     125            6994 :             e.typeClobbered = true;
     126                 :         } else {
     127            6422 :             JS_ASSERT(!e.dataClobbered);
     128            6422 :             e.dataClobbered = true;
     129                 :         }
     130           13416 :         return evict;
     131                 :     }
     132                 : 
     133             597 :     JS_ASSERT(lastResort != FrameState::InvalidIndex);
     134             597 :     JS_ASSERT(regs[lastResort]);
     135                 : 
     136             597 :     SyncEntry *e = regs[lastResort];
     137             597 :     RegisterID reg = RegisterID(lastResort);
     138             597 :     if (e->hasDataReg && e->dataReg == reg) {
     139             309 :         e->hasDataReg = false;
     140             288 :     } else if (e->hasTypeReg && e->typeReg == reg) {
     141             288 :         e->hasTypeReg = false;
     142                 :     } else {
     143               0 :         JS_NOT_REACHED("no way");
     144                 :     }
     145                 : 
     146             597 :     return reg;
     147                 : }
     148                 : 
     149                 : JSC::MacroAssembler::RegisterID
     150          133392 : ImmutableSync::allocReg()
     151                 : {
     152          133392 :     RegisterID reg = doAllocReg();
     153          133392 :     JS_ASSERT(!frame->regstate(reg).isPinned());
     154          133392 :     return reg;
     155                 : }
     156                 : 
     157                 : void
     158          261872 : ImmutableSync::freeReg(JSC::MacroAssembler::RegisterID reg)
     159                 : {
     160          261872 :     if (!frame->regstate(reg).isPinned())
     161          259676 :         avail.putReg(reg);
     162          261872 : }
     163                 : 
     164                 : inline ImmutableSync::SyncEntry &
     165          438941 : ImmutableSync::entryFor(FrameEntry *fe)
     166                 : {
     167          438941 :     JS_ASSERT(fe <= top || frame->isTemporary(fe));
     168          438941 :     SyncEntry &e = entries[fe - frame->entries];
     169          438941 :     if (e.generation != generation)
     170          297349 :         e.reset(generation);
     171          438941 :     return e;
     172                 : }
     173                 : 
     174                 : void
     175          425525 : ImmutableSync::sync(FrameEntry *fe)
     176                 : {
     177          425525 :     if (fe->isCopy())
     178          128214 :         syncCopy(fe);
     179                 :     else
     180          297311 :         syncNormal(fe);
     181          425525 : }
     182                 : 
     183                 : bool
     184          246479 : ImmutableSync::shouldSyncType(FrameEntry *fe, SyncEntry &e)
     185                 : {
     186                 :     /* Registers are synced up-front. */
     187          246479 :     return !fe->type.synced() && !fe->type.inRegister();
     188                 : }
     189                 : 
     190                 : bool
     191          297311 : ImmutableSync::shouldSyncData(FrameEntry *fe, SyncEntry &e)
     192                 : {
     193                 :     /* Registers are synced up-front. */
     194          297311 :     return !fe->data.synced() && !fe->data.inRegister();
     195                 : }
     196                 : 
     197                 : JSC::MacroAssembler::RegisterID
     198           60479 : ImmutableSync::ensureTypeReg(FrameEntry *fe, SyncEntry &e)
     199                 : {
     200           60479 :     if (fe->type.inRegister() && !e.typeClobbered)
     201           24012 :         return fe->type.reg();
     202           36467 :     if (e.hasTypeReg)
     203            2272 :         return e.typeReg;
     204           34195 :     e.typeReg = allocReg();
     205           34195 :     e.hasTypeReg = true;
     206           34195 :     regs[e.typeReg] = &e;
     207           34195 :     masm->loadTypeTag(frame->addressOf(fe), e.typeReg);
     208           34195 :     return e.typeReg;
     209                 : }
     210                 : 
     211                 : JSC::MacroAssembler::RegisterID
     212          127684 : ImmutableSync::ensureDataReg(FrameEntry *fe, SyncEntry &e)
     213                 : {
     214          127684 :     if (fe->data.inRegister() && !e.dataClobbered)
     215           22528 :         return fe->data.reg();
     216          105156 :     if (e.hasDataReg)
     217            5959 :         return e.dataReg;
     218           99197 :     e.dataReg = allocReg();
     219           99197 :     e.hasDataReg = true;
     220           99197 :     regs[e.dataReg] = &e;
     221           99197 :     masm->loadPayload(frame->addressOf(fe), e.dataReg);
     222           99197 :     return e.dataReg;
     223                 : }
     224                 : 
     225                 : void
     226          128214 : ImmutableSync::syncCopy(FrameEntry *fe)
     227                 : {
     228          128214 :     JS_ASSERT(fe >= bottom);
     229                 : 
     230          128214 :     FrameEntry *backing = fe->copyOf();
     231          128214 :     SyncEntry &e = entryFor(backing);
     232                 : 
     233          128214 :     JS_ASSERT(!backing->isConstant());
     234                 : 
     235          128214 :     Address addr = frame->addressOf(fe);
     236                 : 
     237          128214 :     if (fe->isTypeKnown() && !fe->isType(JSVAL_TYPE_DOUBLE) && !e.learnedType) {
     238           62134 :         e.learnedType = true;
     239           62134 :         e.type = fe->getKnownType();
     240                 :     }
     241                 : 
     242          128214 :     if (!fe->data.synced())
     243          127405 :         masm->storePayload(ensureDataReg(backing, e), addr);
     244                 : 
     245          128214 :     if (!fe->type.synced()) {
     246          127377 :         if (e.learnedType)
     247           67177 :             masm->storeTypeTag(ImmType(e.type), addr);
     248                 :         else
     249           60200 :             masm->storeTypeTag(ensureTypeReg(backing, e), addr);
     250                 :     }
     251          128214 : }
     252                 : 
     253                 : void
     254          297311 : ImmutableSync::syncNormal(FrameEntry *fe)
     255                 : {
     256          297311 :     SyncEntry &e = entryFor(fe);
     257                 : 
     258          297311 :     Address addr = frame->addressOf(fe);
     259                 : 
     260          297311 :     if (fe->isTypeKnown() && !fe->isType(JSVAL_TYPE_DOUBLE)) {
     261          157216 :         e.learnedType = true;
     262          157216 :         e.type = fe->getKnownType();
     263                 :     }
     264                 : 
     265          297311 :     if (shouldSyncData(fe, e)) {
     266           51111 :         if (fe->isConstant()) {
     267           50832 :             masm->storeValue(fe->getValue(), addr);
     268           50832 :             return;
     269                 :         }
     270             279 :         masm->storePayload(ensureDataReg(fe, e), addr);
     271                 :     }
     272                 : 
     273          246479 :     if (shouldSyncType(fe, e)) {
     274           21194 :         if (e.learnedType)
     275           20915 :             masm->storeTypeTag(ImmType(e.type), addr);
     276                 :         else
     277             279 :             masm->storeTypeTag(ensureTypeReg(fe, e), addr);
     278                 :     }
     279                 : 
     280          246479 :     if (e.hasDataReg) {
     281           98854 :         freeReg(e.dataReg);
     282           98854 :         regs[e.dataReg] = NULL;
     283          363277 :     } else if (!e.dataClobbered &&
     284          141220 :                fe->data.inRegister() &&
     285           74432 :                frame->regstate(fe->data.reg()).usedBy()) {
     286           74432 :         freeReg(fe->data.reg());
     287                 :     }
     288                 : 
     289          246479 :     if (e.hasTypeReg) {
     290           33907 :         freeReg(e.typeReg);
     291           33907 :         regs[e.typeReg] = NULL;
     292          472980 :     } else if (!e.typeClobbered &&
     293          205729 :                fe->type.inRegister() &&
     294           54679 :                frame->regstate(fe->type.reg()).usedBy()) {
     295           54679 :         freeReg(fe->type.reg());
     296                 :     }
     297                 : }
     298                 : 
     299                 : #endif /* JS_NUNBOX32 */
     300                 : 

Generated by: LCOV version 1.7