summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/interpreter/CallFrame.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-05-24 08:28:08 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-05-24 08:28:08 +0000
commita4e969f4965059196ca948db781e52f7cfebf19e (patch)
tree6ca352808c8fdc52006a0f33f6ae3c593b23867d /Source/JavaScriptCore/interpreter/CallFrame.cpp
parent41386e9cb918eed93b3f13648cbef387e371e451 (diff)
downloadWebKitGtk-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.cpp228
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