From 5466563f4b5b6b86523e3f89bb7f77e5b5270c78 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 15 Oct 2012 16:08:57 +0200 Subject: 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 --- Source/JavaScriptCore/interpreter/CallFrame.cpp | 4 +- Source/JavaScriptCore/interpreter/CallFrame.h | 65 ++++++----- .../JavaScriptCore/interpreter/CallFrameClosure.h | 6 +- Source/JavaScriptCore/interpreter/Interpreter.cpp | 127 ++++++++++++--------- Source/JavaScriptCore/interpreter/Interpreter.h | 16 +-- Source/JavaScriptCore/interpreter/JSStack.cpp | 107 +++++++++++++++++ Source/JavaScriptCore/interpreter/JSStack.h | 124 ++++++++++++++++++++ Source/JavaScriptCore/interpreter/RegisterFile.cpp | 107 ----------------- Source/JavaScriptCore/interpreter/RegisterFile.h | 124 -------------------- Source/JavaScriptCore/interpreter/VMInspector.cpp | 32 +++--- 10 files changed, 368 insertions(+), 344 deletions(-) create mode 100644 Source/JavaScriptCore/interpreter/JSStack.cpp create mode 100644 Source/JavaScriptCore/interpreter/JSStack.h delete mode 100644 Source/JavaScriptCore/interpreter/RegisterFile.cpp delete mode 100644 Source/JavaScriptCore/interpreter/RegisterFile.h (limited to 'Source/JavaScriptCore/interpreter') 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(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(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(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(offset); + this[JSStack::ArgumentCount].tag() = static_cast(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(this[RegisterFile::ArgumentCount].tag()); + return bitwise_cast(this[JSStack::ArgumentCount].tag()); } void setCurrentVPC(Instruction* vpc) { - this[RegisterFile::ArgumentCount].tag() = bitwise_cast(vpc); + this[JSStack::ArgumentCount].tag() = bitwise_cast(vpc); } #else Instruction* currentVPC() const; void setCurrentVPC(Instruction* vpc); #endif - void setCallerFrame(CallFrame* callerFrame) { static_cast(this)[RegisterFile::CallerFrame] = callerFrame; } - void setScope(JSScope* scope) { static_cast(this)[RegisterFile::ScopeChain] = scope; } + void setCallerFrame(CallFrame* callerFrame) { static_cast(this)[JSStack::CallerFrame] = callerFrame; } + void setScope(JSScope* scope) { static_cast(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(reinterpret_cast(this) | HostCallFrameFlag); } CallFrame* removeHostCallFrameFlag() { return reinterpret_cast(reinterpret_cast(this) & ~HostCallFrameFlag); } - void setArgumentCountIncludingThis(int count) { static_cast(this)[RegisterFile::ArgumentCount].payload() = count; } - void setCallee(JSObject* callee) { static_cast(this)[RegisterFile::Callee] = Register::withCallee(callee); } - void setCodeBlock(CodeBlock* codeBlock) { static_cast(this)[RegisterFile::CodeBlock] = codeBlock; } - void setReturnPC(void* value) { static_cast(this)[RegisterFile::ReturnPC] = (Instruction*)value; } + void setArgumentCountIncludingThis(int count) { static_cast(this)[JSStack::ArgumentCount].payload() = count; } + void setCallee(JSObject* callee) { static_cast(this)[JSStack::Callee] = Register::withCallee(callee); } + void setCodeBlock(CodeBlock* codeBlock) { static_cast(this)[JSStack::CodeBlock] = codeBlock; } + void setReturnPC(void* value) { static_cast(this)[JSStack::ReturnPC] = (Instruction*)value; } #if ENABLE(DFG_JIT) bool isInlineCallFrame(); - void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast(this)[RegisterFile::ReturnPC] = inlineCallFrame; } + void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast(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 #include @@ -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/JSStack.cpp b/Source/JavaScriptCore/interpreter/JSStack.cpp new file mode 100644 index 000000000..5dd708a48 --- /dev/null +++ b/Source/JavaScriptCore/interpreter/JSStack.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "JSStack.h" + +#include "ConservativeRoots.h" +#include "Interpreter.h" + +namespace JSC { + +static size_t committedBytesCount = 0; + +static Mutex& stackStatisticsMutex() +{ + DEFINE_STATIC_LOCAL(Mutex, staticMutex, ()); + return staticMutex; +} + +JSStack::~JSStack() +{ + void* base = m_reservation.base(); + m_reservation.decommit(base, reinterpret_cast(m_commitEnd) - reinterpret_cast(base)); + addToCommittedByteCount(-(reinterpret_cast(m_commitEnd) - reinterpret_cast(base))); + m_reservation.deallocate(); +} + +bool JSStack::growSlowCase(Register* newEnd) +{ + if (newEnd <= m_commitEnd) { + m_end = newEnd; + return true; + } + + long delta = roundUpAllocationSize(reinterpret_cast(newEnd) - reinterpret_cast(m_commitEnd), commitSize); + if (reinterpret_cast(m_commitEnd) + delta > static_cast(m_reservation.base()) + m_reservation.size()) + return false; + + m_reservation.commit(m_commitEnd, delta); + addToCommittedByteCount(delta); + m_commitEnd = reinterpret_cast_ptr(reinterpret_cast(m_commitEnd) + delta); + m_end = newEnd; + return true; +} + +void JSStack::gatherConservativeRoots(ConservativeRoots& conservativeRoots) +{ + conservativeRoots.add(begin(), end()); +} + +void JSStack::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks) +{ + conservativeRoots.add(begin(), end(), jitStubRoutines, dfgCodeBlocks); +} + +void JSStack::releaseExcessCapacity() +{ + ptrdiff_t delta = reinterpret_cast(m_commitEnd) - reinterpret_cast(m_reservation.base()); + m_reservation.decommit(m_reservation.base(), delta); + addToCommittedByteCount(-delta); + m_commitEnd = static_cast(m_reservation.base()); +} + +void JSStack::initializeThreading() +{ + stackStatisticsMutex(); +} + +size_t JSStack::committedByteCount() +{ + MutexLocker locker(stackStatisticsMutex()); + return committedBytesCount; +} + +void JSStack::addToCommittedByteCount(long byteCount) +{ + MutexLocker locker(stackStatisticsMutex()); + ASSERT(static_cast(committedBytesCount) + byteCount > -1); + committedBytesCount += byteCount; +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/interpreter/JSStack.h b/Source/JavaScriptCore/interpreter/JSStack.h new file mode 100644 index 000000000..86fa40be7 --- /dev/null +++ b/Source/JavaScriptCore/interpreter/JSStack.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSStack_h +#define JSStack_h + +#include "ExecutableAllocator.h" +#include "Register.h" +#include +#include +#include + +namespace JSC { + + class ConservativeRoots; + class DFGCodeBlocks; + class JITStubRoutineSet; + class LLIntOffsetsExtractor; + + class JSStack { + WTF_MAKE_NONCOPYABLE(JSStack); + public: + enum CallFrameHeaderEntry { + CallFrameHeaderSize = 6, + + ArgumentCount = -6, + CallerFrame = -5, + Callee = -4, + ScopeChain = -3, + ReturnPC = -2, // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. + CodeBlock = -1, + }; + + 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 stack + static const ptrdiff_t maxExcessCapacity = 8 * 1024; + + JSStack(size_t capacity = defaultCapacity); + ~JSStack(); + + void gatherConservativeRoots(ConservativeRoots&); + void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, DFGCodeBlocks&); + + Register* begin() const { return static_cast(m_reservation.base()); } + Register* end() const { return m_end; } + size_t size() const { return end() - begin(); } + + bool grow(Register*); + void shrink(Register*); + + static size_t committedByteCount(); + static void initializeThreading(); + + Register* const * addressOfEnd() const + { + return &m_end; + } + + private: + friend class LLIntOffsetsExtractor; + + bool growSlowCase(Register*); + void releaseExcessCapacity(); + void addToCommittedByteCount(long); + Register* m_end; + Register* m_commitEnd; + PageReservation m_reservation; + }; + + inline JSStack::JSStack(size_t capacity) + : m_end(0) + { + ASSERT(capacity && isPageAligned(capacity)); + + m_reservation = PageReservation::reserve(roundUpAllocationSize(capacity * sizeof(Register), commitSize), OSAllocator::JSVMStackPages); + m_end = static_cast(m_reservation.base()); + m_commitEnd = static_cast(m_reservation.base()); + } + + inline void JSStack::shrink(Register* newEnd) + { + if (newEnd >= m_end) + return; + m_end = newEnd; + if (m_end == m_reservation.base() && (m_commitEnd - begin()) >= maxExcessCapacity) + releaseExcessCapacity(); + } + + inline bool JSStack::grow(Register* newEnd) + { + if (newEnd <= m_end) + return true; + return growSlowCase(newEnd); + } + +} // namespace JSC + +#endif // JSStack_h diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.cpp b/Source/JavaScriptCore/interpreter/RegisterFile.cpp deleted file mode 100644 index dacb53872..000000000 --- a/Source/JavaScriptCore/interpreter/RegisterFile.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "RegisterFile.h" - -#include "ConservativeRoots.h" -#include "Interpreter.h" - -namespace JSC { - -static size_t committedBytesCount = 0; - -static Mutex& registerFileStatisticsMutex() -{ - DEFINE_STATIC_LOCAL(Mutex, staticMutex, ()); - return staticMutex; -} - -RegisterFile::~RegisterFile() -{ - void* base = m_reservation.base(); - m_reservation.decommit(base, reinterpret_cast(m_commitEnd) - reinterpret_cast(base)); - addToCommittedByteCount(-(reinterpret_cast(m_commitEnd) - reinterpret_cast(base))); - m_reservation.deallocate(); -} - -bool RegisterFile::growSlowCase(Register* newEnd) -{ - if (newEnd <= m_commitEnd) { - m_end = newEnd; - return true; - } - - long delta = roundUpAllocationSize(reinterpret_cast(newEnd) - reinterpret_cast(m_commitEnd), commitSize); - if (reinterpret_cast(m_commitEnd) + delta > static_cast(m_reservation.base()) + m_reservation.size()) - return false; - - m_reservation.commit(m_commitEnd, delta); - addToCommittedByteCount(delta); - m_commitEnd = reinterpret_cast_ptr(reinterpret_cast(m_commitEnd) + delta); - m_end = newEnd; - return true; -} - -void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots) -{ - conservativeRoots.add(begin(), end()); -} - -void RegisterFile::gatherConservativeRoots(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, DFGCodeBlocks& dfgCodeBlocks) -{ - conservativeRoots.add(begin(), end(), jitStubRoutines, dfgCodeBlocks); -} - -void RegisterFile::releaseExcessCapacity() -{ - ptrdiff_t delta = reinterpret_cast(m_commitEnd) - reinterpret_cast(m_reservation.base()); - m_reservation.decommit(m_reservation.base(), delta); - addToCommittedByteCount(-delta); - m_commitEnd = static_cast(m_reservation.base()); -} - -void RegisterFile::initializeThreading() -{ - registerFileStatisticsMutex(); -} - -size_t RegisterFile::committedByteCount() -{ - MutexLocker locker(registerFileStatisticsMutex()); - return committedBytesCount; -} - -void RegisterFile::addToCommittedByteCount(long byteCount) -{ - MutexLocker locker(registerFileStatisticsMutex()); - ASSERT(static_cast(committedBytesCount) + byteCount > -1); - committedBytesCount += byteCount; -} - -} // namespace JSC diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.h b/Source/JavaScriptCore/interpreter/RegisterFile.h deleted file mode 100644 index 8fff8208c..000000000 --- a/Source/JavaScriptCore/interpreter/RegisterFile.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef RegisterFile_h -#define RegisterFile_h - -#include "ExecutableAllocator.h" -#include "Register.h" -#include -#include -#include - -namespace JSC { - - class ConservativeRoots; - class DFGCodeBlocks; - class JITStubRoutineSet; - class LLIntOffsetsExtractor; - - class RegisterFile { - WTF_MAKE_NONCOPYABLE(RegisterFile); - public: - enum CallFrameHeaderEntry { - CallFrameHeaderSize = 6, - - ArgumentCount = -6, - CallerFrame = -5, - Callee = -4, - ScopeChain = -3, - ReturnPC = -2, // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*. - CodeBlock = -1, - }; - - 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 - static const ptrdiff_t maxExcessCapacity = 8 * 1024; - - RegisterFile(size_t capacity = defaultCapacity); - ~RegisterFile(); - - void gatherConservativeRoots(ConservativeRoots&); - void gatherConservativeRoots(ConservativeRoots&, JITStubRoutineSet&, DFGCodeBlocks&); - - Register* begin() const { return static_cast(m_reservation.base()); } - Register* end() const { return m_end; } - size_t size() const { return end() - begin(); } - - bool grow(Register*); - void shrink(Register*); - - static size_t committedByteCount(); - static void initializeThreading(); - - Register* const * addressOfEnd() const - { - return &m_end; - } - - private: - friend class LLIntOffsetsExtractor; - - bool growSlowCase(Register*); - void releaseExcessCapacity(); - void addToCommittedByteCount(long); - Register* m_end; - Register* m_commitEnd; - PageReservation m_reservation; - }; - - inline RegisterFile::RegisterFile(size_t capacity) - : m_end(0) - { - ASSERT(capacity && isPageAligned(capacity)); - - m_reservation = PageReservation::reserve(roundUpAllocationSize(capacity * sizeof(Register), commitSize), OSAllocator::JSVMStackPages); - m_end = static_cast(m_reservation.base()); - m_commitEnd = static_cast(m_reservation.base()); - } - - inline void RegisterFile::shrink(Register* newEnd) - { - if (newEnd >= m_end) - return; - m_end = newEnd; - if (m_end == m_reservation.base() && (m_commitEnd - begin()) >= maxExcessCapacity) - releaseExcessCapacity(); - } - - inline bool RegisterFile::grow(Register* newEnd) - { - if (newEnd <= m_end) - return true; - return growSlowCase(newEnd); - } - -} // namespace JSC - -#endif // RegisterFile_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(frame[RegisterFile::CodeBlock].payload()), - getTypeName(frame[RegisterFile::CodeBlock].jsValue()), - - CAST(frame[RegisterFile::ReturnPC].payload()), - getTypeName(frame[RegisterFile::ReturnPC].jsValue()), - - CAST(frame[RegisterFile::ScopeChain].payload()), - getTypeName(frame[RegisterFile::ScopeChain].jsValue()), - - CAST(frame[RegisterFile::Callee].payload()), - getTypeName(frame[RegisterFile::Callee].jsValue()), - - CAST(frame[RegisterFile::CallerFrame].payload()), - getTypeName(frame[RegisterFile::CallerFrame].jsValue()), - - frame[RegisterFile::ArgumentCount].payload(), - vPC); + frameCount, frame, + CAST(frame[JSStack::CodeBlock].payload()), + getTypeName(frame[JSStack::CodeBlock].jsValue()), + CAST(frame[JSStack::ReturnPC].payload()), + getTypeName(frame[JSStack::ReturnPC].jsValue()), + CAST(frame[JSStack::ScopeChain].payload()), + getTypeName(frame[JSStack::ScopeChain].jsValue()), + CAST(frame[JSStack::Callee].payload()), + getTypeName(frame[JSStack::Callee].jsValue()), + CAST(frame[JSStack::CallerFrame].callFrame()), + getTypeName(frame[JSStack::CallerFrame].jsValue()), + frame[JSStack::ArgumentCount].payload(), + vPC); if (funcName || file || (line >= 0)) { printf(" @"); -- cgit v1.2.1