Commit c4497327 authored by oliver@apple.com's avatar oliver@apple.com

fourthTier: Disambiguate between CallFrame bytecodeOffset and codeOriginIndex.

https://bugs.webkit.org/show_bug.cgi?id=117262.

Reviewed by Geoffrey Garen.

When writing to the ArgumentCount tag in CallFrame, we will set the high
bit if the written value is a codeOriginIndex.

* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeOrigin.h:
(CodeOrigin):
(JSC::CodeOrigin::isHandle):
(JSC::CodeOrigin::encodeHandle):
(JSC::CodeOrigin::decodeHandle):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::beginCall):
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryBuildGetByIDList):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::locationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
(JSC::CallFrame::currentVPC):
(JSC::CallFrame::setCurrentVPC):
(JSC::CallFrame::trueCallFrame):
* interpreter/CallFrame.h:
(ExecState):
(JSC::ExecState::inlineCallFrame):
* interpreter/CallFrameInlines.h: Added.
(JSC::CallFrame::hasLocationAsBytecodeOffset):
(JSC::CallFrame::hasLocationAsCodeOriginIndex):
(JSC::CallFrame::locationAsRawBits):
(JSC::CallFrame::setLocationAsRawBits):
(JSC::CallFrame::locationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
(JSC::CallFrame::locationAsCodeOriginIndex):
* interpreter/Interpreter.cpp:
(JSC::getBytecodeOffsetForCallFrame):
(JSC::getCallerInfo):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153209 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent db4f90d9
......@@ -5,6 +5,60 @@
* interpreter/Interpreter.cpp:
* jit/JITStubs.cpp:
2013-06-05 Mark Lam <mark.lam@apple.com>
Disambiguate between CallFrame bytecodeOffset and codeOriginIndex.
https://bugs.webkit.org/show_bug.cgi?id=117262.
Reviewed by Geoffrey Garen.
When writing to the ArgumentCount tag in CallFrame, we will set the high
bit if the written value is a codeOriginIndex.
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeOrigin.h:
(CodeOrigin):
(JSC::CodeOrigin::isHandle):
(JSC::CodeOrigin::encodeHandle):
(JSC::CodeOrigin::decodeHandle):
* dfg/DFGJITCompiler.h:
(JSC::DFG::JITCompiler::beginCall):
* dfg/DFGRepatch.cpp:
(JSC::DFG::tryBuildGetByIDList):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::locationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
(JSC::CallFrame::currentVPC):
(JSC::CallFrame::setCurrentVPC):
(JSC::CallFrame::trueCallFrame):
* interpreter/CallFrame.h:
(ExecState):
(JSC::ExecState::inlineCallFrame):
* interpreter/CallFrameInlines.h: Added.
(JSC::CallFrame::hasLocationAsBytecodeOffset):
(JSC::CallFrame::hasLocationAsCodeOriginIndex):
(JSC::CallFrame::locationAsRawBits):
(JSC::CallFrame::setLocationAsRawBits):
(JSC::CallFrame::locationAsBytecodeOffset):
(JSC::CallFrame::setLocationAsBytecodeOffset):
(JSC::CallFrame::locationAsCodeOriginIndex):
* interpreter/Interpreter.cpp:
(JSC::getBytecodeOffsetForCallFrame):
(JSC::getCallerInfo):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
2013-06-05 Filip Pizlo <fpizlo@apple.com>
Unreviewed, fix release build.
* interpreter/Interpreter.cpp:
* jit/JITStubs.cpp:
2013-06-04 Filip Pizlo <fpizlo@apple.com>
fourthTier: Clean up AbstractValue
......
......@@ -435,6 +435,7 @@ javascriptcore_sources += \
Source/JavaScriptCore/interpreter/CallFrameClosure.h \
Source/JavaScriptCore/interpreter/CallFrame.cpp \
Source/JavaScriptCore/interpreter/CallFrame.h \
Source/JavaScriptCore/interpreter/CallFrameInlines.h \
Source/JavaScriptCore/interpreter/Interpreter.cpp \
Source/JavaScriptCore/interpreter/Interpreter.h \
Source/JavaScriptCore/interpreter/JSStack.cpp \
......
......@@ -685,6 +685,7 @@
<ClInclude Include="..\interpreter\AbstractPC.h" />
<ClInclude Include="..\interpreter\CachedCall.h" />
<ClInclude Include="..\interpreter\CallFrame.h" />
<ClInclude Include="..\interpreter\CallFrameInlines.h" />
<ClInclude Include="..\interpreter\CallFrameClosure.h" />
<ClInclude Include="..\interpreter\Interpreter.h" />
<ClInclude Include="..\interpreter\JSStack.h" />
......
......@@ -1211,6 +1211,9 @@
<ClInclude Include="..\interpreter\CallFrame.h">
<Filter>interpreter</Filter>
</ClInclude>
<ClInclude Include="..\interpreter\CallFrameInlines.h">
<Filter>interpreter</Filter>
</ClInclude>
<ClInclude Include="..\interpreter\CallFrameClosure.h">
<Filter>interpreter</Filter>
</ClInclude>
......
......@@ -88,6 +88,21 @@ struct CodeOrigin {
Vector<CodeOrigin> inlineStack() const;
void dump(PrintStream&) const;
static inline bool isHandle(uint32_t bits) { return !!(bits & handleFlag); }
static inline uint32_t encodeHandle(uint32_t bits)
{
ASSERT(!isHandle(bits));
return bits | handleFlag;
}
static inline uint32_t decodeHandle(uint32_t bits)
{
ASSERT(isHandle(bits));
return bits & ~handleFlag;
}
private:
static const uint32_t handleFlag = (1 << 31);
};
struct InlineCallFrame {
......
......@@ -313,7 +313,8 @@ public:
void beginCall(CodeOrigin codeOrigin, CallBeginToken& token)
{
unsigned index = m_exceptionChecks.size();
store32(TrustedImm32(index), tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount)));
unsigned handle = CodeOrigin::encodeHandle(index);
store32(TrustedImm32(handle), tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount)));
token.set(codeOrigin, index);
}
......
/*
* Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
* Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -28,6 +28,7 @@
#if ENABLE(DFG_JIT)
#include "CallFrameInlines.h"
#include "DFGCCallHelpers.h"
#include "DFGScratchRegisterAllocator.h"
#include "DFGSpeculativeJIT.h"
......@@ -466,7 +467,7 @@ static bool tryBuildGetByIDList(ExecState* exec, JSValue baseValue, const Identi
// place that we made it from. It just so happens to be the place that we are at
// right now!
stubJit.store32(
MacroAssembler::TrustedImm32(exec->codeOriginIndexForDFG()),
MacroAssembler::TrustedImm32(exec->locationAsRawBits()),
CCallHelpers::tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount)));
operationCall = stubJit.call();
......
......@@ -26,6 +26,7 @@
#include "config.h"
#include "CallFrame.h"
#include "CallFrameInlines.h"
#include "CodeBlock.h"
#include "Interpreter.h"
#include "Operations.h"
......@@ -41,25 +42,28 @@ JSStack* CallFrame::stack()
#endif
#if USE(JSVALUE32_64)
unsigned CallFrame::bytecodeOffsetForNonDFGCode() const
unsigned CallFrame::locationAsBytecodeOffset() const
{
ASSERT(codeBlock());
ASSERT(hasLocationAsBytecodeOffset());
return currentVPC() - codeBlock()->instructions().begin();
}
void CallFrame::setBytecodeOffsetForNonDFGCode(unsigned offset)
void CallFrame::setLocationAsBytecodeOffset(unsigned offset)
{
ASSERT(codeBlock());
ASSERT(!CodeOrigin::isHandle(offset));
setCurrentVPC(codeBlock()->instructions().begin() + offset);
ASSERT(hasLocationAsBytecodeOffset());
}
#else
Instruction* CallFrame::currentVPC() const
{
return codeBlock()->instructions().begin() + bytecodeOffsetForNonDFGCode();
return codeBlock()->instructions().begin() + locationAsBytecodeOffset();
}
void CallFrame::setCurrentVPC(Instruction* vpc)
{
setBytecodeOffsetForNonDFGCode(vpc - codeBlock()->instructions().begin());
setLocationAsBytecodeOffset(vpc - codeBlock()->instructions().begin());
}
#endif
......@@ -119,7 +123,7 @@ CallFrame* CallFrame::trueCallFrame(AbstractPC pc)
return 0;
}
} else {
unsigned index = codeOriginIndexForDFG();
unsigned index = locationAsCodeOriginIndex();
ASSERT(machineCodeBlock->canGetCodeOrigin(index));
if (!machineCodeBlock->canGetCodeOrigin(index)) {
// See above. In release builds, we try to protect ourselves from crashing even
......
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
* Copyright (C) 2003, 2007, 2008, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2003, 2007, 2008, 2011, 2013 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -113,22 +113,16 @@ namespace JSC {
void clearReturnPC() { registers()[JSStack::ReturnPC] = static_cast<Instruction*>(0); }
#endif
AbstractPC abstractReturnPC(VM& vm) { return AbstractPC(vm, this); }
#if USE(JSVALUE32_64)
unsigned bytecodeOffsetForNonDFGCode() const;
void setBytecodeOffsetForNonDFGCode(unsigned offset);
#else
unsigned bytecodeOffsetForNonDFGCode() const
{
ASSERT(codeBlock());
return this[JSStack::ArgumentCount].tag();
}
void setBytecodeOffsetForNonDFGCode(unsigned offset)
{
ASSERT(codeBlock());
this[JSStack::ArgumentCount].tag() = static_cast<int32_t>(offset);
}
#endif
bool hasLocationAsBytecodeOffset() const;
bool hasLocationAsCodeOriginIndex() const;
unsigned locationAsRawBits() const;
unsigned locationAsBytecodeOffset() const;
unsigned locationAsCodeOriginIndex() const;
void setLocationAsRawBits(unsigned);
void setLocationAsBytecodeOffset(unsigned);
Register* frameExtent()
{
......@@ -141,7 +135,6 @@ namespace JSC {
#if ENABLE(DFG_JIT)
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
......
/*
* Copyright (C) 2013 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.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
* 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 CallFrameInlines_h
#define CallFrameInlines_h
#include "CallFrame.h"
#include "CodeOrigin.h"
namespace JSC {
inline bool CallFrame::hasLocationAsBytecodeOffset() const
{
return !CodeOrigin::isHandle(locationAsRawBits());
}
inline bool CallFrame::hasLocationAsCodeOriginIndex() const
{
return CodeOrigin::isHandle(locationAsRawBits());
}
inline unsigned CallFrame::locationAsRawBits() const
{
return this[JSStack::ArgumentCount].tag();
}
inline void CallFrame::setLocationAsRawBits(unsigned bits)
{
this[JSStack::ArgumentCount].tag() = static_cast<int32_t>(bits);
}
#if USE(JSVALUE64)
inline unsigned CallFrame::locationAsBytecodeOffset() const
{
ASSERT(hasLocationAsBytecodeOffset());
ASSERT(codeBlock());
return locationAsRawBits();
}
inline void CallFrame::setLocationAsBytecodeOffset(unsigned offset)
{
ASSERT(codeBlock());
setLocationAsRawBits(offset);
ASSERT(hasLocationAsBytecodeOffset());
}
#endif // USE(JSVALUE64)
inline unsigned CallFrame::locationAsCodeOriginIndex() const
{
ASSERT(hasLocationAsCodeOriginIndex());
ASSERT(codeBlock());
return CodeOrigin::decodeHandle(locationAsRawBits());
}
} // namespace JSC
#endif // CallFrameInlines_h
......@@ -34,6 +34,7 @@
#include "BatchedTransitionOptimizer.h"
#include "CallFrame.h"
#include "CallFrameClosure.h"
#include "CallFrameInlines.h"
#include "CodeBlock.h"
#include "Heap.h"
#include "Debugger.h"
......@@ -474,9 +475,9 @@ static unsigned getBytecodeOffsetForCallFrame(CallFrame* callFrame)
return 0;
#if ENABLE(DFG_JIT)
if (JITCode::isOptimizingJIT(codeBlock->jitType()))
return codeBlock->codeOrigin(callFrame->codeOriginIndexForDFG()).bytecodeIndex;
return codeBlock->codeOrigin(callFrame->locationAsCodeOriginIndex()).bytecodeIndex;
#endif
return callFrame->bytecodeOffsetForNonDFGCode();
return callFrame->locationAsBytecodeOffset();
}
static CallFrame* getCallerInfo(VM* vm, CallFrame* callFrame, unsigned& bytecodeOffset, CodeBlock*& caller)
......@@ -501,14 +502,14 @@ static CallFrame* getCallerInfo(VM* vm, CallFrame* callFrame, unsigned& bytecode
if (wasCalledByHost) {
#if ENABLE(DFG_JIT)
if (callerCodeBlock && JITCode::isOptimizingJIT(callerCodeBlock->jitType())) {
unsigned codeOriginIndex = callFrame->callerFrame()->removeHostCallFrameFlag()->codeOriginIndexForDFG();
unsigned codeOriginIndex = callFrame->callerFrame()->removeHostCallFrameFlag()->locationAsCodeOriginIndex();
CodeOrigin origin = callerCodeBlock->codeOrigin(codeOriginIndex);
bytecodeOffset = origin.bytecodeIndex;
if (InlineCallFrame* inlineCallFrame = origin.inlineCallFrame)
callerCodeBlock = inlineCallFrame->baselineCodeBlock();
} else
#endif
bytecodeOffset = trueCallerFrame->bytecodeOffsetForNonDFGCode();
bytecodeOffset = trueCallerFrame->locationAsBytecodeOffset();
} else {
#if ENABLE(DFG_JIT)
if (callFrame->isInlineCallFrame()) {
......
......@@ -36,6 +36,7 @@
#include "Arguments.h"
#include "ArrayConstructor.h"
#include "CallFrame.h"
#include "CallFrameInlines.h"
#include "CodeBlock.h"
#include "CodeProfiling.h"
#include "CommonSlowPaths.h"
......@@ -1689,7 +1690,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
JSObject* object = asObject(baseValue);
bool didOptimize = false;
unsigned bytecodeOffset = callFrame->bytecodeOffsetForNonDFGCode();
unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
ASSERT(bytecodeOffset);
ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
ASSERT(!byValInfo.stubRoutine);
......@@ -1823,7 +1824,7 @@ DEFINE_STUB_FUNCTION(void, op_put_by_val)
JSObject* object = asObject(baseValue);
bool didOptimize = false;
unsigned bytecodeOffset = callFrame->bytecodeOffsetForNonDFGCode();
unsigned bytecodeOffset = callFrame->locationAsBytecodeOffset();
ASSERT(bytecodeOffset);
ByValInfo& byValInfo = callFrame->codeBlock()->getByValInfo(bytecodeOffset - 1);
ASSERT(!byValInfo.stubRoutine);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment