diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
commit | 5466563f4b5b6b86523e3f89bb7f77e5b5270c78 (patch) | |
tree | 8caccf7cd03a15207cde3ba282c88bf132482a91 /Source/JavaScriptCore/interpreter | |
parent | 33b26980cb24288b5a9f2590ccf32a949281bb79 (diff) | |
download | qtwebkit-5466563f4b5b6b86523e3f89bb7f77e5b5270c78.tar.gz |
Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300)
WebKit update which introduces the QtWebKitWidgets module that contains the WK1
widgets based API. (In fact it renames QtWebKit to QtWebKitWidgets while we're
working on completing the entire split as part of
https://bugs.webkit.org/show_bug.cgi?id=99314
Diffstat (limited to 'Source/JavaScriptCore/interpreter')
-rw-r--r-- | Source/JavaScriptCore/interpreter/CallFrame.cpp | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/interpreter/CallFrame.h | 65 | ||||
-rw-r--r-- | Source/JavaScriptCore/interpreter/CallFrameClosure.h | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/interpreter/Interpreter.cpp | 127 | ||||
-rw-r--r-- | Source/JavaScriptCore/interpreter/Interpreter.h | 16 | ||||
-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.cpp | 32 |
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(" @"); |