summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/interpreter
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-24 11:24:40 +0100
committerBen Murdoch <benm@google.com>2011-06-02 09:53:15 +0100
commit81bc750723a18f21cd17d1b173cd2a4dda9cea6e (patch)
tree7a9e5ed86ff429fd347a25153107221543909b19 /Source/JavaScriptCore/interpreter
parent94088a6d336c1dd80a1e734af51e96abcbb689a7 (diff)
downloadexternal_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.zip
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.gz
external_webkit-81bc750723a18f21cd17d1b173cd2a4dda9cea6e.tar.bz2
Merge WebKit at r80534: Intial merge by Git
Change-Id: Ia7a83357124c9e1cdb1debf55d9661ec0bd09a61
Diffstat (limited to 'Source/JavaScriptCore/interpreter')
-rw-r--r--Source/JavaScriptCore/interpreter/CachedCall.h4
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.h19
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp101
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h2
-rw-r--r--Source/JavaScriptCore/interpreter/RegisterFile.cpp20
-rw-r--r--Source/JavaScriptCore/interpreter/RegisterFile.h9
6 files changed, 74 insertions, 81 deletions
diff --git a/Source/JavaScriptCore/interpreter/CachedCall.h b/Source/JavaScriptCore/interpreter/CachedCall.h
index 740001d..05e9056 100644
--- a/Source/JavaScriptCore/interpreter/CachedCall.h
+++ b/Source/JavaScriptCore/interpreter/CachedCall.h
@@ -38,10 +38,10 @@ namespace JSC {
CachedCall(CallFrame* callFrame, JSFunction* function, int argCount)
: m_valid(false)
, m_interpreter(callFrame->interpreter())
- , m_globalObjectScope(callFrame, function->scope().globalObject())
+ , m_globalObjectScope(callFrame, function->scope()->globalObject.get())
{
ASSERT(!function->isHostFunction());
- m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argCount, function->scope().node());
+ m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, function, argCount, function->scope());
m_valid = !callFrame->hadException();
}
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index 190a7c1..e73e13a 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -26,13 +26,13 @@
#include "JSGlobalData.h"
#include "MacroAssemblerCodeRef.h"
#include "RegisterFile.h"
-#include "ScopeChain.h"
namespace JSC {
class Arguments;
class JSActivation;
class Interpreter;
+ class ScopeChainNode;
// Represents the current state of script execution.
// Passed as the first argument to most functions.
@@ -51,23 +51,13 @@ namespace JSC {
// Global object in which the currently executing code was defined.
// Differs from dynamicGlobalObject() during function calls across web browser frames.
- JSGlobalObject* lexicalGlobalObject() const
- {
- return scopeChain()->globalObject;
- }
+ inline JSGlobalObject* lexicalGlobalObject() const;
// Differs from lexicalGlobalObject because this will have DOM window shell rather than
// the actual DOM window, which can't be "this" for security reasons.
- JSObject* globalThisValue() const
- {
- return scopeChain()->globalThis;
- }
+ inline JSObject* globalThisValue() const;
- JSGlobalData& globalData() const
- {
- ASSERT(scopeChain()->globalData);
- return *scopeChain()->globalData;
- }
+ inline JSGlobalData& globalData() const;
// Convenience functions for access to global data.
// It takes a few memory references to get from a call frame to the global data
@@ -90,6 +80,7 @@ namespace JSC {
static const HashTable* jsonTable(CallFrame* callFrame) { return callFrame->globalData().jsonTable; }
static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; }
static const HashTable* numberTable(CallFrame* callFrame) { return callFrame->globalData().numberTable; }
+ static const HashTable* objectConstructorTable(CallFrame* callFrame) { return callFrame->globalData().objectConstructorTable; }
static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index c2612ac..b9a9c40 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -42,7 +42,6 @@
#include "EvalCodeCache.h"
#include "ExceptionHelpers.h"
#include "GetterSetter.h"
-#include "GlobalEvalFunction.h"
#include "JSActivation.h"
#include "JSArray.h"
#include "JSByteArray.h"
@@ -77,11 +76,11 @@ using namespace std;
namespace JSC {
// Returns the depth of the scope chain within a given call frame.
-static int depth(CodeBlock* codeBlock, ScopeChain& sc)
+static int depth(CodeBlock* codeBlock, ScopeChainNode* sc)
{
if (!codeBlock->needsFullScopeChain())
return 0;
- return sc.localDepth();
+ return sc->localDepth();
}
#if ENABLE(INTERPRETER)
@@ -419,9 +418,10 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
return callFrame->globalData().interpreter->execute(eval.get(), callFrame, callFrame->uncheckedR(codeBlock->thisRegister()).jsValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain);
}
-Interpreter::Interpreter()
+Interpreter::Interpreter(JSGlobalData& globalData)
: m_sampleEntryDepth(0)
, m_reentryDepth(0)
+ , m_registerFile(globalData)
{
#if ENABLE(COMPUTED_GOTO_INTERPRETER)
privateExecute(InitializeAndReturn, 0, 0);
@@ -564,24 +564,21 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
oldCodeBlock->createActivation(callFrame);
scopeChain = callFrame->scopeChain();
}
- while (!scopeChain->object->inherits(&JSActivation::info))
+ while (!scopeChain->object->inherits(&JSActivation::s_info))
scopeChain = scopeChain->pop();
callFrame->setScopeChain(scopeChain);
JSActivation* activation = asActivation(scopeChain->object.get());
- activation->copyRegisters();
+ activation->copyRegisters(*scopeChain->globalData);
if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
if (!oldCodeBlock->isStrictMode())
asArguments(arguments)->setActivation(callFrame->globalData(), activation);
}
} else if (oldCodeBlock->usesArguments() && !oldCodeBlock->isStrictMode()) {
if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue())
- asArguments(arguments)->copyRegisters();
+ asArguments(arguments)->copyRegisters(callFrame->globalData());
}
- if (oldCodeBlock->needsFullScopeChain())
- scopeChain->deref();
-
CallFrame* callerFrame = callFrame->callerFrame();
if (callerFrame->hasHostCallFrameFlag())
return false;
@@ -645,7 +642,7 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
start++;
while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
stop++;
- while (stop > expressionStart && isStrWhiteSpace(data[stop]))
+ while (stop > expressionStart && isStrWhiteSpace(data[stop - 1]))
stop--;
message = makeUString(message, " (near '...", codeBlock->source()->getRange(start, stop), "...')");
}
@@ -710,11 +707,10 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
// Unwind the scope chain within the exception handler's call frame.
ScopeChainNode* scopeChain = callFrame->scopeChain();
- ScopeChain sc(scopeChain);
int scopeDelta = 0;
if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode
|| callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
- scopeDelta = depth(codeBlock, sc) - handler->scopeDepth;
+ scopeDelta = depth(codeBlock, scopeChain) - handler->scopeDepth;
ASSERT(scopeDelta >= 0);
while (scopeDelta--)
scopeChain = scopeChain->pop();
@@ -761,10 +757,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), codeBlock->m_numParameters, 0);
newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj);
- if (codeBlock->needsFullScopeChain())
- scopeChain->ref();
-
- DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject.get());
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
@@ -835,7 +828,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
newCallFrame->init(newCodeBlock, 0, callDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, callDataScopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(newCallFrame, callDataScopeChain->globalObject.get());
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
@@ -867,7 +860,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset);
newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, function);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject.get());
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
@@ -924,7 +917,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
newCallFrame->init(newCodeBlock, 0, constructDataScopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, constructDataScopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(newCallFrame, constructDataScopeChain->globalObject.get());
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
@@ -959,7 +952,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
newCallFrame = CallFrame::create(newCallFrame->registers() + registerOffset);
newCallFrame->init(0, 0, scopeChain, callFrame->addHostCallFrameFlag(), argCount, constructor);
- DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(newCallFrame, scopeChain->globalObject.get());
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
@@ -1076,7 +1069,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
return checkedReturn(throwStackOverflowError(callFrame));
- DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
+ DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject.get());
JSObject* compileError = eval->compile(callFrame, scopeChain);
if (UNLIKELY(!!compileError))
@@ -1084,7 +1077,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
EvalCodeBlock* codeBlock = &eval->generatedBytecode();
JSObject* variableObject;
- for (ScopeChainNode* node = scopeChain; ; node = node->next) {
+ for (ScopeChainNode* node = scopeChain; ; node = node->next.get()) {
ASSERT(node);
if (node->object->isVariableObject()) {
variableObject = static_cast<JSVariableObject*>(node->object.get());
@@ -1133,9 +1126,6 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), codeBlock->m_numParameters, 0);
newCallFrame->uncheckedR(newCallFrame->hostThisRegister()) = JSValue(thisObj);
- if (codeBlock->needsFullScopeChain())
- scopeChain->ref();
-
Profiler** profiler = Profiler::enabledProfilerReference();
if (*profiler)
(*profiler)->willExecute(callFrame, eval->sourceURL(), eval->lineNo());
@@ -2366,7 +2356,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT(scope->isGlobalObject());
int index = vPC[2].u.operand;
- callFrame->uncheckedR(dst) = scope->registerAt(index);
+ callFrame->uncheckedR(dst) = scope->registerAt(index).get();
vPC += OPCODE_LENGTH(op_get_global_var);
NEXT_INSTRUCTION();
}
@@ -2380,7 +2370,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
int index = vPC[1].u.operand;
int value = vPC[2].u.operand;
- scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
+ scope->registerAt(index).set(*globalData, scope, callFrame->r(value).jsValue());
vPC += OPCODE_LENGTH(op_put_global_var);
NEXT_INSTRUCTION();
}
@@ -2411,7 +2401,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
}
ASSERT((*iter)->isVariableObject());
JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get());
- callFrame->uncheckedR(dst) = scope->registerAt(index);
+ callFrame->uncheckedR(dst) = scope->registerAt(index).get();
ASSERT(callFrame->r(dst).jsValue());
vPC += OPCODE_LENGTH(op_get_scoped_var);
NEXT_INSTRUCTION();
@@ -2443,19 +2433,21 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
ASSERT((*iter)->isVariableObject());
JSVariableObject* scope = static_cast<JSVariableObject*>(iter->get());
ASSERT(callFrame->r(value).jsValue());
- scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
+ scope->registerAt(index).set(*globalData, scope, callFrame->r(value).jsValue());
vPC += OPCODE_LENGTH(op_put_scoped_var);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_resolve_base) {
- /* resolve_base dst(r) property(id)
+ /* resolve_base dst(r) property(id) isStrict(bool)
Searches the scope chain for an object containing
identifier property, and if one is found, writes it to
- register dst. If none is found, the outermost scope (which
- will be the global object) is stored in register dst.
+ register dst. If none is found and isStrict is false, the
+ outermost scope (which will be the global object) is
+ stored in register dst.
*/
resolveBase(callFrame, vPC);
+ CHECK_FOR_EXCEPTION();
vPC += OPCODE_LENGTH(op_resolve_base);
NEXT_INSTRUCTION();
@@ -2476,6 +2468,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
exceptionValue = createErrorForInvalidGlobalAssignment(callFrame, ident.ustring());
goto vm_throw;
}
+
+ vPC += OPCODE_LENGTH(op_ensure_property_exists);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_resolve_with_base) {
@@ -3803,7 +3797,7 @@ skip_id_custom_self:
*/
if (!function->name().isNull()) {
JSStaticScopeObject* functionScopeObject = new (callFrame) JSStaticScopeObject(callFrame, function->name(), func, ReadOnly | DontDelete);
- func->scope().push(functionScopeObject);
+ func->setScope(*globalData, func->scope()->push(functionScopeObject));
}
callFrame->uncheckedR(dst) = JSValue(func);
@@ -3833,7 +3827,7 @@ skip_id_custom_self:
Register* newCallFrame = callFrame->registers() + registerOffset;
Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
JSValue thisValue = argv[0].jsValue();
- JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject;
+ JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject.get();
if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset);
@@ -3959,7 +3953,7 @@ skip_id_custom_self:
exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments);
goto vm_throw;
}
- if (asObject(arguments)->classInfo() == &Arguments::info) {
+ if (asObject(arguments)->classInfo() == &Arguments::s_info) {
Arguments* args = asArguments(arguments);
argCount = args->numProvidedArguments(callFrame);
argCount = min<uint32_t>(argCount, Arguments::MaxArguments);
@@ -3981,7 +3975,7 @@ skip_id_custom_self:
goto vm_throw;
}
array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
- } else if (asObject(arguments)->inherits(&JSArray::info)) {
+ } else if (asObject(arguments)->inherits(&JSArray::s_info)) {
JSObject* argObject = asObject(arguments);
argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
argCount = min<uint32_t>(argCount, Arguments::MaxArguments);
@@ -4101,7 +4095,7 @@ skip_id_custom_self:
ASSERT(codeBlock->needsFullScopeChain());
JSValue activationValue = callFrame->r(activation).jsValue();
if (activationValue) {
- asActivation(activationValue)->copyRegisters();
+ asActivation(activationValue)->copyRegisters(*globalData);
if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
if (!codeBlock->isStrictMode())
@@ -4109,7 +4103,7 @@ skip_id_custom_self:
}
} else if (JSValue argumentsValue = callFrame->r(unmodifiedArgumentsRegister(arguments)).jsValue()) {
if (!codeBlock->isStrictMode())
- asArguments(argumentsValue)->copyRegisters();
+ asArguments(argumentsValue)->copyRegisters(*globalData);
}
vPC += OPCODE_LENGTH(op_tear_off_activation);
@@ -4131,7 +4125,7 @@ skip_id_custom_self:
ASSERT(!codeBlock->needsFullScopeChain() && codeBlock->ownerExecutable()->usesArguments());
if (JSValue arguments = callFrame->r(unmodifiedArgumentsRegister(src1)).jsValue())
- asArguments(arguments)->copyRegisters();
+ asArguments(arguments)->copyRegisters(*globalData);
vPC += OPCODE_LENGTH(op_tear_off_arguments);
NEXT_INSTRUCTION();
@@ -4148,9 +4142,6 @@ skip_id_custom_self:
int result = vPC[1].u.operand;
- if (callFrame->codeBlock()->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue())
- callFrame->scopeChain()->deref();
-
JSValue returnValue = callFrame->r(result).jsValue();
vPC = callFrame->returnVPC();
@@ -4189,9 +4180,6 @@ skip_id_custom_self:
int result = vPC[1].u.operand;
- if (codeBlock->needsFullScopeChain() && callFrame->r(codeBlock->activationRegister()).jsValue())
- callFrame->scopeChain()->deref();
-
JSValue returnValue = callFrame->r(result).jsValue();
if (UNLIKELY(!returnValue.isObject()))
@@ -4236,7 +4224,7 @@ skip_id_custom_self:
if (!callFrame->r(activationReg).jsValue()) {
JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionExecutable*>(codeBlock->ownerExecutable()));
callFrame->r(activationReg) = JSValue(activation);
- callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
+ callFrame->setScopeChain(callFrame->scopeChain()->push(activation));
}
vPC += OPCODE_LENGTH(op_create_activation);
NEXT_INSTRUCTION();
@@ -4275,8 +4263,8 @@ skip_id_custom_self:
if (proto.isObject())
structure = asObject(proto)->inheritorID();
else
- structure = constructor->scope().node()->globalObject->emptyObjectStructure();
- callFrame->uncheckedR(thisRegister) = JSValue(new (&callFrame->globalData()) JSObject(structure));
+ structure = constructor->scope()->globalObject->emptyObjectStructure();
+ callFrame->uncheckedR(thisRegister) = constructEmptyObject(callFrame, structure);
vPC += OPCODE_LENGTH(op_create_this);
NEXT_INSTRUCTION();
@@ -4641,11 +4629,6 @@ skip_id_custom_self:
program. Return control to the calling native code.
*/
- if (codeBlock->needsFullScopeChain()) {
- ScopeChainNode* scopeChain = callFrame->scopeChain();
- ASSERT(scopeChain->refCount > 1);
- scopeChain->deref();
- }
int result = vPC[1].u.operand;
return callFrame->r(result).jsValue();
}
@@ -4775,9 +4758,13 @@ skip_id_custom_self:
// cannot fathom if we don't assign to the exceptionValue before branching)
exceptionValue = createInterruptedExecutionException(globalData);
}
+ JSGlobalObject* globalObject = callFrame->lexicalGlobalObject();
handler = throwException(callFrame, exceptionValue, vPC - codeBlock->instructions().begin());
- if (!handler)
- return throwError(callFrame, exceptionValue);
+ if (!handler) {
+ // Can't use the callframe at this point as the scopechain, etc have
+ // been released.
+ return throwError(globalObject->globalExec(), exceptionValue);
+ }
codeBlock = callFrame->codeBlock();
vPC = codeBlock->instructions().begin() + handler->target;
@@ -4814,7 +4801,7 @@ JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* functio
}
Arguments* arguments = new (functionCallFrame) Arguments(functionCallFrame);
- arguments->copyRegisters();
+ arguments->copyRegisters(functionCallFrame->globalData());
return arguments;
}
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index 753d90e..8f29f60 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -69,7 +69,7 @@ namespace JSC {
friend class JIT;
friend class CachedCall;
public:
- Interpreter();
+ Interpreter(JSGlobalData&);
RegisterFile& registerFile() { return m_registerFile; }
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.cpp b/Source/JavaScriptCore/interpreter/RegisterFile.cpp
index 4c37676..47f0c18 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.cpp
+++ b/Source/JavaScriptCore/interpreter/RegisterFile.cpp
@@ -29,6 +29,8 @@
#include "config.h"
#include "RegisterFile.h"
+#include "Interpreter.h"
+#include "JSGlobalData.h"
#include "JSGlobalObject.h"
namespace JSC {
@@ -59,12 +61,24 @@ void RegisterFile::releaseExcessCapacity()
void RegisterFile::setGlobalObject(JSGlobalObject* globalObject)
{
- m_globalObject = globalObject;
+ m_globalObject.set(globalObject->globalData(), globalObject, RegisterFile::globalObjectCollectedNotifier());
}
-bool RegisterFile::clearGlobalObject(JSGlobalObject* globalObject)
+class GlobalObjectNotifier : public Finalizer {
+public:
+ void finalize(Handle<Unknown> value, void*)
+ {
+ JSGlobalObject* globalObject = asGlobalObject(value.get());
+ globalObject->globalData().interpreter->registerFile().setNumGlobals(0);
+ }
+};
+
+Finalizer* RegisterFile::globalObjectCollectedNotifier()
{
- return m_globalObject.clear(globalObject);
+ // This will leak alas, but we only create one of them, and it doesn't
+ // take up any significant amount of space.
+ static GlobalObjectNotifier* notifier = new GlobalObjectNotifier;
+ return notifier;
}
JSGlobalObject* RegisterFile::globalObject()
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.h b/Source/JavaScriptCore/interpreter/RegisterFile.h
index e9c6df1..bb42902 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.h
+++ b/Source/JavaScriptCore/interpreter/RegisterFile.h
@@ -112,7 +112,7 @@ namespace JSC {
// Allow 8k of excess registers before we start trying to reap the registerfile
static const ptrdiff_t maxExcessCapacity = 8 * 1024;
- RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals);
+ RegisterFile(JSGlobalData&, size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals);
~RegisterFile();
Register* start() const { return m_start; }
@@ -120,7 +120,6 @@ namespace JSC {
size_t size() const { return m_end - m_start; }
void setGlobalObject(JSGlobalObject*);
- bool clearGlobalObject(JSGlobalObject*);
JSGlobalObject* globalObject();
bool grow(Register* newEnd);
@@ -135,6 +134,8 @@ namespace JSC {
static size_t committedByteCount();
static void initializeThreading();
+ static Finalizer* globalObjectCollectedNotifier();
+
private:
void releaseExcessCapacity();
void addToCommittedByteCount(long);
@@ -150,16 +151,16 @@ namespace JSC {
WeakGCPtr<JSGlobalObject> m_globalObject; // The global object whose vars are currently stored in the register file.
};
- inline RegisterFile::RegisterFile(size_t capacity, size_t maxGlobals)
+ inline RegisterFile::RegisterFile(JSGlobalData& globalData, size_t capacity, size_t maxGlobals)
: m_numGlobals(0)
, m_maxGlobals(maxGlobals)
, m_start(0)
, m_end(0)
, m_max(0)
+ , m_globalObject(globalData, RegisterFile::globalObjectCollectedNotifier())
{
ASSERT(maxGlobals && isPageAligned(maxGlobals));
ASSERT(capacity && isPageAligned(capacity));
-
size_t bufferLength = (capacity + maxGlobals) * sizeof(Register);
m_reservation = PageReservation::reserve(roundUpAllocationSize(bufferLength, commitSize), OSAllocator::JSVMStackPages);
void* base = m_reservation.base();