Ignore:
Timestamp:
Sep 11, 2012, 9:08:18 PM (13 years ago)
Author:
[email protected]
Message:

JSActivation should inline allocate its registers, and eliminate
'arguments' registers in the common case
https://bugs.webkit.org/show_bug.cgi?id=96427

Reviewed by Filip Pizlo.

This cuts the size class for simple closures down to 64 bytes.

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator): Set the usesNonStrictEval
flag, which is new. Use a more specific test for whether a function
uses 'arguments', so we can avoid allocating, initializing, and tearing
off those registers in the common case. Distinguish between capturing
arguments and not, so we can avoid allocating space for arguments in
the torn-off object.

We can make this even more general in the future, with some bytecode
generator refactoring.

(JSC::BytecodeGenerator::resolve): Updated for new interface.

  • bytecompiler/BytecodeGenerator.h:

(BytecodeGenerator):
(JSC::BytecodeGenerator::symbolTable): Updated some types.

  • heap/Heap.cpp:

(JSC::Heap::isValidAllocation): Allow large allocations, now that they
are both supported and used.

  • heap/Heap.h:

(Heap): Added a new form of allocateCell that specifies the full size
of the allocation, to allow for extra space on the end.

  • interpreter/CallFrame.h:

(JSC::ExecState::argumentOffset):
(JSC::ExecState::argumentOffsetIncludingThis):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::unwindCallFrame): Refactored this code to be more
specific about tearing off 'arguments' vs activations. This is something
I forgot in my last patch, and it is required now that we can have
acitvations without 'arguments' registers.

  • runtime/Arguments.h:

(JSC::Arguments::setRegisters): No need for setRegisters anymore because
the activation object's storage doesn't change.

  • runtime/JSActivation.cpp:

(JSC::JSActivation::JSActivation): Initialize our storage manually because
it's not declared to the C++ compiler.

(JSC::JSActivation::visitChildren): No copyAndAppend because our storage
is not out-of-line anymore.

(JSC::JSActivation::symbolTableGet):
(JSC::JSActivation::symbolTablePut):
(JSC::JSActivation::getOwnPropertyNames):
(JSC::JSActivation::symbolTablePutWithAttributes):
(JSC::JSActivation::getOwnPropertySlot):
(JSC::JSActivation::getOwnPropertyDescriptor):
(JSC::JSActivation::argumentsGetter): Refactored isTornOff() testing to
avoid using a data member and to avoid hard-coding any offset assumptions.

  • runtime/JSActivation.h:

(JSC):
(JSActivation):
(JSC::JSActivation::create):
(JSC::JSActivation::isDynamicScope):
(JSC::JSActivation::captureStart):
(JSC::JSActivation::storageSize):
(JSC::JSActivation::storageSizeInBytes):
(JSC::JSActivation::registerOffset):
(JSC::JSActivation::tearOff):
(JSC::JSActivation::isTornOff):
(JSC::JSActivation::storage):
(JSC::JSActivation::allocationSize):
(JSC::JSActivation::isValid): New helper functions for doing the math
on our inline storage. Note that in the "AllOfTheThings" tear-off case,
the number of things is not known at compile time, so we store the
number in the argument count register. We can't just copy the raw contents
of the register beacuse we need a value that is safe for precise marking,
and the value in the register file has an invalid tag.

  • runtime/JSCell.h:

(JSC::allocateCell): New function for allocating with extra storage
on the end.

  • runtime/JSSymbolTableObject.h:

(JSC::JSSymbolTableObject::JSSymbolTableObject):
(JSC::JSSymbolTableObject::finishCreation):

  • runtime/JSVariableObject.h:

(JSC::JSVariableObject::JSVariableObject):
(JSVariableObject): Make it easier for subclasses to use their symbol
tables during construction, by passing the table as a constructor argument.

  • runtime/SymbolTable.h:

(JSC::SharedSymbolTable::usesNonStrictEval):
(JSC::SharedSymbolTable::setUsesNonStrictEval):
(SharedSymbolTable):
(JSC::SharedSymbolTable::captureMode):
(JSC::SharedSymbolTable::setCaptureMode):
(JSC::SharedSymbolTable::captureStart):
(JSC::SharedSymbolTable::setCaptureStart):
(JSC::SharedSymbolTable::captureEnd):
(JSC::SharedSymbolTable::setCaptureEnd):
(JSC::SharedSymbolTable::parameterCountIncludingThis):
(JSC::SharedSymbolTable::setParameterCountIncludingThis):
(JSC::SharedSymbolTable::SharedSymbolTable): Added data members to more
precisely describe what kind of capture is in play, and to avoid having
data members in the activation. We expect N activations per symbol table,
so this can be a big savings in heavy closure usage.

Location:
trunk/Source/JavaScriptCore/runtime
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/Arguments.h

    r126695 r128260  
    111111            d->registers = &activation->registerAt(0);
    112112        }
    113         void setRegisters(WriteBarrierBase<Unknown>* registers) { d->registers = registers; }
    114113
    115114        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
  • trunk/Source/JavaScriptCore/runtime/JSActivation.cpp

    r127363 r128260  
    4242const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSActivation) };
    4343
    44 JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
    45     : Base(
    46         callFrame->globalData(),
    47         callFrame->lexicalGlobalObject()->activationStructure(),
    48         callFrame->registers(),
    49         callFrame->scope()
    50     )
    51     , m_registerArray(callFrame->globalData(), this, 0)
    52     , m_numCapturedArgs(max(callFrame->argumentCount(), functionExecutable->parameterCount()))
    53     , m_numCapturedVars(functionExecutable->capturedVariableCount())
    54     , m_isTornOff(false)
    55     , m_requiresDynamicChecks(functionExecutable->usesEval() && !functionExecutable->isStrictMode())
    56     , m_argumentsRegister(functionExecutable->generatedBytecode().argumentsRegister())
    57 {
    58 }
    59 
    60 void JSActivation::finishCreation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
    61 {
    62     Base::finishCreation(callFrame->globalData(), functionExecutable->symbolTable());
    63     ASSERT(inherits(&s_info));
    64 }
    65 
    6644void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor)
    6745{
     
    7351
    7452    // No need to mark our registers if they're still in the RegisterFile.
    75     PropertyStorage registerArray = thisObject->m_registerArray.get();
    76     if (!registerArray)
     53    if (!thisObject->isTornOff())
    7754        return;
    7855
    79     visitor.copyAndAppend(bitwise_cast<void**>(&registerArray), thisObject->registerArraySizeInBytes(), reinterpret_cast<JSValue*>(registerArray), thisObject->registerArraySize());
    80     thisObject->m_registerArray.set(registerArray, StorageBarrier::Unchecked);
    81     thisObject->m_registers = registerArray + thisObject->registerOffset();
    82 
    83     // Update the arguments object, since it points at our buffer.
    84     CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers));
    85     if (JSValue v = callFrame->uncheckedR(unmodifiedArgumentsRegister(thisObject->m_argumentsRegister)).jsValue())
    86         jsCast<Arguments*>(v)->setRegisters(thisObject->m_registers);
     56    for (size_t i = 0; i < thisObject->storageSize(); ++i)
     57        visitor.append(&thisObject->storage()[i]);
    8758}
    8859
     
    9465
    9566    // Defend against the inspector asking for a var after it has been optimized out.
    96     if (m_isTornOff && entry.getIndex() >= m_numCapturedVars)
     67    if (isTornOff() && !isValid(entry))
    9768        return false;
    9869
     
    10879
    10980    // Defend against the inspector asking for a var after it has been optimized out.
    110     if (m_isTornOff && entry.getIndex() >= m_numCapturedVars)
     81    if (isTornOff() && !isValid(entry))
    11182        return false;
    11283
     
    130101
    131102    // Defend against the inspector asking for a var after it has been optimized out.
    132     if (m_isTornOff && entry.getIndex() >= m_numCapturedVars)
     103    if (isTornOff() && !isValid(entry))
    133104        return false;
    134105
     
    141112    JSActivation* thisObject = jsCast<JSActivation*>(object);
    142113
    143     if (mode == IncludeDontEnumProperties)
     114    if (mode == IncludeDontEnumProperties && !thisObject->isTornOff())
    144115        propertyNames.add(exec->propertyNames().arguments);
    145116
     
    148119        if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties)
    149120            continue;
    150         if (it->second.getIndex() >= thisObject->m_numCapturedVars)
     121        if (!thisObject->isValid(it->second))
    151122            continue;
    152123        propertyNames.add(Identifier(exec, it->first.get()));
     
    165136    SymbolTableEntry& entry = iter->second;
    166137    ASSERT(!entry.isNull());
    167     if (entry.getIndex() >= m_numCapturedVars)
     138    if (!isValid(entry))
    168139        return false;
    169140
     
    179150    if (propertyName == exec->propertyNames().arguments) {
    180151        // Defend against the inspector asking for the arguments object after it has been optimized out.
    181         if (!thisObject->m_isTornOff) {
     152        if (!thisObject->isTornOff()) {
    182153            slot.setCustom(thisObject, thisObject->getArgumentsGetter());
    183154            return true;
     
    206177    if (propertyName == exec->propertyNames().arguments) {
    207178        // Defend against the inspector asking for the arguments object after it has been optimized out.
    208         if (!thisObject->m_isTornOff) {
     179        if (!thisObject->isTornOff()) {
    209180            PropertySlot slot;
    210181            JSActivation::getOwnPropertySlot(thisObject, exec, propertyName, slot);
     
    266237JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, PropertyName)
    267238{
    268     JSActivation* activation = asActivation(slotBase);
     239    JSActivation* activation = jsCast<JSActivation*>(slotBase);
     240    if (activation->isTornOff())
     241        return jsUndefined();
     242
    269243    CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers));
    270     int argumentsRegister = activation->m_argumentsRegister;
     244    int argumentsRegister = callFrame->codeBlock()->argumentsRegister();
    271245    if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue())
    272246        return arguments;
  • trunk/Source/JavaScriptCore/runtime/JSActivation.h

    r127376 r128260  
    3838namespace JSC {
    3939
    40     class Arguments;
    4140    class Register;
    4241   
    4342    class JSActivation : public JSVariableObject {
    4443    private:
    45         JSActivation(CallFrame*, FunctionExecutable*);
     44        JSActivation(JSGlobalData& globalData, CallFrame*, SharedSymbolTable*, size_t storageSize);
    4645   
    4746    public:
    4847        typedef JSVariableObject Base;
    4948
    50         static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* funcExec)
     49        static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* functionExecutable)
    5150        {
    52             JSActivation* activation = new (NotNull, allocateCell<JSActivation>(globalData.heap)) JSActivation(callFrame, funcExec);
    53             activation->finishCreation(callFrame, funcExec);
     51            size_t storageSize = JSActivation::storageSize(callFrame, functionExecutable->symbolTable());
     52            JSActivation* activation = new (
     53                NotNull,
     54                allocateCell<JSActivation>(
     55                    globalData.heap,
     56                    allocationSize(storageSize)
     57                )
     58            ) JSActivation(globalData, callFrame, functionExecutable->symbolTable(), storageSize);
     59            activation->finishCreation(globalData);
    5460            return activation;
    5561        }
     
    7682        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(ActivationObjectType, StructureFlags), &s_info); }
    7783
    78         bool isValidScopedLookup(int index) { return index < m_numCapturedVars; }
     84        bool isValid(const SymbolTableEntry&);
     85        bool isTornOff();
    7986
    8087    protected:
    81         void finishCreation(CallFrame*, FunctionExecutable*);
    8288        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
    8389
     
    9298        NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
    9399
    94         size_t registerOffset();
    95         size_t registerArraySize();
    96         size_t registerArraySizeInBytes();
    97 
    98         StorageBarrier m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file.
    99         int m_numCapturedArgs;
    100         int m_numCapturedVars : 30;
    101         bool m_isTornOff : 1;
    102         bool m_requiresDynamicChecks : 1;
    103         int m_argumentsRegister;
     100        static size_t allocationSize(size_t storageSize);
     101        static size_t storageSize(CallFrame*, SharedSymbolTable*);
     102        static int captureStart(CallFrame*, SharedSymbolTable*);
     103
     104        int registerOffset();
     105        size_t storageSize();
     106        WriteBarrier<Unknown>* storage(); // storageSize() number of registers.
    104107    };
     108
     109    extern int activationCount;
     110    extern int allTheThingsCount;
     111
     112    inline JSActivation::JSActivation(JSGlobalData& globalData, CallFrame* callFrame, SharedSymbolTable* symbolTable, size_t storageSize)
     113        : Base(
     114            globalData,
     115            callFrame->lexicalGlobalObject()->activationStructure(),
     116            callFrame->registers(),
     117            callFrame->scope(),
     118            symbolTable
     119        )
     120    {
     121        WriteBarrier<Unknown>* storage = this->storage();
     122        for (size_t i = 0; i < storageSize; ++i)
     123            new(&storage[i]) WriteBarrier<Unknown>;
     124    }
    105125
    106126    JSActivation* asActivation(JSValue);
     
    119139    inline bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
    120140    {
    121         requiresDynamicChecks = m_requiresDynamicChecks;
     141        requiresDynamicChecks = symbolTable()->usesNonStrictEval();
    122142        return false;
    123143    }
    124144
    125     inline size_t JSActivation::registerOffset()
    126     {
    127         if (!m_numCapturedArgs)
    128             return 0;
    129 
    130         size_t capturedArgumentCountIncludingThis = m_numCapturedArgs + 1;
    131         return CallFrame::offsetFor(capturedArgumentCountIncludingThis);
    132     }
    133 
    134     inline size_t JSActivation::registerArraySize()
    135     {
    136         return registerOffset() + m_numCapturedVars;
    137     }
    138 
    139     inline size_t JSActivation::registerArraySizeInBytes()
    140     {
    141         return registerArraySize() * sizeof(WriteBarrierBase<Unknown>);
     145    inline int JSActivation::captureStart(CallFrame* callFrame, SharedSymbolTable* symbolTable)
     146    {
     147        if (symbolTable->captureMode() == SharedSymbolTable::AllOfTheThings)
     148            return -CallFrame::offsetFor(std::max<size_t>(callFrame->argumentCountIncludingThis(), symbolTable->parameterCountIncludingThis()));
     149        return symbolTable->captureStart();
     150    }
     151
     152    inline size_t JSActivation::storageSize(CallFrame* callFrame, SharedSymbolTable* symbolTable)
     153    {
     154        return symbolTable->captureEnd() - captureStart(callFrame, symbolTable);
     155    }
     156
     157    inline int JSActivation::registerOffset()
     158    {
     159        return -captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
     160    }
     161
     162    inline size_t JSActivation::storageSize()
     163    {
     164        return storageSize(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable());
    142165    }
    143166
    144167    inline void JSActivation::tearOff(JSGlobalData& globalData)
    145168    {
    146         ASSERT(!m_registerArray);
    147         ASSERT(m_numCapturedVars + m_numCapturedArgs);
    148 
    149         void* allocation = 0;
    150         if (!globalData.heap.tryAllocateStorage(registerArraySizeInBytes(), &allocation))
    151             CRASH();
    152         PropertyStorage registerArray = static_cast<PropertyStorage>(allocation);
    153         PropertyStorage registers = registerArray + registerOffset();
    154 
    155         // arguments
    156         int from = CallFrame::argumentOffset(m_numCapturedArgs - 1);
    157         int to = CallFrame::thisArgumentOffset(); // Skip 'this' because it's not lexically accessible.
    158         for (int i = from; i < to; ++i)
    159             registers[i].set(globalData, this, m_registers[i].get());
    160 
    161         // vars
    162         from = 0;
    163         to = m_numCapturedVars;
    164         for (int i = from; i < to; ++i)
    165             registers[i].set(globalData, this, m_registers[i].get());
    166 
    167         m_registerArray.set(globalData, this, registerArray);
    168         m_registers = registers;
    169         m_isTornOff = true;
     169        ASSERT(!isTornOff());
     170
     171        int registerOffset = this->registerOffset();
     172        WriteBarrierBase<Unknown>* dst = storage() + registerOffset;
     173        WriteBarrierBase<Unknown>* src = m_registers;
     174
     175        if (symbolTable()->captureMode() == SharedSymbolTable::AllOfTheThings) {
     176            int from = -registerOffset;
     177            int to = CallFrame::thisArgumentOffset(); // Skip 'this' because it's not lexically accessible.
     178            for (int i = from; i < to; ++i)
     179                dst[i].set(globalData, this, src[i].get());
     180
     181            dst[RegisterFile::ArgumentCount].set(globalData, this, JSValue(
     182                CallFrame::create(reinterpret_cast<Register*>(src))->argumentCountIncludingThis()));
     183
     184            int captureEnd = symbolTable()->captureEnd();
     185            for (int i = 0; i < captureEnd; ++i)
     186                dst[i].set(globalData, this, src[i].get());
     187        } else {
     188            int captureEnd = symbolTable()->captureEnd();
     189            for (int i = symbolTable()->captureStart(); i < captureEnd; ++i)
     190                dst[i].set(globalData, this, src[i].get());
     191        }
     192
     193        m_registers = dst;
     194        ASSERT(isTornOff());
     195    }
     196
     197    inline bool JSActivation::isTornOff()
     198    {
     199        return m_registers == storage() + registerOffset();
     200    }
     201
     202    inline WriteBarrier<Unknown>* JSActivation::storage()
     203    {
     204        return reinterpret_cast<WriteBarrier<Unknown>*>(
     205            reinterpret_cast<char*>(this) +
     206                WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation))
     207        );
     208    }
     209
     210    inline size_t JSActivation::allocationSize(size_t storageSize)
     211    {
     212        size_t objectSizeInBytes = WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(JSActivation));
     213        size_t storageSizeInBytes = storageSize * sizeof(WriteBarrier<Unknown>);
     214        return objectSizeInBytes + storageSizeInBytes;
     215    }
     216
     217    inline bool JSActivation::isValid(const SymbolTableEntry& entry)
     218    {
     219        if (entry.getIndex() < captureStart(CallFrame::create(reinterpret_cast<Register*>(m_registers)), symbolTable()))
     220            return false;
     221        if (entry.getIndex() >= symbolTable()->captureEnd())
     222            return false;
     223        return true;
    170224    }
    171225
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r128146 r128260  
    6565        friend class MarkedBlock;
    6666        template<typename T> friend void* allocateCell(Heap&);
     67        template<typename T> friend void* allocateCell(Heap&, size_t);
    6768
    6869    public:
     
    338339    }
    339340   
     341    template<typename T>
     342    void* allocateCell(Heap& heap, size_t size)
     343    {
     344        ASSERT(size >= sizeof(T));
     345#if ENABLE(GC_VALIDATION)
     346        ASSERT(!heap.globalData()->isInitializingObject());
     347        heap.globalData()->setInitializingObjectClass(&T::s_info);
     348#endif
     349        JSCell* result = 0;
     350        if (NeedsDestructor<T>::value)
     351            result = static_cast<JSCell*>(heap.allocateWithDestructor(size));
     352        else {
     353            ASSERT(T::s_info.methodTable.destroy == JSCell::destroy);
     354            result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
     355        }
     356        result->clearStructure();
     357        return result;
     358    }
     359   
    340360    inline bool isZapped(const JSCell* cell)
    341361    {
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r127505 r128260  
    2828#include "CallFrame.h"
    2929#include "Interpreter.h"
     30#include "JSFunction.h"
    3031#include "JSGlobalObject.h"
    3132#include "JSString.h"
  • trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h

    r127363 r128260  
    5050    static const unsigned StructureFlags = IsEnvironmentRecord | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags;
    5151   
    52     JSSymbolTableObject(JSGlobalData& globalData, Structure* structure, JSScope* scope)
     52    JSSymbolTableObject(JSGlobalData& globalData, Structure* structure, JSScope* scope, SharedSymbolTable* symbolTable = 0)
    5353        : Base(globalData, structure, scope)
    5454    {
     55        if (symbolTable)
     56            m_symbolTable.set(globalData, this, symbolTable);
    5557    }
    5658
    57     void finishCreation(JSGlobalData& globalData, SharedSymbolTable* symbolTable = 0)
     59    void finishCreation(JSGlobalData& globalData)
    5860    {
    5961        Base::finishCreation(globalData);
    60         if (!symbolTable)
    61             symbolTable = SharedSymbolTable::create(globalData);
    62         m_symbolTable.set(globalData, this, symbolTable);
     62        if (!m_symbolTable)
     63            m_symbolTable.set(globalData, this, SharedSymbolTable::create(globalData));
    6364    }
    6465
  • trunk/Source/JavaScriptCore/runtime/JSVariableObject.h

    r127363 r128260  
    6161            Structure* structure,
    6262            Register* registers,
    63             JSScope* scope
     63            JSScope* scope,
     64            SharedSymbolTable* symbolTable = 0
    6465        )
    65             : Base(globalData, structure, scope)
     66            : Base(globalData, structure, scope, symbolTable)
    6667            , m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers))
    6768        {
    68         }
    69 
    70         void finishCreation(JSGlobalData& globalData, SharedSymbolTable* symbolTable = 0)
    71         {
    72             Base::finishCreation(globalData, symbolTable);
    73             COMPILE_ASSERT(sizeof(WriteBarrierBase<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrierBase);
    7469        }
    7570
  • trunk/Source/JavaScriptCore/runtime/SymbolTable.h

    r127191 r128260  
    341341        }
    342342
     343        bool usesNonStrictEval() { return m_usesNonStrictEval; }
     344        void setUsesNonStrictEval(bool usesNonStrictEval) { m_usesNonStrictEval = usesNonStrictEval; }
     345
     346        enum CaptureMode {
     347            SomeOfTheThings,
     348            AllOfTheThings
     349        };
     350
     351        CaptureMode captureMode() { return m_captureMode; }
     352        void setCaptureMode(CaptureMode captureMode) { m_captureMode = captureMode; }
     353
     354        int captureStart() { return m_captureStart; }
     355        void setCaptureStart(int captureStart) { m_captureStart = captureStart; }
     356
     357        int captureEnd() { return m_captureEnd; }
     358        void setCaptureEnd(int captureEnd) { m_captureEnd = captureEnd; }
     359
     360        int parameterCountIncludingThis() { return m_parameterCountIncludingThis; }
     361        void setParameterCountIncludingThis(int parameterCountIncludingThis) { m_parameterCountIncludingThis = parameterCountIncludingThis; }
     362
    343363        static JS_EXPORTDATA const ClassInfo s_info;
    344364
     
    346366        SharedSymbolTable(JSGlobalData& globalData)
    347367            : JSCell(globalData, globalData.sharedSymbolTableStructure.get())
    348         {
    349         }
     368            , m_parameterCountIncludingThis(0)
     369            , m_usesNonStrictEval(false)
     370            , m_captureMode(SomeOfTheThings)
     371            , m_captureStart(0)
     372            , m_captureEnd(0)
     373        {
     374        }
     375
     376        int m_parameterCountIncludingThis;
     377        bool m_usesNonStrictEval;
     378
     379        CaptureMode m_captureMode;
     380        int m_captureStart;
     381        int m_captureEnd;
    350382    };
    351383   
Note: See TracChangeset for help on using the changeset viewer.