LCOV - app.info - js/src/methodjit/ImmutableSync.cpp

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