Changeset 36821 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Sep 23, 2008, 5:27:18 PM (17 years ago)
Author:
[email protected]
Message:

2008-09-23 Geoffrey Garen <[email protected]>

Reviewed by Darin Adler.


Changed the layout of the call frame from


{ header, parameters, locals | constants, temporaries }


to


{ parameters, header | locals, constants, temporaries }


This simplifies function entry+exit, and enables a number of future
optimizations.


13.5% speedup on empty call benchmark for bytecode; 23.6% speedup on
empty call benchmark for CTI.


SunSpider says no change. SunSpider --v8 says 1% faster.

  • VM/CTI.cpp:


Added a bit of abstraction for calculating whether a register is a
constant, since this patch changes that calculation:
(JSC::CTI::isConstant):
(JSC::CTI::getConstant):
(JSC::CTI::emitGetArg):
(JSC::CTI::emitGetPutArg):
(JSC::CTI::getConstantImmediateNumericArg):

Updated for changes to callframe header location:
(JSC::CTI::emitPutToCallFrameHeader):
(JSC::CTI::emitGetFromCallFrameHeader):
(JSC::CTI::printOpcodeOperandTypes):


Renamed to spite Oliver:
(JSC::CTI::emitInitRegister):


Added an abstraction for emitting a call through a register, so that
calls through registers generate exception info, too:
(JSC::CTI::emitCall):

Updated to match the new callframe header layout, and to support calls
through registers, which have no destination address:
(JSC::CTI::compileOpCall):
(JSC::CTI::privateCompileMainPass):
(JSC::CTI::privateCompileSlowCases):
(JSC::CTI::privateCompile):

  • VM/CTI.h:

More of the above:
(JSC::CallRecord::CallRecord):

  • VM/CodeBlock.cpp:

Updated for new register layout:
(JSC::registerName):
(JSC::CodeBlock::dump):

  • VM/CodeBlock.h:


Updated CodeBlock to track slightly different information about the
register frame, and tweaked the style of an ASSERT_NOT_REACHED.
(JSC::CodeBlock::CodeBlock):
(JSC::CodeBlock::getStubInfo):

  • VM/CodeGenerator.cpp:


Added some abstraction around constant register allocation, since this
patch changes it, changed codegen to account for the new callframe
layout, and added abstraction around register fetching code
that used to assume that all local registers lived at negative indices,
since vars now live at positive indices:
(JSC::CodeGenerator::generate):
(JSC::CodeGenerator::addVar):
(JSC::CodeGenerator::addGlobalVar):
(JSC::CodeGenerator::allocateConstants):
(JSC::CodeGenerator::CodeGenerator):
(JSC::CodeGenerator::addParameter):
(JSC::CodeGenerator::registerFor):
(JSC::CodeGenerator::constRegisterFor):
(JSC::CodeGenerator::newRegister):
(JSC::CodeGenerator::newTemporary):
(JSC::CodeGenerator::highestUsedRegister):
(JSC::CodeGenerator::addConstant):


ASSERT that our caller referenced the registers it passed to us.
Otherwise, we might overwrite them with parameters:
(JSC::CodeGenerator::emitCall):
(JSC::CodeGenerator::emitConstruct):

  • VM/CodeGenerator.h:


Added some abstraction for getting a RegisterID for a given index,
since the rules are a little weird:
(JSC::CodeGenerator::registerFor):

  • VM/Machine.cpp:

Utility function to transform a machine return PC to a virtual machine
return VPC, for the sake of stack unwinding, since both PCs are stored
in the same location now:
(JSC::vPCForPC):

Tweaked to account for new call frame:
(JSC::Machine::initializeCallFrame):


Tweaked to account for registerOffset supplied by caller:
(JSC::slideRegisterWindowForCall):

Tweaked to account for new register layout:
(JSC::scopeChainForCall):
(JSC::Machine::callEval):
(JSC::Machine::dumpRegisters):
(JSC::Machine::unwindCallFrame):
(JSC::Machine::execute):

Changed op_call and op_construct to implement the new calling convention:
(JSC::Machine::privateExecute):

Tweaked to account for the new register layout:
(JSC::Machine::retrieveArguments):
(JSC::Machine::retrieveCaller):
(JSC::Machine::retrieveLastCaller):
(JSC::Machine::callFrame):
(JSC::Machine::getArgumentsData):

Changed CTI call helpers to implement the new calling convention:
(JSC::Machine::cti_op_call_JSFunction):
(JSC::Machine::cti_op_call_NotJSFunction):
(JSC::Machine::cti_op_ret_activation):
(JSC::Machine::cti_op_ret_profiler):
(JSC::Machine::cti_op_construct_JSConstruct):
(JSC::Machine::cti_op_construct_NotJSConstruct):
(JSC::Machine::cti_op_call_eval):

  • VM/Machine.h:
  • VM/Opcode.h:


Renamed op_initialise_locals to op_init, because this opcode
doesn't initialize all locals, and it doesn't initialize only locals.
Also, to spite Oliver.


  • VM/RegisterFile.h:


New call frame enumeration values:
(JSC::RegisterFile::):

Simplified the calculation of whether a RegisterID is a temporary,
since we can no longer assume that all positive non-constant registers
are temporaries:

  • VM/RegisterID.h: (JSC::RegisterID::RegisterID): (JSC::RegisterID::setTemporary): (JSC::RegisterID::isTemporary):

Renamed firstArgumentIndex to firstParameterIndex because the assumption
that this variable pertained to the actual arguments supplied by the
caller caused me to write some buggy code:

  • kjs/Arguments.cpp: (JSC::ArgumentsData::ArgumentsData): (JSC::Arguments::Arguments): (JSC::Arguments::fillArgList): (JSC::Arguments::getOwnPropertySlot): (JSC::Arguments::put):

Updated for new call frame layout:

  • kjs/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::functionName): (JSC::DebuggerCallFrame::type):
  • kjs/DebuggerCallFrame.h:

Changed the activation object to account for the fact that a call frame
header now sits between parameters and local variables. This change
requires all variable objects to do their own marking, since they
now use their register storage differently:

  • kjs/JSActivation.cpp: (JSC::JSActivation::mark): (JSC::JSActivation::copyRegisters): (JSC::JSActivation::createArgumentsObject):
  • kjs/JSActivation.h:

Updated global object to use the new interfaces required by the change
to JSActivation above:

  • kjs/JSGlobalObject.cpp: (JSC::JSGlobalObject::reset): (JSC::JSGlobalObject::mark): (JSC::JSGlobalObject::copyGlobalsFrom): (JSC::JSGlobalObject::copyGlobalsTo):
  • kjs/JSGlobalObject.h: (JSC::JSGlobalObject::addStaticGlobals):

Updated static scope object to use the new interfaces required by the
change to JSActivation above:

  • kjs/JSStaticScopeObject.cpp: (JSC::JSStaticScopeObject::mark): (JSC::JSStaticScopeObject::~JSStaticScopeObject):
  • kjs/JSStaticScopeObject.h: (JSC::JSStaticScopeObject::JSStaticScopeObject): (JSC::JSStaticScopeObject::d):

Updated variable object to use the new interfaces required by the
change to JSActivation above:

  • kjs/JSVariableObject.cpp: (JSC::JSVariableObject::copyRegisterArray): (JSC::JSVariableObject::setRegisters):
  • kjs/JSVariableObject.h:

Changed the bit twiddling in symbol table not to assume that all indices
are negative, since they can be positive now:

  • kjs/SymbolTable.h: (JSC::SymbolTableEntry::SymbolTableEntry): (JSC::SymbolTableEntry::isNull): (JSC::SymbolTableEntry::getIndex): (JSC::SymbolTableEntry::getAttributes): (JSC::SymbolTableEntry::setAttributes): (JSC::SymbolTableEntry::isReadOnly): (JSC::SymbolTableEntry::pack): (JSC::SymbolTableEntry::isValidIndex):

Changed call and construct nodes to ref their functions and/or bases,
so that emitCall/emitConstruct doesn't overwrite them with parameters.
Also, updated for rename to registerFor:

  • kjs/nodes.cpp: (JSC::ResolveNode::emitCode): (JSC::NewExprNode::emitCode): (JSC::EvalFunctionCallNode::emitCode): (JSC::FunctionCallValueNode::emitCode): (JSC::FunctionCallResolveNode::emitCode): (JSC::FunctionCallBracketNode::emitCode): (JSC::FunctionCallDotNode::emitCode): (JSC::PostfixResolveNode::emitCode): (JSC::DeleteResolveNode::emitCode): (JSC::TypeOfResolveNode::emitCode): (JSC::PrefixResolveNode::emitCode): (JSC::ReadModifyResolveNode::emitCode): (JSC::AssignResolveNode::emitCode): (JSC::ConstDeclNode::emitCodeSingle): (JSC::ForInNode::emitCode):

Added abstraction for getting exception info out of a call through a
register:

  • masm/X86Assembler.h: (JSC::X86Assembler::emitCall):


Removed duplicate #if:

  • wtf/Platform.h:
Location:
trunk/JavaScriptCore/kjs
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/Arguments.cpp

    r36804 r36821  
    3939
    4040struct ArgumentsData : Noncopyable {
    41     ArgumentsData(JSActivation* activation, unsigned numParameters, unsigned firstArgumentIndex, unsigned numArguments, JSFunction* callee)
     41    ArgumentsData(JSActivation* activation, unsigned numParameters, int firstParameterIndex, unsigned numArguments, JSFunction* callee)
    4242        : activation(activation)
    4343        , numParameters(numParameters)
    44         , firstArgumentIndex(firstArgumentIndex)
     44        , firstParameterIndex(firstParameterIndex)
    4545        , numArguments(numArguments)
    4646        , extraArguments(0)
     
    5454
    5555    unsigned numParameters;
    56     unsigned firstArgumentIndex;
     56    int firstParameterIndex;
    5757    unsigned numArguments;
    5858    Register* extraArguments;
     
    6666
    6767// ECMA 10.1.8
    68 Arguments::Arguments(ExecState* exec, JSFunction* function, JSActivation* activation, int firstArgumentIndex, Register* argv, int argc)
     68Arguments::Arguments(ExecState* exec, JSFunction* function, JSActivation* activation, int firstParameterIndex, Register* argv, int argc)
    6969    : JSObject(exec->lexicalGlobalObject()->argumentsStructure())
    70     , d(new ArgumentsData(activation, function->numParameters(), firstArgumentIndex, argc, function))
     70    , d(new ArgumentsData(activation, function->numParameters(), firstParameterIndex, argc, function))
    7171{
    7272    ASSERT(activation);
     
    119119
    120120        if (d->numParameters == d->numArguments) {
    121             args.initialize(&d->activation->registerAt(d->firstArgumentIndex), d->numArguments);
     121            args.initialize(&d->activation->registerAt(d->firstParameterIndex), d->numArguments);
    122122            return;
    123123        }
     
    126126        unsigned i = 0;
    127127        for (; i < parametersLength; ++i)
    128             args.append(d->activation->uncheckedSymbolTableGetValue(d->firstArgumentIndex + i));
     128            args.append(d->activation->uncheckedSymbolTableGetValue(d->firstParameterIndex + i));
    129129        for (; i < d->numArguments; ++i)
    130130            args.append(d->extraArguments[i - d->numParameters].getJSValue());
     
    136136    for (; i < parametersLength; ++i) {
    137137        if (!d->deletedArguments[i])
    138             args.append(d->activation->uncheckedSymbolTableGetValue(d->firstArgumentIndex + i));
     138            args.append(d->activation->uncheckedSymbolTableGetValue(d->firstParameterIndex + i));
    139139        else
    140140            args.append(get(exec, i));
     
    152152    if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
    153153        if (i < d->numParameters)
    154             d->activation->uncheckedSymbolTableGet(d->firstArgumentIndex + i, slot);
     154            d->activation->uncheckedSymbolTableGet(d->firstParameterIndex + i, slot);
    155155        else
    156156            slot.setValue(d->extraArguments[i - d->numParameters].getJSValue());
     
    167167    if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
    168168        if (i < d->numParameters)
    169             d->activation->uncheckedSymbolTableGet(d->firstArgumentIndex + i, slot);
     169            d->activation->uncheckedSymbolTableGet(d->firstParameterIndex + i, slot);
    170170        else
    171171            slot.setValue(d->extraArguments[i - d->numParameters].getJSValue());
     
    190190    if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
    191191        if (i < d->numParameters)
    192             d->activation->uncheckedSymbolTablePut(d->firstArgumentIndex + i, value);
     192            d->activation->uncheckedSymbolTablePut(d->firstParameterIndex + i, value);
    193193        else
    194194            d->extraArguments[i - d->numParameters] = value;
     
    205205    if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
    206206        if (i < d->numParameters)
    207             d->activation->uncheckedSymbolTablePut(d->firstArgumentIndex + i, value);
     207            d->activation->uncheckedSymbolTablePut(d->firstParameterIndex + i, value);
    208208        else
    209209            d->extraArguments[i - d->numParameters] = value;
  • trunk/JavaScriptCore/kjs/DebuggerCallFrame.cpp

    r36263 r36821  
    3737namespace JSC {
    3838
    39 Register* DebuggerCallFrame::callFrame() const
    40 {
    41     return m_registers - m_codeBlock->numLocals - RegisterFile::CallFrameHeaderSize;
    42 }
    43 
    4439const UString* DebuggerCallFrame::functionName() const
    4540{
     
    4742        return 0;
    4843
    49     JSFunction* function = static_cast<JSFunction*>(callFrame()[RegisterFile::Callee].getJSValue());
     44    JSFunction* function = static_cast<JSFunction*>(m_registers[RegisterFile::Callee].getJSValue());
    5045    if (!function)
    5146        return 0;
     
    5550DebuggerCallFrame::Type DebuggerCallFrame::type() const
    5651{
    57     if (callFrame()[RegisterFile::Callee].getJSValue())
     52    if (m_registers[RegisterFile::Callee].getJSValue())
    5853        return FunctionType;
    5954
  • trunk/JavaScriptCore/kjs/DebuggerCallFrame.h

    r36263 r36821  
    6868
    6969    private:
    70         Register* callFrame() const;
    71 
    7270        ExecState* m_exec;
    7371        JSGlobalObject* m_dynamicGlobalObject;
  • trunk/JavaScriptCore/kjs/JSActivation.cpp

    r36743 r36821  
    5252}
    5353
     54void JSActivation::mark()
     55{
     56    Base::mark();
     57   
     58    if (d()->argumentsObject)
     59        d()->argumentsObject->mark();
     60
     61    Register* registerArray = d()->registerArray.get();
     62    if (!registerArray)
     63        return;
     64
     65    size_t numParametersMinusThis = d()->functionBody->generatedByteCode().numParameters - 1;
     66
     67    size_t i = 0;
     68    size_t count = numParametersMinusThis;
     69    for ( ; i < count; ++i) {
     70        Register& r = registerArray[i];
     71        if (!r.marked())
     72            r.mark();
     73    }
     74
     75    size_t numVars = d()->functionBody->generatedByteCode().numVars;
     76
     77    // Skip the call frame, which sits between the parameters and vars.
     78    i += RegisterFile::CallFrameHeaderSize;
     79    count += RegisterFile::CallFrameHeaderSize + numVars;
     80
     81    for ( ; i < count; ++i) {
     82        Register& r = registerArray[i];
     83        if (!r.marked())
     84            r.mark();
     85    }
     86}
     87
    5488void JSActivation::copyRegisters()
    5589{
    56     int numLocals = d()->functionBody->generatedByteCode().numLocals;
     90    ASSERT(!d()->registerArray);
     91    ASSERT(!d()->registerArraySize);
     92
     93    size_t numParametersMinusThis = d()->functionBody->generatedByteCode().numParameters - 1;
     94    size_t numVars = d()->functionBody->generatedByteCode().numVars;
     95    size_t numLocals = numVars + numParametersMinusThis;
     96
    5797    if (!numLocals)
    5898        return;
    5999
    60     copyRegisterArray(d()->registers - numLocals, numLocals);
     100    int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
     101    size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
     102
     103    Register* registerArray = copyRegisterArray(d()->registers - registerOffset, registerArraySize);
     104    setRegisters(registerArray + registerOffset, registerArray, registerArraySize);
    61105}
    62106
     
    127171}
    128172
    129 void JSActivation::mark()
    130 {
    131     Base::mark();
    132    
    133     if (d()->argumentsObject)
    134         d()->argumentsObject->mark();
    135 }
    136 
    137173bool JSActivation::isActivationObject() const
    138174{
     
    164200Arguments* JSActivation::createArgumentsObject(ExecState* exec)
    165201{
    166     Register* callFrame = d()->registers - d()->functionBody->generatedByteCode().numLocals - RegisterFile::CallFrameHeaderSize;
    167 
    168202    JSFunction* function;
    169203    Register* argv;
    170204    int argc;
    171     exec->machine()->getArgumentsData(callFrame, function, argv, argc);
    172 
    173     int firstArgumentIndex = -d()->functionBody->generatedByteCode().numLocals + 1;
    174     return new (exec) Arguments(exec, function, this, firstArgumentIndex, argv, argc);
     205    int firstParameterIndex;
     206    exec->machine()->getArgumentsData(d()->registers, function, firstParameterIndex, argv, argc);
     207
     208    return new (exec) Arguments(exec, function, this, firstParameterIndex, argv, argc);
    175209}
    176210
  • trunk/JavaScriptCore/kjs/JSActivation.h

    r36735 r36821  
    4545        virtual ~JSActivation();
    4646       
     47        virtual void mark();
     48
    4749        virtual bool isActivationObject() const;
    4850        virtual bool isDynamicScope() const;
     
    7274        virtual JSObject* toThisObject(ExecState*) const;
    7375
    74         virtual void mark();
    75        
    7676        void copyRegisters();
    7777       
  • trunk/JavaScriptCore/kjs/JSGlobalObject.cpp

    r36757 r36821  
    203203    ASSERT(!hasCustomProperties());
    204204    symbolTable().clear();
    205     setRegisterArray(0, 0);
     205    setRegisters(0, 0, 0);
    206206
    207207    ExecState* exec = d()->globalExec.get();
     
    397397    // No need to mark the other structures, because their prototypes are all
    398398    // guaranteed to be referenced elsewhere.
     399
     400    Register* registerArray = d()->registerArray.get();
     401    if (!registerArray)
     402        return;
     403
     404    size_t size = d()->registerArraySize;
     405    for (size_t i = 0; i < size; ++i) {
     406        Register& r = registerArray[i];
     407        if (!r.marked())
     408            r.mark();
     409    }
    399410}
    400411
     
    424435        return;
    425436    }
    426     copyRegisterArray(registerFile.lastGlobal(), numGlobals);
     437   
     438    Register* registerArray = copyRegisterArray(registerFile.lastGlobal(), numGlobals);
     439    setRegisters(registerArray + numGlobals, registerArray, numGlobals);
    427440}
    428441
     
    438451    if (d()->registerArray) {
    439452        memcpy(registerFile.base() - d()->registerArraySize, d()->registerArray.get(), d()->registerArraySize * sizeof(Register));
    440         setRegisterArray(0, 0);
    441     }
    442 
    443     d()->registers = registerFile.base();
     453        setRegisters(registerFile.base(), 0, 0);
     454    }
    444455}
    445456
  • trunk/JavaScriptCore/kjs/JSGlobalObject.h

    r36755 r36821  
    157157        virtual ~JSGlobalObject();
    158158
     159        virtual void mark();
     160
    159161        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
    160162        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
     
    225227        ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
    226228
    227         virtual void mark();
    228 
    229229        virtual bool isGlobalObject() const { return true; }
    230230        virtual JSGlobalObject* toGlobalObject(ExecState*) const;
     
    275275    inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
    276276    {
    277         size_t registerArraySize = d()->registerArraySize;
    278         Register* registerArray = new Register[registerArraySize + count];
     277        size_t oldSize = d()->registerArraySize;
     278        size_t newSize = oldSize + count;
     279        Register* registerArray = new Register[newSize];
    279280        if (d()->registerArray)
    280             memcpy(registerArray + count, d()->registerArray.get(), registerArraySize * sizeof(Register));
    281         setRegisterArray(registerArray, registerArraySize + count);
    282 
    283         for (int i = 0, index = -static_cast<int>(registerArraySize) - 1; i < count; ++i, --index) {
     281            memcpy(registerArray + count, d()->registerArray.get(), oldSize * sizeof(Register));
     282        setRegisters(registerArray + newSize, registerArray, newSize);
     283
     284        for (int i = 0, index = -static_cast<int>(oldSize) - 1; i < count; ++i, --index) {
    284285            GlobalPropertyInfo& global = globals[i];
    285286            ASSERT(global.attributes & DontDelete);
  • trunk/JavaScriptCore/kjs/JSStaticScopeObject.cpp

    r36263 r36821  
    3232ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject);
    3333
     34void JSStaticScopeObject::mark()
     35{
     36    JSVariableObject::mark();
     37   
     38    if (!d()->registerStore.marked())
     39        d()->registerStore.mark();
     40}
     41
    3442JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
    3543{
     
    6068JSStaticScopeObject::~JSStaticScopeObject()
    6169{
    62     ASSERT(d);
    63     delete static_cast<JSStaticScopeObjectData*>(d);
     70    ASSERT(d());
     71    delete d();
    6472}
    6573
  • trunk/JavaScriptCore/kjs/JSStaticScopeObject.h

    r36263 r36821  
    4848            : JSVariableObject(exec->globalData().nullProtoStructureID, new JSStaticScopeObjectData())
    4949        {
    50             JSStaticScopeObjectData* data = static_cast<JSStaticScopeObjectData*>(d);
    51             data->registerStore = value;
     50            d()->registerStore = value;
    5251            symbolTable().add(ident.ustring().rep(), SymbolTableEntry(-1, attributes));
    5352        }
    5453        virtual ~JSStaticScopeObject();
     54        virtual void mark();
    5555        bool isDynamicScope() const;
    5656        virtual JSObject* toThisObject(ExecState*) const;
     
    5959        virtual void put(ExecState*, const Identifier&, JSValue*, PutPropertySlot&);
    6060        void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
     61
     62    private:
     63        JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
    6164    };
    6265
  • trunk/JavaScriptCore/kjs/JSVariableObject.cpp

    r36263 r36821  
    6464}
    6565
    66 void JSVariableObject::mark()
    67 {
    68     JSObject::mark();
    69 
    70     if (!d->registerArray)
    71         return;
    72    
    73     Register* end = d->registerArray.get() + d->registerArraySize;
    74     for (Register* it = d->registerArray.get(); it != end; ++it)
    75         if (!(*it).marked())
    76             (*it).mark();
    77 }
    78 
    7966bool JSVariableObject::isVariableObject() const
    8067{
     
    8269}
    8370
    84 void JSVariableObject::copyRegisterArray(Register* src, size_t count)
     71Register* JSVariableObject::copyRegisterArray(Register* src, size_t count)
    8572{
    86     ASSERT(!d->registerArray);
    87 
    8873    Register* registerArray = new Register[count];
    8974    memcpy(registerArray, src, count * sizeof(Register));
    9075
    91     setRegisterArray(registerArray, count);
     76    return registerArray;
    9277}
    9378
    94 void JSVariableObject::setRegisterArray(Register* registerArray, size_t count)
     79void JSVariableObject::setRegisters(Register* r, Register* registerArray, size_t count)
    9580{
    9681    if (registerArray != d->registerArray.get())
    9782        d->registerArray.set(registerArray);
    9883    d->registerArraySize = count;
    99     d->registers = registerArray + count;
     84    d->registers = r;
    10085}
    10186
  • trunk/JavaScriptCore/kjs/JSVariableObject.h

    r36675 r36821  
    4949        virtual bool deleteProperty(ExecState*, const Identifier&);
    5050        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
    51         virtual void mark();
    5251       
    5352        virtual bool isVariableObject() const;
     
    7271
    7372            SymbolTable* symbolTable; // Maps name -> offset from "r" in register file.
    74             Register* registers; // Pointers to the register past the end of local storage. (Local storage indexes are negative.)
     73            Register* registers; // "r" in the register file.
    7574            OwnArrayPtr<Register> registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
    7675            size_t registerArraySize;
     
    9291        }
    9392
    94         void copyRegisterArray(Register* src, size_t count);
    95         void setRegisterArray(Register* registerArray, size_t count);
     93        Register* copyRegisterArray(Register* src, size_t count);
     94        void setRegisters(Register* r, Register* registerArray, size_t count);
    9695
    9796        bool symbolTableGet(const Identifier&, PropertySlot&);
  • trunk/JavaScriptCore/kjs/SymbolTable.h

    r36263 r36821  
    3939
    4040    // The bit twiddling in this class assumes that every register index is a
    41     // reasonably small negative number, and therefore has its high two bits set.
     41    // reasonably small positive or negative number, and therefore has its high
     42    // four bits all set or all unset.
    4243
    4344    struct SymbolTableEntry {
    4445        SymbolTableEntry()
    45             : rawValue(0)
     46            : m_bits(0)
    4647        {
    4748        }
    48        
     49
    4950        SymbolTableEntry(int index)
    5051        {
    51             ASSERT(index & 0x80000000);
    52             ASSERT(index & 0x40000000);
     52            ASSERT(isValidIndex(index));
     53            pack(index, false, false);
     54        }
    5355
    54             rawValue = index & ~0x80000000 & ~0x40000000;
     56        SymbolTableEntry(int index, unsigned attributes)
     57        {
     58            ASSERT(isValidIndex(index));
     59            pack(index, attributes & ReadOnly, attributes & DontEnum);
    5560        }
    5661       
    57         SymbolTableEntry(int index, unsigned attributes)
    58         {
    59             ASSERT(index & 0x80000000);
    60             ASSERT(index & 0x40000000);
    61 
    62             rawValue = index;
    63            
    64             if (!(attributes & ReadOnly))
    65                 rawValue &= ~0x80000000;
    66            
    67             if (!(attributes & DontEnum))
    68                 rawValue &= ~0x40000000;
    69         }
    70 
    7162        bool isNull() const
    7263        {
    73             return !rawValue;
     64            return !m_bits;
    7465        }
    7566
    7667        int getIndex() const
    7768        {
    78             ASSERT(!isNull());
    79             return rawValue | 0x80000000 | 0x40000000;
     69            return m_bits >> FlagBits;
    8070        }
    8171
     
    8373        {
    8474            unsigned attributes = 0;
    85            
    86             if (rawValue & 0x80000000)
     75            if (m_bits & ReadOnlyFlag)
    8776                attributes |= ReadOnly;
    88            
    89             if (rawValue & 0x40000000)
     77            if (m_bits & DontEnumFlag)
    9078                attributes |= DontEnum;
    91            
    9279            return attributes;
    9380        }
     
    9582        void setAttributes(unsigned attributes)
    9683        {
    97             rawValue = getIndex();
    98            
    99             if (!(attributes & ReadOnly))
    100                 rawValue &= ~0x80000000;
    101            
    102             if (!(attributes & DontEnum))
    103                 rawValue &= ~0x40000000;
     84            pack(getIndex(), attributes & ReadOnly, attributes & DontEnum);
    10485        }
    10586
    10687        bool isReadOnly() const
    10788        {
    108             return rawValue & 0x80000000;
     89            return m_bits & ReadOnlyFlag;
    10990        }
    11091
    111         int rawValue;
     92    private:
     93        static const unsigned ReadOnlyFlag = 0x1;
     94        static const unsigned DontEnumFlag = 0x2;
     95        static const unsigned NotNullFlag = 0x4;
     96        static const unsigned FlagBits = 3;
     97
     98        void pack(int index, bool readOnly, bool dontEnum)
     99        {
     100            m_bits = (index << FlagBits) | NotNullFlag;
     101            if (readOnly)
     102                m_bits |= ReadOnlyFlag;
     103            if (dontEnum)
     104                m_bits |= DontEnumFlag;
     105        }
     106       
     107        bool isValidIndex(int index)
     108        {
     109            return ((index << FlagBits) >> FlagBits) == index;
     110        }
     111
     112        int m_bits;
    112113    };
    113114
     
    115116        typedef SymbolTableEntry TraitType;
    116117        static SymbolTableEntry emptyValue() { return SymbolTableEntry(); }
    117         static const bool emptyValueIsZero = false;
     118        static const bool emptyValueIsZero = true;
    118119        static const bool needsDestruction = false;
    119120    };
  • trunk/JavaScriptCore/kjs/nodes.cpp

    r36809 r36821  
    287287RegisterID* ResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    288288{
    289     if (RegisterID* local = generator.registerForLocal(m_ident)) {
     289    if (RegisterID* local = generator.registerFor(m_ident)) {
    290290        if (dst == ignoredResult())
    291291            return 0;
     
    405405RegisterID* NewExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    406406{
    407     RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
    408     return generator.emitConstruct(generator.finalDestination(dst, r0.get()), r0.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
     407    RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
     408    return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    409409}
    410410
     
    412412{
    413413    RefPtr<RegisterID> base = generator.tempDestination(dst);
    414     RegisterID* func = generator.newTemporary();
    415     generator.emitResolveWithBase(base.get(), func, generator.propertyNames().eval);
    416     return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
     414    RefPtr<RegisterID> func = generator.newTemporary();
     415    generator.emitResolveWithBase(base.get(), func.get(), generator.propertyNames().eval);
     416    return generator.emitCallEval(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    417417}
    418418
    419419RegisterID* FunctionCallValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    420420{
    421     RegisterID* func = generator.emitNode(m_expr.get());
    422     return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
     421    RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
     422    return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
    423423}
    424424
    425425RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    426426{
    427     if (RegisterID* local = generator.registerForLocal(m_ident))
    428         return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
     427    if (RefPtr<RegisterID> local = generator.registerFor(m_ident))
     428        return generator.emitCall(generator.finalDestination(dst), local.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
    429429
    430430    int index = 0;
     
    432432    JSValue* globalObject = 0;
    433433    if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
    434         RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
    435         return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
     434        RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
     435        return generator.emitCall(generator.finalDestination(dst), func.get(), 0, m_args.get(), m_divot, m_startOffset, m_endOffset);
    436436    }
    437437
    438438    RefPtr<RegisterID> base = generator.tempDestination(dst);
    439     RegisterID* func = generator.newTemporary();
     439    RefPtr<RegisterID> func = generator.newTemporary();
    440440    int identifierStart = m_divot - m_startOffset;
    441441    generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
    442     generator.emitResolveFunction(base.get(), func, m_ident);
    443     return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
     442    generator.emitResolveFunction(base.get(), func.get(), m_ident);
     443    return generator.emitCall(generator.finalDestination(dst, base.get()), func.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    444444}
    445445
     
    449449    RegisterID* property = generator.emitNode(m_subscript.get());
    450450    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    451     RegisterID* function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
    452     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
     451    RefPtr<RegisterID> function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
     452    return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    453453}
    454454
     
    457457    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
    458458    generator.emitExpressionInfo(m_divot - m_subexpressionDivotOffset, m_startOffset - m_subexpressionDivotOffset, m_subexpressionEndOffset);
    459     RegisterID* function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
    460     return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
     459    RefPtr<RegisterID> function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
     460    return generator.emitCall(generator.finalDestination(dst, base.get()), function.get(), base.get(), m_args.get(), m_divot, m_startOffset, m_endOffset);
    461461}
    462462
     
    475475RegisterID* PostfixResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    476476{
    477     if (RegisterID* local = generator.registerForLocal(m_ident)) {
     477    if (RegisterID* local = generator.registerFor(m_ident)) {
    478478        if (generator.isLocalConstant(m_ident)) {
    479479            if (dst == ignoredResult())
     
    575575RegisterID* DeleteResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    576576{
    577     if (generator.registerForLocal(m_ident))
     577    if (generator.registerFor(m_ident))
    578578        return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
    579579
     
    630630RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    631631{
    632     if (RegisterID* local = generator.registerForLocal(m_ident)) {
     632    if (RegisterID* local = generator.registerFor(m_ident)) {
    633633        if (dst == ignoredResult())
    634634            return 0;
     
    659659RegisterID* PrefixResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    660660{
    661     if (RegisterID* local = generator.registerForLocal(m_ident)) {
     661    if (RegisterID* local = generator.registerFor(m_ident)) {
    662662        if (generator.isLocalConstant(m_ident)) {
    663663            if (dst == ignoredResult())
     
    894894RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    895895{
    896     if (RegisterID* local = generator.registerForLocal(m_ident)) {
     896    if (RegisterID* local = generator.registerFor(m_ident)) {
    897897        if (generator.isLocalConstant(m_ident)) {
    898898            RegisterID* src2 = generator.emitNode(m_right.get());
     
    938938RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
    939939{
    940     if (RegisterID* local = generator.registerForLocal(m_ident)) {
     940    if (RegisterID* local = generator.registerFor(m_ident)) {
    941941        if (generator.isLocalConstant(m_ident))
    942942            return generator.emitNode(dst, m_right.get());
     
    10481048RegisterID* ConstDeclNode::emitCodeSingle(CodeGenerator& generator)
    10491049{
    1050     if (RegisterID* local = generator.registerForLocalConstInit(m_ident)) {
     1050    if (RegisterID* local = generator.constRegisterFor(m_ident)) {
    10511051        if (!m_init)
    10521052            return local;
     
    13391339    if (m_lexpr->isResolveNode()) {
    13401340        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
    1341         propertyName = generator.registerForLocal(ident);
     1341        propertyName = generator.registerFor(ident);
    13421342        if (!propertyName) {
    13431343            propertyName = generator.newTemporary();
Note: See TracChangeset for help on using the changeset viewer.