Changeset 33327

Show
Ignore:
Timestamp:
05/12/08 23:03:29 (6 months ago)
Author:
mrowe@apple.com
Message:

2008-05-03 Geoffrey Garen <ggaren@apple.com>

Reviewed by Oliver Hunt.

A bit more efficient fix than r32832: Don't copy globals into function
register files; instead, have the RegisterFileStack track only the base
of the last *global* register file, so the global object's register
references stay good.

SunSpider reports a .3% speedup. Not sure what that's about.

Location:
branches/squirrelfish/JavaScriptCore
Files:
8 modified

Legend:

Unmodified
Added
Removed
  • branches/squirrelfish/JavaScriptCore/ChangeLog

    r33326 r33327  
     12008-05-03  Geoffrey Garen  <ggaren@apple.com> 
     2 
     3        Reviewed by Oliver Hunt. 
     4         
     5        A bit more efficient fix than r32832: Don't copy globals into function 
     6        register files; instead, have the RegisterFileStack track only the base 
     7        of the last *global* register file, so the global object's register 
     8        references stay good. 
     9         
     10        SunSpider reports a .3% speedup. Not sure what that's about. 
     11 
    1122008-05-03  Oliver Hunt  <oliver@apple.com> 
    213 
  • branches/squirrelfish/JavaScriptCore/JavaScriptCore.exp

    r33315 r33327  
    129129__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEPNS_17FunctionPrototypeEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_4ListEE 
    130130__ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFPNS_7JSValueES2_PNS_8JSObjectERKNS_4ListEE 
    131 __ZN3KJS17RegisterFileStack20allocateRegisterFileEm 
     131__ZN3KJS17RegisterFileStack20allocateRegisterFileEmPS0_ 
    132132__ZN3KJS19InternalFunctionImp11getCallDataERNS_8CallDataE 
    133133__ZN3KJS19InternalFunctionImp4infoE 
  • branches/squirrelfish/JavaScriptCore/VM/Machine.cpp

    r33326 r33327  
    556556 
    557557    RegisterFile* registerFile = registerFileStack->pushGlobalRegisterFile(); 
    558     CodeBlock* codeBlock = &programNode->code(scopeChain, !registerFileStack->inImplicitCall()); 
     558    CodeBlock* codeBlock = &programNode->code(scopeChain, registerFileStack->current()->isGlobal()); 
    559559    registerFile->addGlobalSlots(codeBlock->numVars); 
    560560 
  • branches/squirrelfish/JavaScriptCore/VM/RegisterFile.cpp

    r33304 r33327  
    9898{ 
    9999    m_base = base; 
    100     m_stack->baseChanged(this); 
     100    if (m_baseObserver) 
     101        m_baseObserver->baseChanged(this); 
    101102} 
    102103 
  • branches/squirrelfish/JavaScriptCore/VM/RegisterFile.h

    r33321 r33327  
    8888    public: 
    8989        enum { DefaultRegisterFileSize = 2 * 1024 * 1024 }; 
    90         RegisterFile(RegisterFileStack* stack, size_t maxSize) 
    91             : m_isForImplicitCall(false) 
    92             , m_size(0) 
     90        RegisterFile(size_t maxSize, RegisterFileStack* m_baseObserver) 
     91            : m_size(0) 
    9392            , m_capacity(0) 
    9493            , m_maxSize(maxSize) 
    9594            , m_base(0) 
    9695            , m_buffer(0) 
    97             , m_stack(stack) 
     96            , m_baseObserver(m_baseObserver) 
    9897        { 
    9998        } 
     
    150149            Collector::markStackObjectsConservatively(m_buffer, m_base + m_size); 
    151150        } 
    152         void setIsForImplicitCall(bool isForImplicitCall) { m_isForImplicitCall = isForImplicitCall; } 
    153         bool isForImplicitCall() { return m_isForImplicitCall; } 
     151 
     152        bool isGlobal() { return !!m_baseObserver; } 
     153 
    154154    private: 
    155155        size_t newBuffer(size_t size, size_t capacity, size_t minCapacity, size_t maxSize, size_t offset); 
     
    170170        Register* m_base; 
    171171        Register* m_buffer; 
    172         RegisterFileStack* m_stack; 
     172        RegisterFileStack* m_baseObserver; 
    173173    }; 
    174174     
  • branches/squirrelfish/JavaScriptCore/VM/RegisterFileStack.cpp

    r33325 r33327  
    3636RegisterFileStack::~RegisterFileStack() 
    3737{ 
    38     for (size_t i = 0; i < m_stack.size(); ++i) 
    39         delete m_stack[i]; 
     38    ASSERT(m_stack.size() == 1 && m_stack[0]->size() == 0); // The stack shouldn't be destroyed during execution. 
     39    delete m_stack[0]; 
    4040} 
    4141 
     
    4848        return current; 
    4949 
    50     RegisterFile* previous = current; 
    51  
    5250    // Slow case: Existing register file is in use: Create a nested 
    5351    // register file with a copy of this register file's globals. 
    54     RegisterFile* registerFile = allocateRegisterFile(current->maxSize() - current->size()); 
    55     registerFile->addGlobalSlots(previous->numGlobalSlots()); 
    56     registerFile->copyGlobals(previous); 
     52    RegisterFile* lastGlobal = this->lastGlobal(); 
    5753 
    58     return registerFile; 
     54    current = allocateRegisterFile(current->maxSize() - current->size(), this); 
     55    current->addGlobalSlots(lastGlobal->numGlobalSlots()); 
     56    current->copyGlobals(lastGlobal); 
     57    m_globalBase = *current->basePointer(); 
     58 
     59    return current; 
    5960} 
    6061 
     
    7273    m_stack.removeLast(); 
    7374 
    74     RegisterFile* previous = current(); 
    75     ASSERT(tmp->numGlobalSlots() == previous->numGlobalSlots() || !m_implicitCallDepth); 
    76     previous->addGlobalSlots(tmp->numGlobalSlots() - previous->numGlobalSlots()); 
    77     previous->copyGlobals(tmp); 
    78     m_base = *current()->basePointer(); 
     75    ASSERT(tmp->isGlobal() || tmp->numGlobalSlots() == lastGlobal()->numGlobalSlots()); 
     76    if (tmp->isGlobal()) { 
     77        RegisterFile* lastGlobal = this->lastGlobal(); 
     78        lastGlobal->addGlobalSlots(tmp->numGlobalSlots() - lastGlobal->numGlobalSlots()); 
     79        lastGlobal->copyGlobals(tmp); 
     80 
     81        m_globalBase = *lastGlobal->basePointer(); 
     82    } 
     83 
    7984    delete tmp; 
    8085} 
     
    8287RegisterFile* RegisterFileStack::pushFunctionRegisterFile() 
    8388{ 
    84     m_implicitCallDepth++; 
    85  
    86     RegisterFile* previous = current(); 
    87  
    88     RegisterFile* result = allocateRegisterFile(current()->maxSize() - current()->size()); 
    89     result->addGlobalSlots(previous->numGlobalSlots()); 
    90     result->copyGlobals(previous); 
    91     result->setIsForImplicitCall(true); 
    92     return result; 
     89    return allocateRegisterFile(current()->maxSize() - current()->size()); 
    9390} 
    9491 
    9592void RegisterFileStack::popFunctionRegisterFile() 
    9693{ 
    97     RegisterFile* tmp = m_stack.last(); 
     94    delete m_stack.last(); 
    9895    m_stack.removeLast(); 
    99  
    100     RegisterFile* previous = current(); 
    101     ASSERT(tmp->numGlobalSlots() == previous->numGlobalSlots()); 
    102     previous->copyGlobals(tmp); 
    103     m_base = *current()->basePointer(); 
    104     delete tmp; 
    10596} 
    10697 
    107 RegisterFile* RegisterFileStack::allocateRegisterFile(size_t maxSize) 
     98RegisterFile* RegisterFileStack::allocateRegisterFile(size_t maxSize, RegisterFileStack* registerFileStack) 
    10899{ 
    109     RegisterFile* registerFile = new RegisterFile(this, maxSize); 
     100    RegisterFile* registerFile = new RegisterFile(maxSize, registerFileStack); 
    110101    m_stack.append(registerFile); 
    111     m_base = *registerFile->basePointer(); 
    112102    return registerFile; 
    113103} 
  • branches/squirrelfish/JavaScriptCore/VM/RegisterFileStack.h

    r33305 r33327  
    3838    public: 
    3939        RegisterFileStack() 
    40             : m_implicitCallDepth(0) 
     40            : m_globalBase(0) 
    4141        { 
    42             allocateRegisterFile(); 
     42            allocateRegisterFile(RegisterFile::DefaultRegisterFileSize, this); 
    4343        } 
    4444 
     
    6060        } 
    6161 
    62         // Pointer to a value that holds the base of the top-most register file. 
    63         Register** basePointer() { return &m_base; } 
     62        // Pointer to a value that holds the base of the top-most global register file. 
     63        Register** globalBasePointer() { return &m_globalBase; } 
    6464 
    6565        void baseChanged(RegisterFile* registerFile) 
    6666        { 
    67             ASSERT(registerFile == current()); 
    68             m_base = *registerFile->basePointer(); 
     67            ASSERT(registerFile == lastGlobal()); 
     68            m_globalBase = *registerFile->basePointer(); 
    6969        } 
    7070 
    71         bool inImplicitCall() { return m_implicitCallDepth > 0; } 
     71    private: 
     72        typedef Vector<RegisterFile*, 4> Stack; 
    7273 
    7374        RegisterFile* lastGlobal() { 
    7475            ASSERT(m_stack.size()); 
    7576            for (size_t i = m_stack.size() - 1; i > 0; --i) { 
    76                 if (!m_stack[i]->isForImplicitCall()) 
     77                if (m_stack[i]->isGlobal()) 
    7778                    return m_stack[i]; 
    7879            } 
    79             ASSERT(!m_stack[0]->isForImplicitCall()); 
     80            ASSERT(m_stack[0]->isGlobal()); 
    8081            return m_stack[0]; 
    8182        } 
    82     private: 
    83         typedef Vector<RegisterFile*, 4> Stack; 
    8483 
    85         RegisterFile* allocateRegisterFile(size_t maxSize = RegisterFile::DefaultRegisterFileSize); 
     84        RegisterFile* allocateRegisterFile(size_t maxSize, RegisterFileStack* = 0); 
    8685 
    8786        RegisterFile* previous() { return m_stack[m_stack.size() - 2]; } 
     
    8988 
    9089        Stack m_stack; 
    91         Register* m_base; 
    92         int m_implicitCallDepth; 
     90        Register* m_globalBase; 
    9391    }; 
    9492 
  • branches/squirrelfish/JavaScriptCore/kjs/JSGlobalObject.h

    r33324 r33327  
    8181        struct JSGlobalObjectData : public JSVariableObjectData { 
    8282            JSGlobalObjectData(JSGlobalObject* globalObject, JSObject* thisValue) 
    83                 : JSVariableObjectData(&symbolTable, registerFileStack.basePointer(), 0) 
     83                : JSVariableObjectData(&symbolTable, registerFileStack.globalBasePointer(), 0) 
    8484                , globalScopeChain(globalObject) 
    8585                , globalExec(new ExecState(globalObject, thisValue, globalScopeChain))