summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/interpreter')
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.cpp4
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.h65
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrameClosure.h6
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp127
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h16
-rw-r--r--Source/JavaScriptCore/interpreter/JSStack.cpp (renamed from Source/JavaScriptCore/interpreter/RegisterFile.cpp)26
-rw-r--r--Source/JavaScriptCore/interpreter/JSStack.h (renamed from Source/JavaScriptCore/interpreter/RegisterFile.h)24
-rw-r--r--Source/JavaScriptCore/interpreter/VMInspector.cpp32
8 files changed, 162 insertions, 138 deletions
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.cpp b/Source/JavaScriptCore/interpreter/CallFrame.cpp
index 63bc93aeb..6dcf354b3 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.cpp
+++ b/Source/JavaScriptCore/interpreter/CallFrame.cpp
@@ -43,9 +43,9 @@ void CallFrame::dumpCaller()
dataLog("Callpoint => %s:%d\n", urlString.utf8().data(), signedLineNumber);
}
-RegisterFile* CallFrame::registerFile()
+JSStack* CallFrame::stack()
{
- return &interpreter()->registerFile();
+ return &interpreter()->stack();
}
#endif
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index 4758e5bd0..7aa49a9b0 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -25,8 +25,8 @@
#include "AbstractPC.h"
#include "JSGlobalData.h"
+#include "JSStack.h"
#include "MacroAssemblerCodeRef.h"
-#include "RegisterFile.h"
namespace JSC {
@@ -39,13 +39,13 @@ namespace JSC {
// Passed as the first argument to most functions.
class ExecState : private Register {
public:
- JSValue calleeAsValue() const { return this[RegisterFile::Callee].jsValue(); }
- JSObject* callee() const { return this[RegisterFile::Callee].function(); }
- CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
+ JSValue calleeAsValue() const { return this[JSStack::Callee].jsValue(); }
+ JSObject* callee() const { return this[JSStack::Callee].function(); }
+ CodeBlock* codeBlock() const { return this[JSStack::CodeBlock].Register::codeBlock(); }
JSScope* scope() const
{
- ASSERT(this[RegisterFile::ScopeChain].Register::scope());
- return this[RegisterFile::ScopeChain].Register::scope();
+ ASSERT(this[JSStack::ScopeChain].Register::scope());
+ return this[JSStack::ScopeChain].Register::scope();
}
// Global object in which execution began.
@@ -102,11 +102,11 @@ namespace JSC {
CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
- CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
+ CallFrame* callerFrame() const { return this[JSStack::CallerFrame].callFrame(); }
#if ENABLE(JIT) || ENABLE(LLINT)
- ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); }
- bool hasReturnPC() const { return !!this[RegisterFile::ReturnPC].vPC(); }
- void clearReturnPC() { registers()[RegisterFile::ReturnPC] = static_cast<Instruction*>(0); }
+ ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[JSStack::ReturnPC].vPC()); }
+ bool hasReturnPC() const { return !!this[JSStack::ReturnPC].vPC(); }
+ void clearReturnPC() { registers()[JSStack::ReturnPC] = static_cast<Instruction*>(0); }
#endif
AbstractPC abstractReturnPC(JSGlobalData& globalData) { return AbstractPC(globalData, this); }
#if USE(JSVALUE32_64)
@@ -116,13 +116,13 @@ namespace JSC {
unsigned bytecodeOffsetForNonDFGCode() const
{
ASSERT(codeBlock());
- return this[RegisterFile::ArgumentCount].tag();
+ return this[JSStack::ArgumentCount].tag();
}
void setBytecodeOffsetForNonDFGCode(unsigned offset)
{
ASSERT(codeBlock());
- this[RegisterFile::ArgumentCount].tag() = static_cast<int32_t>(offset);
+ this[JSStack::ArgumentCount].tag() = static_cast<int32_t>(offset);
}
#endif
@@ -136,8 +136,8 @@ namespace JSC {
Register* frameExtentInternal();
#if ENABLE(DFG_JIT)
- InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].asInlineCallFrame(); }
- unsigned codeOriginIndexForDFG() const { return this[RegisterFile::ArgumentCount].tag(); }
+ InlineCallFrame* inlineCallFrame() const { return this[JSStack::ReturnPC].asInlineCallFrame(); }
+ unsigned codeOriginIndexForDFG() const { return this[JSStack::ArgumentCount].tag(); }
#else
// This will never be called if !ENABLE(DFG_JIT) since all calls should be guarded by
// isInlineCallFrame(). But to make it easier to write code without having a bunch of
@@ -151,25 +151,25 @@ namespace JSC {
#if USE(JSVALUE32_64)
Instruction* currentVPC() const
{
- return bitwise_cast<Instruction*>(this[RegisterFile::ArgumentCount].tag());
+ return bitwise_cast<Instruction*>(this[JSStack::ArgumentCount].tag());
}
void setCurrentVPC(Instruction* vpc)
{
- this[RegisterFile::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc);
+ this[JSStack::ArgumentCount].tag() = bitwise_cast<int32_t>(vpc);
}
#else
Instruction* currentVPC() const;
void setCurrentVPC(Instruction* vpc);
#endif
- void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
- void setScope(JSScope* scope) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scope; }
+ void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[JSStack::CallerFrame] = callerFrame; }
+ void setScope(JSScope* scope) { static_cast<Register*>(this)[JSStack::ScopeChain] = scope; }
ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, JSScope* scope,
CallFrame* callerFrame, int argc, JSObject* callee)
{
ASSERT(callerFrame); // Use noCaller() rather than 0 for the outer host call frame caller.
- ASSERT(callerFrame == noCaller() || callerFrame->removeHostCallFrameFlag()->registerFile()->end() >= this);
+ ASSERT(callerFrame == noCaller() || callerFrame->removeHostCallFrameFlag()->stack()->end() >= this);
setCodeBlock(codeBlock);
setScope(scope);
@@ -186,10 +186,19 @@ namespace JSC {
// Access to arguments as passed. (After capture, arguments may move to a different location.)
size_t argumentCount() const { return argumentCountIncludingThis() - 1; }
- size_t argumentCountIncludingThis() const { return this[RegisterFile::ArgumentCount].payload(); }
+ size_t argumentCountIncludingThis() const { return this[JSStack::ArgumentCount].payload(); }
static int argumentOffset(int argument) { return s_firstArgumentOffset - argument; }
static int argumentOffsetIncludingThis(int argument) { return s_thisArgumentOffset - argument; }
+ // In the following (argument() and setArgument()), the 'argument'
+ // parameter is the index of the arguments of the target function of
+ // this frame. The index starts at 0 for the first arg, 1 for the
+ // second, etc.
+ //
+ // The arguments (in this case) do not include the 'this' value.
+ // arguments(0) will not fetch the 'this' value. To get/set 'this',
+ // use thisValue() and setThisValue() below.
+
JSValue argument(size_t argument)
{
if (argument >= argumentCount())
@@ -207,7 +216,7 @@ namespace JSC {
JSValue argumentAfterCapture(size_t argument);
- static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize; }
+ static int offsetFor(size_t argumentCountIncludingThis) { return argumentCountIncludingThis + JSStack::CallFrameHeaderSize; }
// FIXME: Remove these.
int hostThisRegister() { return thisArgumentOffset(); }
@@ -219,15 +228,15 @@ namespace JSC {
CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); }
CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); }
- void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount].payload() = count; }
- void setCallee(JSObject* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = Register::withCallee(callee); }
- void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[RegisterFile::CodeBlock] = codeBlock; }
- void setReturnPC(void* value) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = (Instruction*)value; }
+ void setArgumentCountIncludingThis(int count) { static_cast<Register*>(this)[JSStack::ArgumentCount].payload() = count; }
+ void setCallee(JSObject* callee) { static_cast<Register*>(this)[JSStack::Callee] = Register::withCallee(callee); }
+ void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[JSStack::CodeBlock] = codeBlock; }
+ void setReturnPC(void* value) { static_cast<Register*>(this)[JSStack::ReturnPC] = (Instruction*)value; }
#if ENABLE(DFG_JIT)
bool isInlineCallFrame();
- void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = inlineCallFrame; }
+ void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast<Register*>(this)[JSStack::ReturnPC] = inlineCallFrame; }
// Call this to get the semantically correct JS CallFrame* for the
// currently executing function.
@@ -260,11 +269,11 @@ namespace JSC {
private:
static const intptr_t HostCallFrameFlag = 1;
- static const int s_thisArgumentOffset = -1 - RegisterFile::CallFrameHeaderSize;
+ static const int s_thisArgumentOffset = -1 - JSStack::CallFrameHeaderSize;
static const int s_firstArgumentOffset = s_thisArgumentOffset - 1;
#ifndef NDEBUG
- RegisterFile* registerFile();
+ JSStack* stack();
#endif
#if ENABLE(DFG_JIT)
bool isInlineCallFrameSlow();
diff --git a/Source/JavaScriptCore/interpreter/CallFrameClosure.h b/Source/JavaScriptCore/interpreter/CallFrameClosure.h
index 125193258..157d1b3b9 100644
--- a/Source/JavaScriptCore/interpreter/CallFrameClosure.h
+++ b/Source/JavaScriptCore/interpreter/CallFrameClosure.h
@@ -52,7 +52,11 @@ struct CallFrameClosure {
void resetCallFrame()
{
newCallFrame->setScope(scope);
- for (int i = argumentCountIncludingThis; i < parameterCountIncludingThis; ++i)
+ // setArgument() takes an arg index that starts from 0 for the first
+ // argument after the 'this' value. Since both argumentCountIncludingThis
+ // and parameterCountIncludingThis includes the 'this' value, we need to
+ // subtract 1 from them to make i a valid argument index for setArgument().
+ for (int i = argumentCountIncludingThis-1; i < parameterCountIncludingThis-1; ++i)
newCallFrame->setArgument(i, jsUndefined());
}
};
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 3107a5dab..00b283393 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -88,10 +88,10 @@ static int depth(CodeBlock* codeBlock, JSScope* sc)
return sc->localDepth();
}
-ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis)
+ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, JSStack* stack, CallFrame* callFrame, size_t registerOffset, int argumentCountIncludingThis)
{
// This ensures enough space for the worst case scenario of zero arguments passed by the caller.
- if (!registerFile->grow(callFrame->registers() + registerOffset + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
+ if (!stack->grow(callFrame->registers() + registerOffset + newCodeBlock->numParameters() + newCodeBlock->m_numCalleeRegisters))
return 0;
if (argumentCountIncludingThis >= newCodeBlock->numParameters()) {
@@ -163,15 +163,15 @@ JSValue eval(CallFrame* callFrame)
JSValue thisValue = callerFrame->thisValue();
ASSERT(isValidThisObject(thisValue, callFrame));
Interpreter* interpreter = callFrame->globalData().interpreter;
- return interpreter->execute(eval, callFrame, thisValue, callerScopeChain, callFrame->registers() - interpreter->registerFile().begin() + 1 + RegisterFile::CallFrameHeaderSize);
+ return interpreter->execute(eval, callFrame, thisValue, callerScopeChain, callFrame->registers() - interpreter->stack().begin() + 1 + JSStack::CallFrameHeaderSize);
}
-CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue thisValue, JSValue arguments, int firstFreeRegister)
+CallFrame* loadVarargs(CallFrame* callFrame, JSStack* stack, JSValue thisValue, JSValue arguments, int firstFreeRegister)
{
if (!arguments) { // f.apply(x, arguments), with arguments unmodified.
unsigned argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize);
- if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !registerFile->grow(newCallFrame->registers())) {
+ CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + argumentCountIncludingThis + JSStack::CallFrameHeaderSize);
+ if (argumentCountIncludingThis > Arguments::MaxArguments + 1 || !stack->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
}
@@ -184,8 +184,8 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue
}
if (arguments.isUndefinedOrNull()) {
- CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + RegisterFile::CallFrameHeaderSize);
- if (!registerFile->grow(newCallFrame->registers())) {
+ CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + 1 + JSStack::CallFrameHeaderSize);
+ if (!stack->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
}
@@ -203,7 +203,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue
Arguments* argsObject = asArguments(arguments);
unsigned argCount = argsObject->length(callFrame);
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
- if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
+ if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
}
@@ -217,7 +217,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue
JSArray* array = asArray(arguments);
unsigned argCount = array->length();
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
- if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
+ if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
}
@@ -230,7 +230,7 @@ CallFrame* loadVarargs(CallFrame* callFrame, RegisterFile* registerFile, JSValue
JSObject* argObject = asObject(arguments);
unsigned argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + firstFreeRegister + CallFrame::offsetFor(argCount + 1));
- if (argCount > Arguments::MaxArguments || !registerFile->grow(newCallFrame->registers())) {
+ if (argCount > Arguments::MaxArguments || !stack->grow(newCallFrame->registers())) {
callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
}
@@ -301,8 +301,8 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
const Register* it;
const Register* end;
- it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - callFrame->argumentCountIncludingThis();
- end = callFrame->registers() - RegisterFile::CallFrameHeaderSize;
+ it = callFrame->registers() - JSStack::CallFrameHeaderSize - callFrame->argumentCountIncludingThis();
+ end = callFrame->registers() - JSStack::CallFrameHeaderSize;
while (it < end) {
JSValue v = it->jsValue();
int registerNumber = it - callFrame->registers();
@@ -710,7 +710,7 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
Register* callerHighWaterMark = callerFrame->registers() + codeBlock->m_numCalleeRegisters;
highWaterMark = max(highWaterMark, callerHighWaterMark);
}
- m_registerFile.shrink(highWaterMark);
+ m_stack.shrink(highWaterMark);
// Unwind the scope chain within the exception handler's call frame.
JSScope* scope = callFrame->scope();
@@ -738,8 +738,25 @@ static inline JSObject* checkedReturn(JSObject* returnValue)
return returnValue;
}
+class SamplingScope {
+public:
+ SamplingScope(Interpreter* interpreter)
+ : m_interpreter(interpreter)
+ {
+ interpreter->startSampling();
+ }
+ ~SamplingScope()
+ {
+ m_interpreter->stopSampling();
+ }
+private:
+ Interpreter* m_interpreter;
+};
+
JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, JSObject* thisObj)
{
+ SamplingScope samplingScope(this);
+
JSScope* scope = callFrame->scope();
ASSERT(isValidThisObject(thisObj, callFrame));
ASSERT(!scope->globalData()->exception);
@@ -863,13 +880,13 @@ failedJSONP:
CodeBlock* codeBlock = &program->generatedBytecode();
// Reserve stack space for this invocation:
- Register* oldEnd = m_registerFile.end();
- Register* newEnd = oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
- if (!m_registerFile.grow(newEnd))
+ Register* oldEnd = m_stack.end();
+ Register* newEnd = oldEnd + codeBlock->numParameters() + JSStack::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
+ if (!m_stack.grow(newEnd))
return checkedReturn(throwStackOverflowError(callFrame));
// Push the call frame for this invocation:
- CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters() + RegisterFile::CallFrameHeaderSize);
+ CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters() + JSStack::CallFrameHeaderSize);
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
newCallFrame->init(codeBlock, 0, scope, CallFrame::noCaller(), codeBlock->numParameters(), 0);
newCallFrame->setThisValue(thisObj);
@@ -883,11 +900,11 @@ failedJSONP:
{
SamplingTool::CallRecord callRecord(m_sampler.get());
- m_reentryDepth++;
+ m_reentryDepth++;
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_program_prologue);
#elif ENABLE(JIT)
- result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
+ result = program->generatedJITCode().execute(&m_stack, newCallFrame, scope->globalData());
#endif // ENABLE(JIT)
m_reentryDepth--;
@@ -896,7 +913,7 @@ failedJSONP:
if (Profiler* profiler = callFrame->globalData().enabledProfiler())
profiler->didExecute(callFrame, program->sourceURL(), program->lineNo());
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(result);
}
@@ -912,13 +929,13 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
return checkedReturn(throwStackOverflowError(callFrame));
- Register* oldEnd = m_registerFile.end();
+ Register* oldEnd = m_stack.end();
ASSERT(callFrame->frameExtent() <= oldEnd || callFrame == callFrame->scope()->globalObject()->globalExec());
int argCount = 1 + args.size(); // implicit "this" parameter
- size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;
+ size_t registerOffset = argCount + JSStack::CallFrameHeaderSize;
CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
- if (!m_registerFile.grow(newCallFrame->registers()))
+ if (!m_stack.grow(newCallFrame->registers()))
return checkedReturn(throwStackOverflowError(callFrame));
newCallFrame->setThisValue(thisValue);
@@ -932,14 +949,14 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScope);
if (UNLIKELY(!!compileError)) {
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(throwError(callFrame, compileError));
}
CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
- newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount);
+ newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_stack, newCallFrame, 0, argCount);
if (UNLIKELY(!newCallFrame)) {
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(throwStackOverflowError(callFrame));
}
@@ -958,7 +975,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_call_prologue);
#elif ENABLE(JIT)
- result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScope->globalData());
+ result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_stack, newCallFrame, callDataScope->globalData());
#endif // ENABLE(JIT)
m_reentryDepth--;
@@ -967,7 +984,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
if (Profiler* profiler = callFrame->globalData().enabledProfiler())
profiler->didExecute(callFrame, function);
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(result);
}
@@ -991,7 +1008,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
if (Profiler* profiler = callFrame->globalData().enabledProfiler())
profiler->didExecute(callFrame, function);
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(result);
}
@@ -1007,11 +1024,11 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (m_reentryDepth >= MaxSmallThreadReentryDepth && m_reentryDepth >= callFrame->globalData().maxReentryDepth)
return checkedReturn(throwStackOverflowError(callFrame));
- Register* oldEnd = m_registerFile.end();
+ Register* oldEnd = m_stack.end();
int argCount = 1 + args.size(); // implicit "this" parameter
- size_t registerOffset = argCount + RegisterFile::CallFrameHeaderSize;
+ size_t registerOffset = argCount + JSStack::CallFrameHeaderSize;
- if (!m_registerFile.grow(oldEnd + registerOffset))
+ if (!m_stack.grow(oldEnd + registerOffset))
return checkedReturn(throwStackOverflowError(callFrame));
CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
@@ -1026,14 +1043,14 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScope);
if (UNLIKELY(!!compileError)) {
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(throwError(callFrame, compileError));
}
CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
- newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, 0, argCount);
+ newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_stack, newCallFrame, 0, argCount);
if (UNLIKELY(!newCallFrame)) {
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(throwStackOverflowError(callFrame));
}
@@ -1052,7 +1069,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_function_for_construct_prologue);
#elif ENABLE(JIT)
- result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScope->globalData());
+ result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_stack, newCallFrame, constructDataScope->globalData());
#endif // ENABLE(JIT)
m_reentryDepth--;
}
@@ -1060,7 +1077,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (Profiler* profiler = callFrame->globalData().enabledProfiler())
profiler->didExecute(callFrame, constructor);
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
if (callFrame->hadException())
return 0;
ASSERT(result.isObject());
@@ -1087,7 +1104,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (Profiler* profiler = callFrame->globalData().enabledProfiler())
profiler->didExecute(callFrame, constructor);
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
if (callFrame->hadException())
return 0;
ASSERT(result.isObject());
@@ -1106,11 +1123,11 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
return CallFrameClosure();
}
- Register* oldEnd = m_registerFile.end();
- size_t registerOffset = argumentCountIncludingThis + RegisterFile::CallFrameHeaderSize;
+ Register* oldEnd = m_stack.end();
+ size_t registerOffset = argumentCountIncludingThis + JSStack::CallFrameHeaderSize;
CallFrame* newCallFrame = CallFrame::create(oldEnd + registerOffset);
- if (!m_registerFile.grow(newCallFrame->registers())) {
+ if (!m_stack.grow(newCallFrame->registers())) {
throwStackOverflowError(callFrame);
return CallFrameClosure();
}
@@ -1118,15 +1135,15 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
JSObject* error = functionExecutable->compileForCall(callFrame, scope);
if (error) {
throwError(callFrame, error);
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return CallFrameClosure();
}
CodeBlock* codeBlock = &functionExecutable->generatedBytecodeForCall();
- newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, 0, argumentCountIncludingThis);
+ newCallFrame = slideRegisterWindowForCall(codeBlock, &m_stack, newCallFrame, 0, argumentCountIncludingThis);
if (UNLIKELY(!newCallFrame)) {
throwStackOverflowError(callFrame);
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return CallFrameClosure();
}
newCallFrame->init(codeBlock, 0, scope, callFrame->addHostCallFrameFlag(), argumentCountIncludingThis, function);
@@ -1137,6 +1154,8 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionE
JSValue Interpreter::execute(CallFrameClosure& closure)
{
+ SamplingScope samplingScope(this);
+
ASSERT(!closure.oldCallFrame->globalData().isCollectorBusy());
if (closure.oldCallFrame->globalData().isCollectorBusy())
return jsNull();
@@ -1154,7 +1173,7 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(closure.newCallFrame, llint_function_for_call_prologue);
#elif ENABLE(JIT)
- result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, closure.newCallFrame, closure.globalData);
+ result = closure.functionExecutable->generatedJITCodeForCall().execute(&m_stack, closure.newCallFrame, closure.globalData);
#endif // ENABLE(JIT)
m_reentryDepth--;
}
@@ -1167,11 +1186,13 @@ JSValue Interpreter::execute(CallFrameClosure& closure)
void Interpreter::endRepeatCall(CallFrameClosure& closure)
{
closure.globalData->topCallFrame = closure.oldCallFrame;
- m_registerFile.shrink(closure.oldEnd);
+ m_stack.shrink(closure.oldEnd);
}
JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope, int globalRegisterOffset)
{
+ SamplingScope samplingScope(this);
+
ASSERT(isValidThisObject(thisValue, callFrame));
ASSERT(!scope->globalData()->exception);
ASSERT(!callFrame->globalData().isCollectorBusy());
@@ -1222,12 +1243,12 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
}
}
- Register* oldEnd = m_registerFile.end();
- Register* newEnd = m_registerFile.begin() + globalRegisterOffset + codeBlock->m_numCalleeRegisters;
- if (!m_registerFile.grow(newEnd))
+ Register* oldEnd = m_stack.end();
+ Register* newEnd = m_stack.begin() + globalRegisterOffset + codeBlock->m_numCalleeRegisters;
+ if (!m_stack.grow(newEnd))
return checkedReturn(throwStackOverflowError(callFrame));
- CallFrame* newCallFrame = CallFrame::create(m_registerFile.begin() + globalRegisterOffset);
+ CallFrame* newCallFrame = CallFrame::create(m_stack.begin() + globalRegisterOffset);
ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
newCallFrame->init(codeBlock, 0, scope, callFrame->addHostCallFrameFlag(), codeBlock->numParameters(), 0);
@@ -1247,7 +1268,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
#if ENABLE(LLINT_C_LOOP)
result = LLInt::CLoop::execute(newCallFrame, llint_eval_prologue);
#elif ENABLE(JIT)
- result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scope->globalData());
+ result = eval->generatedJITCode().execute(&m_stack, newCallFrame, scope->globalData());
#endif // ENABLE(JIT)
m_reentryDepth--;
}
@@ -1255,7 +1276,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
if (Profiler* profiler = callFrame->globalData().enabledProfiler())
profiler->didExecute(callFrame, eval->sourceURL(), eval->lineNo());
- m_registerFile.shrink(oldEnd);
+ m_stack.shrink(oldEnd);
return checkedReturn(result);
}
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index f27ae8206..11c6f078a 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -35,9 +35,9 @@
#include "JSFunction.h"
#include "JSValue.h"
#include "JSObject.h"
+#include "JSStack.h"
#include "LLIntData.h"
#include "Opcode.h"
-#include "RegisterFile.h"
#include <wtf/HashMap.h>
#include <wtf/text/StringBuilder.h>
@@ -189,7 +189,7 @@ namespace JSC {
void initialize(bool canUseJIT);
- RegisterFile& registerFile() { return m_registerFile; }
+ JSStack& stack() { return m_stack; }
Opcode getOpcode(OpcodeID id)
{
@@ -249,14 +249,10 @@ namespace JSC {
NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
- static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
+ static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, JSStack*, CallFrame*, size_t registerOffset, int argc);
static CallFrame* findFunctionCallFrameFromVMCode(CallFrame*, JSFunction*);
-#if !ENABLE(LLINT_C_LOOP)
- JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);
-#endif
-
void dumpRegisters(CallFrame*);
bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
@@ -267,7 +263,7 @@ namespace JSC {
int m_reentryDepth;
- RegisterFile m_registerFile;
+ JSStack m_stack;
#if ENABLE(COMPUTED_GOTO_OPCODES) && ENABLE(LLINT)
Opcode* m_opcodeTable; // Maps OpcodeID => Opcode for compiling
@@ -287,11 +283,11 @@ namespace JSC {
inline JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue thisValue, JSScope* scope)
{
- return execute(eval, callFrame, thisValue, scope, m_registerFile.size() + 1 + RegisterFile::CallFrameHeaderSize);
+ return execute(eval, callFrame, thisValue, scope, m_stack.size() + 1 + JSStack::CallFrameHeaderSize);
}
JSValue eval(CallFrame*);
- CallFrame* loadVarargs(CallFrame*, RegisterFile*, JSValue thisValue, JSValue arguments, int firstFreeRegister);
+ CallFrame* loadVarargs(CallFrame*, JSStack*, JSValue thisValue, JSValue arguments, int firstFreeRegister);
} // namespace JSC
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.cpp b/Source/JavaScriptCore/interpreter/JSStack.cpp
index dacb53872..5dd708a48 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.cpp
+++ b/Source/JavaScriptCore/interpreter/JSStack.cpp
@@ -27,7 +27,7 @@
*/
#include "config.h"
-#include "RegisterFile.h"
+#include "JSStack.h"
#include "ConservativeRoots.h"
#include "Interpreter.h"
@@ -36,13 +36,13 @@ namespace JSC {
static size_t committedBytesCount = 0;
-static Mutex& registerFileStatisticsMutex()
+static Mutex& stackStatisticsMutex()
{
DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
return staticMutex;
}
-RegisterFile::~RegisterFile()
+JSStack::~JSStack()
{
void* base = m_reservation.base();
m_reservation.decommit(base, reinterpret_cast<intptr_t>(m_commitEnd) - reinterpret_cast<intptr_t>(base));
@@ -50,7 +50,7 @@ RegisterFile::~RegisterFile()
m_reservation.deallocate();
}
-bool RegisterFile::growSlowCase(Register* newEnd)
+bool JSStack::growSlowCase(Register* newEnd)
{
if (newEnd <= m_commitEnd) {
m_end = newEnd;
@@ -68,17 +68,17 @@ bool RegisterFile::growSlowCase(Register* newEnd)
return true;
}
-void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
+void JSStack::gatherConservativeRoots(ConservativeRoots& conservativeRoots)
{
conservativeRoots.add(begin(), end());
}
-void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks)
+void JSStack::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks)
{
conservativeRoots.add(begin(), end(), jitStubRoutines, dfgCodeBlocks);
}
-void RegisterFile::releaseExcessCapacity()
+void JSStack::releaseExcessCapacity()
{
ptrdiff_t delta = reinterpret_cast<uintptr_t>(m_commitEnd) - reinterpret_cast<uintptr_t>(m_reservation.base());
m_reservation.decommit(m_reservation.base(), delta);
@@ -86,20 +86,20 @@ void RegisterFile::releaseExcessCapacity()
m_commitEnd = static_cast<Register*>(m_reservation.base());
}
-void RegisterFile::initializeThreading()
+void JSStack::initializeThreading()
{
- registerFileStatisticsMutex();
+ stackStatisticsMutex();
}
-size_t RegisterFile::committedByteCount()
+size_t JSStack::committedByteCount()
{
- MutexLocker locker(registerFileStatisticsMutex());
+ MutexLocker locker(stackStatisticsMutex());
return committedBytesCount;
}
-void RegisterFile::addToCommittedByteCount(long byteCount)
+void JSStack::addToCommittedByteCount(long byteCount)
{
- MutexLocker locker(registerFileStatisticsMutex());
+ MutexLocker locker(stackStatisticsMutex());
ASSERT(static_cast<long>(committedBytesCount) + byteCount > -1);
committedBytesCount += byteCount;
}
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.h b/Source/JavaScriptCore/interpreter/JSStack.h
index 8fff8208c..86fa40be7 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.h
+++ b/Source/JavaScriptCore/interpreter/JSStack.h
@@ -26,8 +26,8 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef RegisterFile_h
-#define RegisterFile_h
+#ifndef JSStack_h
+#define JSStack_h
#include "ExecutableAllocator.h"
#include "Register.h"
@@ -42,8 +42,8 @@ namespace JSC {
class JITStubRoutineSet;
class LLIntOffsetsExtractor;
- class RegisterFile {
- WTF_MAKE_NONCOPYABLE(RegisterFile);
+ class JSStack {
+ WTF_MAKE_NONCOPYABLE(JSStack);
public:
enum CallFrameHeaderEntry {
CallFrameHeaderSize = 6,
@@ -58,11 +58,11 @@ namespace JSC {
static const size_t defaultCapacity = 512 * 1024;
static const size_t commitSize = 16 * 1024;
- // Allow 8k of excess registers before we start trying to reap the registerfile
+ // Allow 8k of excess registers before we start trying to reap the stack
static const ptrdiff_t maxExcessCapacity = 8 * 1024;
- RegisterFile(size_t capacity = defaultCapacity);
- ~RegisterFile();
+ JSStack(size_t capacity = defaultCapacity);
+ ~JSStack();
void gatherConservativeRoots(ConservativeRoots&);
void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, DFGCodeBlocks&);
@@ -84,7 +84,7 @@ namespace JSC {
private:
friend class LLIntOffsetsExtractor;
-
+
bool growSlowCase(Register*);
void releaseExcessCapacity();
void addToCommittedByteCount(long);
@@ -93,7 +93,7 @@ namespace JSC {
PageReservation m_reservation;
};
- inline RegisterFile::RegisterFile(size_t capacity)
+ inline JSStack::JSStack(size_t capacity)
: m_end(0)
{
ASSERT(capacity && isPageAligned(capacity));
@@ -103,7 +103,7 @@ namespace JSC {
m_commitEnd = static_cast<Register*>(m_reservation.base());
}
- inline void RegisterFile::shrink(Register* newEnd)
+ inline void JSStack::shrink(Register* newEnd)
{
if (newEnd >= m_end)
return;
@@ -112,7 +112,7 @@ namespace JSC {
releaseExcessCapacity();
}
- inline bool RegisterFile::grow(Register* newEnd)
+ inline bool JSStack::grow(Register* newEnd)
{
if (newEnd <= m_end)
return true;
@@ -121,4 +121,4 @@ namespace JSC {
} // namespace JSC
-#endif // RegisterFile_h
+#endif // JSStack_h
diff --git a/Source/JavaScriptCore/interpreter/VMInspector.cpp b/Source/JavaScriptCore/interpreter/VMInspector.cpp
index 34bf61535..566d4e8e0 100644
--- a/Source/JavaScriptCore/interpreter/VMInspector.cpp
+++ b/Source/JavaScriptCore/interpreter/VMInspector.cpp
@@ -69,25 +69,19 @@ void VMInspector::dumpFrame(CallFrame* frame, const char* prefix,
printf("%s ", prefix);
printf("frame [%d] %p { cb %p:%s, retPC %p:%s, scope %p:%s, callee %p:%s, callerFrame %p:%s, argc %d, vPC %p }",
- frameCount, frame,
-
- CAST<void*>(frame[RegisterFile::CodeBlock].payload()),
- getTypeName(frame[RegisterFile::CodeBlock].jsValue()),
-
- CAST<void*>(frame[RegisterFile::ReturnPC].payload()),
- getTypeName(frame[RegisterFile::ReturnPC].jsValue()),
-
- CAST<void*>(frame[RegisterFile::ScopeChain].payload()),
- getTypeName(frame[RegisterFile::ScopeChain].jsValue()),
-
- CAST<void*>(frame[RegisterFile::Callee].payload()),
- getTypeName(frame[RegisterFile::Callee].jsValue()),
-
- CAST<void*>(frame[RegisterFile::CallerFrame].payload()),
- getTypeName(frame[RegisterFile::CallerFrame].jsValue()),
-
- frame[RegisterFile::ArgumentCount].payload(),
- vPC);
+ frameCount, frame,
+ CAST<void*>(frame[JSStack::CodeBlock].payload()),
+ getTypeName(frame[JSStack::CodeBlock].jsValue()),
+ CAST<void*>(frame[JSStack::ReturnPC].payload()),
+ getTypeName(frame[JSStack::ReturnPC].jsValue()),
+ CAST<void*>(frame[JSStack::ScopeChain].payload()),
+ getTypeName(frame[JSStack::ScopeChain].jsValue()),
+ CAST<void*>(frame[JSStack::Callee].payload()),
+ getTypeName(frame[JSStack::Callee].jsValue()),
+ CAST<void*>(frame[JSStack::CallerFrame].callFrame()),
+ getTypeName(frame[JSStack::CallerFrame].jsValue()),
+ frame[JSStack::ArgumentCount].payload(),
+ vPC);
if (funcName || file || (line >= 0)) {
printf(" @");