diff options
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(" @"); |