Diff
Modified: trunk/LayoutTests/ChangeLog (156228 => 156229)
--- trunk/LayoutTests/ChangeLog 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/LayoutTests/ChangeLog 2013-09-21 17:40:35 UTC (rev 156229)
@@ -1,3 +1,18 @@
+2013-09-21 Filip Pizlo <[email protected]>
+
+ Get rid of IsInlinedCodeTag and its associated methods since it's unused
+ https://bugs.webkit.org/show_bug.cgi?id=121737
+
+ Reviewed by Sam Weinig.
+
+ * js/dfg-inline-arguments-capture-throw-exception-expected.txt: Added.
+ * js/dfg-inline-arguments-capture-throw-exception.html: Added.
+ * js/script-tests/dfg-inline-arguments-capture-throw-exception.js: Added.
+ (foo):
+ (bar):
+ (makeF):
+ (recurse):
+
2013-09-20 Ryosuke Niwa <[email protected]>
Bad cast from CSSInitialValue to CSSValueList
Added: trunk/LayoutTests/js/dfg-inline-arguments-capture-throw-exception-expected.txt (0 => 156229)
--- trunk/LayoutTests/js/dfg-inline-arguments-capture-throw-exception-expected.txt (rev 0)
+++ trunk/LayoutTests/js/dfg-inline-arguments-capture-throw-exception-expected.txt 2013-09-21 17:40:35 UTC (rev 156229)
@@ -0,0 +1,14 @@
+Tests what happens when you have an inlined function that captures arguments and then throws an exception.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS theException is "The exception 100"
+PASS capturedArgs.length is 4
+PASS capturedArgs[1] is 1
+PASS capturedArgs[2] is 2
+PASS capturedArgs[3] is 3
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/dfg-inline-arguments-capture-throw-exception.html (0 => 156229)
--- trunk/LayoutTests/js/dfg-inline-arguments-capture-throw-exception.html (rev 0)
+++ trunk/LayoutTests/js/dfg-inline-arguments-capture-throw-exception.html 2013-09-21 17:40:35 UTC (rev 156229)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/script-tests/dfg-inline-arguments-capture-throw-exception.js (0 => 156229)
--- trunk/LayoutTests/js/script-tests/dfg-inline-arguments-capture-throw-exception.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/dfg-inline-arguments-capture-throw-exception.js 2013-09-21 17:40:35 UTC (rev 156229)
@@ -0,0 +1,50 @@
+description(
+"Tests what happens when you have an inlined function that captures arguments and then throws an exception."
+);
+
+var capturedArgs;
+
+function foo(f, a, b, c) {
+ var result = 0;
+ capturedArgs = arguments;
+ for (var i = 1; i < arguments.length; ++i)
+ result += arguments[i] + f();
+ return result + a + b + c;
+}
+
+var shouldThrow = false;
+
+function bar(f) {
+ return foo(f, 1, 2, 3);
+}
+
+function makeF(i) {
+ return eval("(function() { if (shouldThrow) throw \"The exception " + i + "\"; return 0; })");
+}
+
+noInline(bar);
+for (var i = 0; i < 100; i = dfgIncrement({f:bar, i:i + 1, n:100}))
+ bar(makeF(i));
+
+function recurse(n) {
+ if (!n)
+ return 42;
+ return recurse(n - 1);
+}
+
+shouldThrow = true;
+
+var theException;
+try {
+ bar(makeF(100));
+ testFailed("bar() didn't throw an exception.");
+} catch (e) {
+ theException = e;
+}
+
+shouldBe("theException", "\"The exception 100\"");
+recurse(1000);
+shouldBe("capturedArgs.length", "4");
+shouldBe("capturedArgs[1]", "1");
+shouldBe("capturedArgs[2]", "2");
+shouldBe("capturedArgs[3]", "3");
Modified: trunk/Source/_javascript_Core/ChangeLog (156228 => 156229)
--- trunk/Source/_javascript_Core/ChangeLog 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-09-21 17:40:35 UTC (rev 156229)
@@ -1,3 +1,30 @@
+2013-09-21 Filip Pizlo <[email protected]>
+
+ Get rid of IsInlinedCodeTag and its associated methods since it's unused
+ https://bugs.webkit.org/show_bug.cgi?id=121737
+
+ Reviewed by Sam Weinig.
+
+ This was meant to be easy, but I kept wondering if it was safe to remove the
+ inline call frame check in Arguments::tearOff(). The check was clearly dead
+ since the bit wasn't being set anywhere.
+
+ It turns out that the unwindCallFrame() function was relying on tearOff()
+ doing the right thing for inlined code, but it wasn't even passing it an
+ inline call frame. I fixed this by having unwindCallFrame() inlining check,
+ while also making sure that the code uses the right operand index for the
+ arguments register.
+
+ * interpreter/CallFrame.h:
+ * interpreter/CallFrameInlines.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::unwindCallFrame):
+ * interpreter/StackVisitor.cpp:
+ (JSC::StackVisitor::Frame::r):
+ * interpreter/StackVisitor.h:
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::tearOff):
+
2013-09-20 Mark Hahnenberg <[email protected]>
(un)shiftCountWithAnyIndexingType will start over in the middle of copying if it sees a hole
Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.h (156228 => 156229)
--- trunk/Source/_javascript_Core/interpreter/CallFrame.h 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.h 2013-09-21 17:40:35 UTC (rev 156229)
@@ -134,30 +134,23 @@
static inline bool isCodeOriginIndex(uint32_t bits);
static inline uint32_t encodeAsCodeOriginIndex(uint32_t bits);
- static inline bool isInlinedCode(uint32_t bits);
- static inline uint32_t encodeAsInlinedCode(uint32_t bits);
-
private:
enum TypeTag {
BytecodeLocationTag = 0,
CodeOriginIndexTag = 1,
- IsInlinedCodeTag = 2,
};
static inline uint32_t encode(TypeTag, uint32_t bits);
- static const uint32_t s_mask = 0x3;
+ static const uint32_t s_mask = 0x1;
#if USE(JSVALUE64)
- static const uint32_t s_shift = 30;
+ static const uint32_t s_shift = 31;
static const uint32_t s_shiftedMask = s_mask << s_shift;
#else
- static const uint32_t s_shift = 2;
+ static const uint32_t s_shift = 1;
#endif
};
- bool isInlinedFrame() const;
- void setIsInlinedFrame();
-
bool hasLocationAsBytecodeOffset() const;
bool hasLocationAsCodeOriginIndex() const;
Modified: trunk/Source/_javascript_Core/interpreter/CallFrameInlines.h (156228 => 156229)
--- trunk/Source/_javascript_Core/interpreter/CallFrameInlines.h 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/Source/_javascript_Core/interpreter/CallFrameInlines.h 2013-09-21 17:40:35 UTC (rev 156229)
@@ -80,13 +80,6 @@
return encodedBits;
}
-inline uint32_t CallFrame::Location::encodeAsInlinedCode(uint32_t bits)
-{
- uint32_t encodedBits = encode(IsInlinedCodeTag, bits);
- ASSERT(isInlinedCode(encodedBits));
- return encodedBits;
-}
-
inline bool CallFrame::Location::isBytecodeLocation(uint32_t bits)
{
return !isCodeOriginIndex(bits);
@@ -102,29 +95,6 @@
#endif
}
-inline bool CallFrame::Location::isInlinedCode(uint32_t bits)
-{
-#if USE(JSVALUE64)
- TypeTag tag = static_cast<TypeTag>(bits >> s_shift);
- return !!(tag & IsInlinedCodeTag);
-#else
- return !!(bits & IsInlinedCodeTag);
-#endif
-}
-
-inline bool CallFrame::isInlinedFrame() const
-{
- return Location::isInlinedCode(locationAsRawBits());
-}
-
-inline void CallFrame::setIsInlinedFrame()
-{
- ASSERT(codeBlock());
- uint32_t bits = Location::encodeAsInlinedCode(locationAsRawBits());
- setLocationAsRawBits(bits);
- ASSERT(isInlinedFrame());
-}
-
inline bool CallFrame::hasLocationAsBytecodeOffset() const
{
return Location::isBytecodeLocation(locationAsRawBits());
Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (156228 => 156229)
--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp 2013-09-21 17:40:35 UTC (rev 156229)
@@ -407,15 +407,18 @@
JSValue activation;
if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->needsActivation()) {
+ RELEASE_ASSERT(!visitor->isInlinedFrame());
activation = callFrame->uncheckedR(oldCodeBlock->activationRegister()).jsValue();
if (activation)
jsCast<JSActivation*>(activation)->tearOff(*scope->vm());
}
if (oldCodeBlock->codeType() == FunctionCode && oldCodeBlock->usesArguments()) {
- if (JSValue arguments = callFrame->uncheckedR(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
+ if (JSValue arguments = visitor->r(unmodifiedArgumentsRegister(oldCodeBlock->argumentsRegister())).jsValue()) {
if (activation)
jsCast<Arguments*>(arguments)->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
+ else if (visitor->isInlinedFrame())
+ jsCast<Arguments*>(arguments)->tearOff(callFrame, visitor->inlineCallFrame());
else
jsCast<Arguments*>(arguments)->tearOff(callFrame);
}
Modified: trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp (156228 => 156229)
--- trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/Source/_javascript_Core/interpreter/StackVisitor.cpp 2013-09-21 17:40:35 UTC (rev 156229)
@@ -287,6 +287,16 @@
column = divotColumn + (divotLine ? 1 : codeBlock->firstLineColumnOffset());
}
+Register& StackVisitor::Frame::r(int index)
+{
+ int offset;
+ if (isInlinedFrame())
+ offset = inlineCallFrame()->stackOffset;
+ else
+ offset = 0;
+ return callFrame()->r(offset + index);
+}
+
void StackVisitor::Frame::retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column)
{
CodeBlock* codeBlock = this->codeBlock();
Modified: trunk/Source/_javascript_Core/interpreter/StackVisitor.h (156228 => 156229)
--- trunk/Source/_javascript_Core/interpreter/StackVisitor.h 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/Source/_javascript_Core/interpreter/StackVisitor.h 2013-09-21 17:40:35 UTC (rev 156229)
@@ -39,6 +39,7 @@
class JSFunction;
class JSObject;
class JSScope;
+class Register;
typedef ExecState CallFrame;
@@ -78,6 +79,8 @@
Arguments* arguments();
CallFrame* callFrame() const { return m_callFrame; }
+
+ Register& r(int index);
#ifndef NDEBUG
JS_EXPORT_PRIVATE void print(int indentLevel);
Modified: trunk/Source/_javascript_Core/runtime/Arguments.cpp (156228 => 156229)
--- trunk/Source/_javascript_Core/runtime/Arguments.cpp 2013-09-21 13:45:10 UTC (rev 156228)
+++ trunk/Source/_javascript_Core/runtime/Arguments.cpp 2013-09-21 17:40:35 UTC (rev 156229)
@@ -326,14 +326,8 @@
}
}
- if (!callFrame->isInlinedFrame()) {
- for (size_t i = 0; i < m_numArguments; ++i)
- trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i));
- return;
- }
-
- tearOffForInlineCallFrame(
- callFrame->vm(), callFrame->registers(), callFrame->inlineCallFrame());
+ for (size_t i = 0; i < m_numArguments; ++i)
+ trySetArgument(callFrame->vm(), i, callFrame->argumentAfterCapture(i));
}
void Arguments::didTearOffActivation(ExecState* exec, JSActivation* activation)