diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-05-24 08:28:08 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-05-24 08:28:08 +0000 |
commit | a4e969f4965059196ca948db781e52f7cfebf19e (patch) | |
tree | 6ca352808c8fdc52006a0f33f6ae3c593b23867d /Source/JavaScriptCore/interpreter/CallFrame.cpp | |
parent | 41386e9cb918eed93b3f13648cbef387e371e451 (diff) | |
download | WebKitGtk-tarball-a4e969f4965059196ca948db781e52f7cfebf19e.tar.gz |
webkitgtk-2.12.3webkitgtk-2.12.3
Diffstat (limited to 'Source/JavaScriptCore/interpreter/CallFrame.cpp')
-rw-r--r-- | Source/JavaScriptCore/interpreter/CallFrame.cpp | 228 |
1 files changed, 184 insertions, 44 deletions
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.cpp b/Source/JavaScriptCore/interpreter/CallFrame.cpp index a226e9848..3d3897b6b 100644 --- a/Source/JavaScriptCore/interpreter/CallFrame.cpp +++ b/Source/JavaScriptCore/interpreter/CallFrame.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2013 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2013, 2014 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,14 +26,74 @@ #include "config.h" #include "CallFrame.h" -#include "CallFrameInlines.h" #include "CodeBlock.h" +#include "InlineCallFrame.h" #include "Interpreter.h" -#include "Operations.h" +#include "JSLexicalEnvironment.h" +#include "JSCInlines.h" #include "VMEntryScope.h" +#include <wtf/StringPrintStream.h> namespace JSC { +bool CallFrame::callSiteBitsAreBytecodeOffset() const +{ + ASSERT(codeBlock()); + switch (codeBlock()->jitType()) { + case JITCode::InterpreterThunk: + case JITCode::BaselineJIT: + return true; + case JITCode::None: + case JITCode::HostCallThunk: + RELEASE_ASSERT_NOT_REACHED(); + return false; + default: + return false; + } + + RELEASE_ASSERT_NOT_REACHED(); + return false; +} + +bool CallFrame::callSiteBitsAreCodeOriginIndex() const +{ + ASSERT(codeBlock()); + switch (codeBlock()->jitType()) { + case JITCode::DFGJIT: + case JITCode::FTLJIT: + return true; + case JITCode::None: + case JITCode::HostCallThunk: + RELEASE_ASSERT_NOT_REACHED(); + return false; + default: + return false; + } + + RELEASE_ASSERT_NOT_REACHED(); + return false; +} + +unsigned CallFrame::callSiteAsRawBits() const +{ + return this[JSStack::ArgumentCount].tag(); +} + +SUPPRESS_ASAN unsigned CallFrame::unsafeCallSiteAsRawBits() const +{ + return this[JSStack::ArgumentCount].unsafeTag(); +} + +CallSiteIndex CallFrame::callSiteIndex() const +{ + return CallSiteIndex(callSiteAsRawBits()); +} + +SUPPRESS_ASAN CallSiteIndex CallFrame::unsafeCallSiteIndex() const +{ + return CallSiteIndex(unsafeCallSiteAsRawBits()); +} + #ifndef NDEBUG JSStack* CallFrame::stack() { @@ -43,63 +103,63 @@ JSStack* CallFrame::stack() #endif #if USE(JSVALUE32_64) -unsigned CallFrame::locationAsBytecodeOffset() const +Instruction* CallFrame::currentVPC() const { - ASSERT(codeBlock()); - ASSERT(hasLocationAsBytecodeOffset()); - return currentVPC() - codeBlock()->instructions().begin(); + return bitwise_cast<Instruction*>(callSiteIndex().bits()); +} + +void CallFrame::setCurrentVPC(Instruction* vpc) +{ + CallSiteIndex callSite(vpc); + this[JSStack::ArgumentCount].tag() = callSite.bits(); } -void CallFrame::setLocationAsBytecodeOffset(unsigned offset) +unsigned CallFrame::callSiteBitsAsBytecodeOffset() const { ASSERT(codeBlock()); - setCurrentVPC(codeBlock()->instructions().begin() + offset); - ASSERT(hasLocationAsBytecodeOffset()); + ASSERT(callSiteBitsAreBytecodeOffset()); + return currentVPC() - codeBlock()->instructions().begin(); } -#else + +#else // USE(JSVALUE32_64) Instruction* CallFrame::currentVPC() const { - return codeBlock()->instructions().begin() + locationAsBytecodeOffset(); + ASSERT(callSiteBitsAreBytecodeOffset()); + return codeBlock()->instructions().begin() + callSiteBitsAsBytecodeOffset(); } + void CallFrame::setCurrentVPC(Instruction* vpc) { - setLocationAsBytecodeOffset(vpc - codeBlock()->instructions().begin()); + CallSiteIndex callSite(vpc - codeBlock()->instructions().begin()); + this[JSStack::ArgumentCount].tag() = static_cast<int32_t>(callSite.bits()); } -#endif - -#if ENABLE(DFG_JIT) -unsigned CallFrame::bytecodeOffsetFromCodeOriginIndex() -{ - ASSERT(hasLocationAsCodeOriginIndex()); - CodeBlock* codeBlock = this->codeBlock(); - ASSERT(codeBlock); - - CodeOrigin codeOrigin; - unsigned index = locationAsCodeOriginIndex(); - ASSERT(codeBlock->canGetCodeOrigin(index)); - codeOrigin = codeBlock->codeOrigin(index); - for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) { - if (inlineCallFrame->baselineCodeBlock() == codeBlock) - return codeOrigin.bytecodeIndex; - - codeOrigin = inlineCallFrame->caller; - inlineCallFrame = codeOrigin.inlineCallFrame; - } - return codeOrigin.bytecodeIndex; +unsigned CallFrame::callSiteBitsAsBytecodeOffset() const +{ + ASSERT(codeBlock()); + ASSERT(callSiteBitsAreBytecodeOffset()); + return callSiteIndex().bits(); } -#endif // ENABLE(DFG_JIT) - +#endif + unsigned CallFrame::bytecodeOffset() { if (!codeBlock()) return 0; #if ENABLE(DFG_JIT) - if (hasLocationAsCodeOriginIndex()) - return bytecodeOffsetFromCodeOriginIndex(); + if (callSiteBitsAreCodeOriginIndex()) { + ASSERT(codeBlock()); + CodeOrigin codeOrigin = this->codeOrigin(); + for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) { + codeOrigin = inlineCallFrame->directCaller; + inlineCallFrame = codeOrigin.inlineCallFrame; + } + return codeOrigin.bytecodeIndex; + } #endif - return locationAsBytecodeOffset(); + ASSERT(callSiteBitsAreBytecodeOffset()); + return callSiteBitsAsBytecodeOffset(); } CodeOrigin CallFrame::codeOrigin() @@ -107,20 +167,20 @@ CodeOrigin CallFrame::codeOrigin() if (!codeBlock()) return CodeOrigin(0); #if ENABLE(DFG_JIT) - if (hasLocationAsCodeOriginIndex()) { - unsigned index = locationAsCodeOriginIndex(); + if (callSiteBitsAreCodeOriginIndex()) { + CallSiteIndex index = callSiteIndex(); ASSERT(codeBlock()->canGetCodeOrigin(index)); return codeBlock()->codeOrigin(index); } #endif - return CodeOrigin(locationAsBytecodeOffset()); + return CodeOrigin(callSiteBitsAsBytecodeOffset()); } -Register* CallFrame::frameExtentInternal() +Register* CallFrame::topOfFrameInternal() { CodeBlock* codeBlock = this->codeBlock(); ASSERT(codeBlock); - return registers() + virtualRegisterForLocal(codeBlock->frameRegisterCount()).offset(); + return registers() + codeBlock->stackPointerOffset(); } JSGlobalObject* CallFrame::vmEntryGlobalObject() @@ -134,4 +194,84 @@ JSGlobalObject* CallFrame::vmEntryGlobalObject() return vm().entryScope->globalObject(); } +CallFrame* CallFrame::callerFrame(VMEntryFrame*& currVMEntryFrame) +{ + if (callerFrameOrVMEntryFrame() == currVMEntryFrame) { + VMEntryRecord* currVMEntryRecord = vmEntryRecord(currVMEntryFrame); + currVMEntryFrame = currVMEntryRecord->prevTopVMEntryFrame(); + return currVMEntryRecord->prevTopCallFrame(); + } + return static_cast<CallFrame*>(callerFrameOrVMEntryFrame()); +} + +SUPPRESS_ASAN CallFrame* CallFrame::unsafeCallerFrame(VMEntryFrame*& currVMEntryFrame) +{ + if (unsafeCallerFrameOrVMEntryFrame() == currVMEntryFrame) { + VMEntryRecord* currVMEntryRecord = vmEntryRecord(currVMEntryFrame); + currVMEntryFrame = currVMEntryRecord->unsafePrevTopVMEntryFrame(); + return currVMEntryRecord->unsafePrevTopCallFrame(); + } + return static_cast<CallFrame*>(unsafeCallerFrameOrVMEntryFrame()); +} + +String CallFrame::friendlyFunctionName() +{ + CodeBlock* codeBlock = this->codeBlock(); + if (!codeBlock) + return emptyString(); + + switch (codeBlock->codeType()) { + case EvalCode: + return ASCIILiteral("eval code"); + case ModuleCode: + return ASCIILiteral("module code"); + case GlobalCode: + return ASCIILiteral("global code"); + case FunctionCode: + if (callee()) + return getCalculatedDisplayName(this, callee()); + return emptyString(); + } + + ASSERT_NOT_REACHED(); + return emptyString(); +} + +void CallFrame::dump(PrintStream& out) +{ + if (CodeBlock* codeBlock = this->codeBlock()) { + out.print(codeBlock->inferredName(), "#", codeBlock->hashAsStringIfPossible(), " [", codeBlock->jitType(), "]"); + + out.print("("); + thisValue().dumpForBacktrace(out); + + for (size_t i = 0; i < argumentCount(); ++i) { + out.print(", "); + JSValue value = argument(i); + value.dumpForBacktrace(out); + } + + out.print(")"); + + return; + } + + out.print(returnPC()); +} + +const char* CallFrame::describeFrame() +{ + const size_t bufferSize = 200; + static char buffer[bufferSize + 1]; + + WTF::StringPrintStream stringStream; + + dump(stringStream); + + strncpy(buffer, stringStream.toCString().data(), bufferSize); + buffer[bufferSize] = '\0'; + + return buffer; +} + } // namespace JSC |