Commit 7b941609 authored by ggaren@apple.com's avatar ggaren@apple.com

2011-03-24 Geoffrey Garen <ggaren@apple.com>

        Reviewed by Oliver Hunt.

        Crash in debugger beneath MarkStack::drain @ me.com, ibm.com
        https://bugs.webkit.org/show_bug.cgi?id=57080
        <rdar://problem/8525907>

        The crash was caused by changes in the executable after recompilation.

        The fix is for the activation to copy the data it needs instead of
        relying on the data in the executable.
        
        SunSpider and v8 report no change.

        * runtime/Arguments.h:
        (JSC::JSActivation::copyRegisters): Use our own data members instead of
        reading data out of the executable.

        * runtime/JSActivation.cpp:
        (JSC::JSActivation::JSActivation): Initialize our data members.

        (JSC::JSActivation::markChildren):
        (JSC::JSActivation::symbolTableGet):
        (JSC::JSActivation::symbolTablePut):
        (JSC::JSActivation::getOwnPropertyNames):
        (JSC::JSActivation::symbolTablePutWithAttributes):
        (JSC::JSActivation::isDynamicScope):
        (JSC::JSActivation::argumentsGetter): Use our own data members instead of
        reading data out of the executable.

        * runtime/JSActivation.h: Added new data members to track data previously
        tracked by the executable. Since I've removed the executable pointer,
        on a 64bit system, I've only made activations bigger by an int.


git-svn-id: svn://svn.chromium.org/blink/trunk@81983 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 09a5b8d5
2011-03-24 Geoffrey Garen <ggaren@apple.com>
Reviewed by Oliver Hunt.
Crash in debugger beneath MarkStack::drain @ me.com, ibm.com
https://bugs.webkit.org/show_bug.cgi?id=57080
<rdar://problem/8525907>
The crash was caused by changes in the executable after recompilation.
The fix is for the activation to copy the data it needs instead of
relying on the data in the executable.
SunSpider and v8 report no change.
* runtime/Arguments.h:
(JSC::JSActivation::copyRegisters): Use our own data members instead of
reading data out of the executable.
* runtime/JSActivation.cpp:
(JSC::JSActivation::JSActivation): Initialize our data members.
(JSC::JSActivation::markChildren):
(JSC::JSActivation::symbolTableGet):
(JSC::JSActivation::symbolTablePut):
(JSC::JSActivation::getOwnPropertyNames):
(JSC::JSActivation::symbolTablePutWithAttributes):
(JSC::JSActivation::isDynamicScope):
(JSC::JSActivation::argumentsGetter): Use our own data members instead of
reading data out of the executable.
* runtime/JSActivation.h: Added new data members to track data previously
tracked by the executable. Since I've removed the executable pointer,
on a 64bit system, I've only made activations bigger by an int.
2011-03-25 David Kilzer <ddkilzer@apple.com>
Remove duplicate entry from JavaScriptCore.exp
......
......@@ -239,14 +239,12 @@ namespace JSC {
{
ASSERT(!m_registerArray);
size_t numParametersMinusThis = m_functionExecutable->parameterCount();
size_t numVars = m_functionExecutable->capturedVariableCount();
size_t numLocals = numVars + numParametersMinusThis;
size_t numLocals = m_numCapturedVars + m_numParametersMinusThis;
if (!numLocals)
return;
int registerOffset = numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
int registerOffset = m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize;
size_t registerArraySize = numLocals + RegisterFile::CallFrameHeaderSize;
OwnArrayPtr<WriteBarrier<Unknown> > registerArray = copyRegisterArray(globalData, m_registers - registerOffset, registerArraySize);
......
......@@ -41,7 +41,10 @@ const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0 };
JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExecutable)
: Base(callFrame->globalData().activationStructure, functionExecutable->symbolTable(), callFrame->registers())
, m_functionExecutable(callFrame->globalData(), this, functionExecutable)
, m_numParametersMinusThis(static_cast<int>(functionExecutable->parameterCount()))
, m_numCapturedVars(functionExecutable->capturedVariableCount())
, m_requiresDynamicChecks(functionExecutable->usesEval())
, m_argumentsRegister(functionExecutable->generatedBytecode().argumentsRegister())
{
ASSERT(inherits(&s_info));
......@@ -58,29 +61,23 @@ JSActivation::~JSActivation()
void JSActivation::markChildren(MarkStack& markStack)
{
Base::markChildren(markStack);
markStack.append(&m_functionExecutable);
// No need to mark our registers if they're still in the RegisterFile.
WriteBarrier<Unknown>* registerArray = m_registerArray.get();
if (!registerArray)
return;
size_t numParametersMinusThis = m_functionExecutable->parameterCount();
size_t count = numParametersMinusThis;
markStack.appendValues(registerArray, count);
size_t numVars = m_functionExecutable->capturedVariableCount();
markStack.appendValues(registerArray, m_numParametersMinusThis);
// Skip the call frame, which sits between the parameters and vars.
markStack.appendValues(registerArray + count + RegisterFile::CallFrameHeaderSize, numVars, MayContainNullValues);
markStack.appendValues(registerArray + m_numParametersMinusThis + RegisterFile::CallFrameHeaderSize, m_numCapturedVars, MayContainNullValues);
}
inline bool JSActivation::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
{
SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
if (!entry.isNull()) {
ASSERT(entry.getIndex() < static_cast<int>(m_functionExecutable->capturedVariableCount()));
ASSERT(entry.getIndex() < m_numCapturedVars);
slot.setValue(registerAt(entry.getIndex()).get());
return true;
}
......@@ -96,7 +93,7 @@ inline bool JSActivation::symbolTablePut(JSGlobalData& globalData, const Identif
return false;
if (entry.isReadOnly())
return true;
ASSERT(entry.getIndex() < static_cast<int>(m_functionExecutable->capturedVariableCount()));
ASSERT(entry.getIndex() < m_numCapturedVars);
registerAt(entry.getIndex()).set(globalData, this, value);
return true;
}
......@@ -105,7 +102,7 @@ void JSActivation::getOwnPropertyNames(ExecState* exec, PropertyNameArray& prope
{
SymbolTable::const_iterator end = symbolTable().end();
for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
ASSERT(it->second.getIndex() < static_cast<int>(m_functionExecutable->capturedVariableCount()));
ASSERT(it->second.getIndex() < m_numCapturedVars);
if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties))
propertyNames.add(Identifier(exec, it->first.get()));
}
......@@ -122,7 +119,7 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData,
return false;
SymbolTableEntry& entry = iter->second;
ASSERT(!entry.isNull());
if (entry.getIndex() >= static_cast<int>(m_functionExecutable->capturedVariableCount()))
if (entry.getIndex() >= m_numCapturedVars)
return false;
entry.setAttributes(attributes);
registerAt(entry.getIndex()).set(globalData, this, value);
......@@ -201,7 +198,7 @@ JSValue JSActivation::toStrictThisObject(ExecState*) const
bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
{
requiresDynamicChecks = m_functionExecutable->usesEval();
requiresDynamicChecks = m_requiresDynamicChecks;
return false;
}
......@@ -209,7 +206,7 @@ JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, const Identi
{
JSActivation* activation = asActivation(slotBase);
CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(activation->m_registers));
int argumentsRegister = activation->m_functionExecutable->generatedBytecode().argumentsRegister();
int argumentsRegister = activation->m_argumentsRegister;
if (JSValue arguments = callFrame->uncheckedR(argumentsRegister).jsValue())
return arguments;
int realArgumentsRegister = unmodifiedArgumentsRegister(argumentsRegister);
......
......@@ -81,7 +81,10 @@ namespace JSC {
static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
WriteBarrier<FunctionExecutable> m_functionExecutable;
int m_numParametersMinusThis;
int m_numCapturedVars : 31;
bool m_requiresDynamicChecks : 1;
int m_argumentsRegister;
};
JSActivation* asActivation(JSValue);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment