Title: [99148] trunk
Revision
99148
Author
[email protected]
Date
2011-11-03 01:06:42 -0700 (Thu, 03 Nov 2011)

Log Message

Source/_javascript_Core: DFG inlining breaks function.arguments[something] if the argument being
retrieved was subjected to DFG's unboxing optimizations
https://bugs.webkit.org/show_bug.cgi?id=71436

Reviewed by Oliver Hunt.
        
This makes inlined arguments retrieval use some of the same machinery as
OSR to determine where from, and how, to retrieve a value that the DFG
might have somehow squirreled away while the old JIT would put it in its
obvious location, using an obvious format.
        
To that end, previously DFG-internal notions such as DataFormat,
VirtualRegister, and ValueRecovery are now in bytecode/ since they are
stored as part of InlineCallFrames.

* bytecode/CodeOrigin.h:
* dfg/DFGAbstractState.cpp:
(JSC::DFG::AbstractState::execute):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleInlining):
(JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
* dfg/DFGJITCompiler32_64.cpp:
(JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
* dfg/DFGNode.h:
* dfg/DFGPropagator.cpp:
(JSC::DFG::Propagator::propagateNodePredictions):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* interpreter/CallFrame.cpp:
(JSC::CallFrame::trueCallerFrame):
* interpreter/CallFrame.h:
(JSC::ExecState::inlineCallFrame):
* interpreter/Register.h:
(JSC::Register::asInlineCallFrame):
(JSC::Register::unboxedInt32):
(JSC::Register::unboxedBoolean):
(JSC::Register::unboxedCell):
* runtime/Arguments.h:
(JSC::Arguments::finishCreationAndCopyRegisters):

LayoutTests: DFG inlining breaks function.arguments[something] if the argument being
retrieved was subjected to DFG's unboxing optimizations
https://bugs.webkit.org/show_bug.cgi?id=71436        

Reviewed by Oliver Hunt.

* fast/js/dfg-inline-arguments-int32-expected.txt: Added.
* fast/js/dfg-inline-arguments-int32.html: Added.
* fast/js/script-tests/dfg-inline-arguments-int32.js: Added.
(foo):
(bar):
(baz):
(argsToStr):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (99147 => 99148)


--- trunk/LayoutTests/ChangeLog	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/LayoutTests/ChangeLog	2011-11-03 08:06:42 UTC (rev 99148)
@@ -1,3 +1,19 @@
+2011-11-02  Filip Pizlo  <[email protected]>
+
+        DFG inlining breaks function.arguments[something] if the argument being
+        retrieved was subjected to DFG's unboxing optimizations
+        https://bugs.webkit.org/show_bug.cgi?id=71436        
+
+        Reviewed by Oliver Hunt.
+
+        * fast/js/dfg-inline-arguments-int32-expected.txt: Added.
+        * fast/js/dfg-inline-arguments-int32.html: Added.
+        * fast/js/script-tests/dfg-inline-arguments-int32.js: Added.
+        (foo):
+        (bar):
+        (baz):
+        (argsToStr):
+
 2011-11-02  Adam Barth  <[email protected]>
 
         CSP should handle empty URLs as agreed at TPAC

Added: trunk/LayoutTests/fast/js/dfg-inline-arguments-int32-expected.txt (0 => 99148)


--- trunk/LayoutTests/fast/js/dfg-inline-arguments-int32-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-inline-arguments-int32-expected.txt	2011-11-03 08:06:42 UTC (rev 99148)
@@ -0,0 +1,209 @@
+This tests that inlining preserves function.arguments functionality if the arguments were represented as unboxed int32.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 1, 2, 3"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 2, 3, 4"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 3, 4, 5"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 4, 5, 6"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 5, 6, 7"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 6, 7, 8"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 7, 8, 9"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 8, 9, 10"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 9, 10, 11"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 10, 11, 12"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 11, 12, 13"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 12, 13, 14"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 13, 14, 15"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 14, 15, 16"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 15, 16, 17"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 16, 17, 18"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 17, 18, 19"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 18, 19, 20"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 19, 20, 21"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 20, 21, 22"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 21, 22, 23"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 22, 23, 24"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 23, 24, 25"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 24, 25, 26"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 25, 26, 27"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 26, 27, 28"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 27, 28, 29"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 28, 29, 30"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 29, 30, 31"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 30, 31, 32"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 31, 32, 33"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 32, 33, 34"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 33, 34, 35"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 34, 35, 36"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 35, 36, 37"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 36, 37, 38"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 37, 38, 39"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 38, 39, 40"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 39, 40, 41"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 40, 41, 42"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 41, 42, 43"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 42, 43, 44"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 43, 44, 45"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 44, 45, 46"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 45, 46, 47"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 46, 47, 48"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 47, 48, 49"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 48, 49, 50"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 49, 50, 51"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 50, 51, 52"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 51, 52, 53"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 52, 53, 54"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 53, 54, 55"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 54, 55, 56"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 55, 56, 57"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 56, 57, 58"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 57, 58, 59"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 58, 59, 60"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 59, 60, 61"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 60, 61, 62"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 61, 62, 63"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 62, 63, 64"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 63, 64, 65"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 64, 65, 66"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 65, 66, 67"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 66, 67, 68"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 67, 68, 69"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 68, 69, 70"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 69, 70, 71"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 70, 71, 72"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 71, 72, 73"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 72, 73, 74"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 73, 74, 75"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 74, 75, 76"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 75, 76, 77"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 76, 77, 78"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 77, 78, 79"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 78, 79, 80"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 79, 80, 81"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 80, 81, 82"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 81, 82, 83"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 82, 83, 84"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 83, 84, 85"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 84, 85, 86"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 85, 86, 87"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 86, 87, 88"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 87, 88, 89"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 88, 89, 90"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 89, 90, 91"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 90, 91, 92"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 91, 92, 93"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 92, 93, 94"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 93, 94, 95"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 94, 95, 96"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 95, 96, 97"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 96, 97, 98"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 97, 98, 99"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 98, 99, 100"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 99, 100, 101"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 100, 101, 102"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 101, 102, 103"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 102, 103, 104"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 103, 104, 105"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 104, 105, 106"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 105, 106, 107"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 106, 107, 108"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 107, 108, 109"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 108, 109, 110"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 109, 110, 111"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 110, 111, 112"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 111, 112, 113"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 112, 113, 114"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 113, 114, 115"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 114, 115, 116"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 115, 116, 117"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 116, 117, 118"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 117, 118, 119"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 118, 119, 120"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 119, 120, 121"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 120, 121, 122"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 121, 122, 123"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 122, 123, 124"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 123, 124, 125"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 124, 125, 126"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 125, 126, 127"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 126, 127, 128"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 127, 128, 129"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 128, 129, 130"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 129, 130, 131"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 130, 131, 132"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 131, 132, 133"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 132, 133, 134"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 133, 134, 135"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 134, 135, 136"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 135, 136, 137"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 136, 137, 138"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 137, 138, 139"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 138, 139, 140"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 139, 140, 141"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 140, 141, 142"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 141, 142, 143"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 142, 143, 144"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 143, 144, 145"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 144, 145, 146"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 145, 146, 147"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 146, 147, 148"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 147, 148, 149"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 148, 149, 150"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 149, 150, 151"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 150, 151, 152"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 151, 152, 153"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 152, 153, 154"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 153, 154, 155"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 154, 155, 156"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 155, 156, 157"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 156, 157, 158"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 157, 158, 159"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 158, 159, 160"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 159, 160, 161"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 160, 161, 162"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 161, 162, 163"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 162, 163, 164"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 163, 164, 165"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 164, 165, 166"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 165, 166, 167"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 166, 167, 168"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 167, 168, 169"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 168, 169, 170"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 169, 170, 171"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 170, 171, 172"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 171, 172, 173"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 172, 173, 174"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 173, 174, 175"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 174, 175, 176"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 175, 176, 177"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 176, 177, 178"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 177, 178, 179"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 178, 179, 180"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 179, 180, 181"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 180, 181, 182"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 181, 182, 183"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 182, 183, 184"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 183, 184, 185"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 184, 185, 186"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 185, 186, 187"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 186, 187, 188"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 187, 188, 189"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 188, 189, 190"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 189, 190, 191"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 190, 191, 192"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 191, 192, 193"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 192, 193, 194"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 193, 194, 195"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 194, 195, 196"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 195, 196, 197"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 196, 197, 198"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 197, 198, 199"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 198, 199, 200"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 199, 200, 201"
+PASS argsToStr(baz(__i + 1, __i + 2, __i + 3)) is "[object Arguments]: 200, 201, 202"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/js/dfg-inline-arguments-int32.html (0 => 99148)


--- trunk/LayoutTests/fast/js/dfg-inline-arguments-int32.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-inline-arguments-int32.html	2011-11-03 08:06:42 UTC (rev 99148)
@@ -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/fast/js/script-tests/dfg-inline-arguments-int32.js (0 => 99148)


--- trunk/LayoutTests/fast/js/script-tests/dfg-inline-arguments-int32.js	                        (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-inline-arguments-int32.js	2011-11-03 08:06:42 UTC (rev 99148)
@@ -0,0 +1,30 @@
+description(
+"This tests that inlining preserves function.arguments functionality if the arguments were represented as unboxed int32."
+);
+
+function foo() {
+    return bar.arguments;
+}
+
+function bar(a,b,c) {
+    return foo(a,b,c);
+}
+
+function baz(a,b,c) {
+    return bar(a,b,c);
+}
+
+function argsToStr(args) {
+    var str = args + ": ";
+    for (var i = 0; i < args.length; ++i) {
+        if (i)
+            str += ", ";
+        str += args[i];
+    }
+    return str;
+}
+
+for (var __i = 0; __i < 200; ++__i)
+    shouldBe("argsToStr(baz(__i + 1, __i + 2, __i + 3))", "\"[object Arguments]: " + (__i + 1) + ", " + (__i + 2) + ", " + (__i + 3) + "\"");
+
+var successfullyParsed = true;

Modified: trunk/Source/_javascript_Core/ChangeLog (99147 => 99148)


--- trunk/Source/_javascript_Core/ChangeLog	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-11-03 08:06:42 UTC (rev 99148)
@@ -1,5 +1,51 @@
 2011-11-02  Filip Pizlo  <[email protected]>
 
+        DFG inlining breaks function.arguments[something] if the argument being
+        retrieved was subjected to DFG's unboxing optimizations
+        https://bugs.webkit.org/show_bug.cgi?id=71436
+
+        Reviewed by Oliver Hunt.
+        
+        This makes inlined arguments retrieval use some of the same machinery as
+        OSR to determine where from, and how, to retrieve a value that the DFG
+        might have somehow squirreled away while the old JIT would put it in its
+        obvious location, using an obvious format.
+        
+        To that end, previously DFG-internal notions such as DataFormat,
+        VirtualRegister, and ValueRecovery are now in bytecode/ since they are
+        stored as part of InlineCallFrames.
+
+        * bytecode/CodeOrigin.h:
+        * dfg/DFGAbstractState.cpp:
+        (JSC::DFG::AbstractState::execute):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleInlining):
+        (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
+        * dfg/DFGJITCompiler32_64.cpp:
+        (JSC::DFG::JITCompiler::exitSpeculativeWithOSR):
+        * dfg/DFGNode.h:
+        * dfg/DFGPropagator.cpp:
+        (JSC::DFG::Propagator::propagateNodePredictions):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * interpreter/CallFrame.cpp:
+        (JSC::CallFrame::trueCallerFrame):
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::inlineCallFrame):
+        * interpreter/Register.h:
+        (JSC::Register::asInlineCallFrame):
+        (JSC::Register::unboxedInt32):
+        (JSC::Register::unboxedBoolean):
+        (JSC::Register::unboxedCell):
+        * runtime/Arguments.h:
+        (JSC::Arguments::finishCreationAndCopyRegisters):
+
+2011-11-02  Filip Pizlo  <[email protected]>
+
         ValueRecovery should be moved out of the DFG JIT
         https://bugs.webkit.org/show_bug.cgi?id=71439
 

Modified: trunk/Source/_javascript_Core/bytecode/CodeOrigin.h (99147 => 99148)


--- trunk/Source/_javascript_Core/bytecode/CodeOrigin.h	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/bytecode/CodeOrigin.h	2011-11-03 08:06:42 UTC (rev 99148)
@@ -26,6 +26,7 @@
 #ifndef CodeOrigin_h
 #define CodeOrigin_h
 
+#include "ValueRecovery.h"
 #include "WriteBarrier.h"
 #include <wtf/StdLibExtras.h>
 #include <wtf/Vector.h>
@@ -75,11 +76,11 @@
 };
 
 struct InlineCallFrame {
+    Vector<ValueRecovery> arguments;
     WriteBarrier<ExecutableBase> executable;
     WriteBarrier<JSFunction> callee;
     CodeOrigin caller;
-    unsigned stackOffset;
-    unsigned numArgumentsIncludingThis : 31;
+    unsigned stackOffset : 31;
     bool isCall : 1;
 };
 

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -659,6 +659,7 @@
         break;
             
     case Phantom:
+    case InlineStart:
         break;
     }
     

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -1003,7 +1003,11 @@
     // This is where the actual inlining really happens.
     unsigned oldIndex = m_currentIndex;
     m_currentIndex = 0;
+
+    addToGraph(InlineStart);
+    
     parseCodeBlock();
+    
     m_currentIndex = oldIndex;
     
     // If the inlined code created some new basic blocks, then we have linking to do.
@@ -2326,7 +2330,7 @@
         inlineCallFrame.stackOffset = inlineCallFrameStart + RegisterFile::CallFrameHeaderSize;
         inlineCallFrame.callee.set(*byteCodeParser->m_globalData, byteCodeParser->m_codeBlock->ownerExecutable(), callee);
         inlineCallFrame.caller = byteCodeParser->currentCodeOrigin();
-        inlineCallFrame.numArgumentsIncludingThis = codeBlock->m_numParameters;
+        inlineCallFrame.arguments.resize(codeBlock->m_numParameters); // Set the number of arguments including this, but don't configure the value recoveries, yet.
         inlineCallFrame.isCall = isCall(kind);
         byteCodeParser->m_codeBlock->inlineCallFrames().append(inlineCallFrame);
         m_inlineCallFrame = &byteCodeParser->m_codeBlock->inlineCallFrames().last();

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -783,7 +783,7 @@
         storePtr(TrustedImmPtr(inlineCallFrame->callee->scope()), addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ScopeChain)));
         storePtr(callerFrameGPR, addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame)));
         storePtr(TrustedImmPtr(jumpTarget), addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ReturnPC)));
-        storePtr(TrustedImmPtr(JSValue::encode(jsNumber(inlineCallFrame->numArgumentsIncludingThis))), addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount)));
+        storePtr(TrustedImmPtr(JSValue::encode(jsNumber(inlineCallFrame->arguments.size()))), addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount)));
         storePtr(TrustedImmPtr(inlineCallFrame->callee.get()), addressFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee)));
     }
     

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler32_64.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -528,7 +528,7 @@
         storePtr(callerFrameGPR, payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::CallerFrame)));
         storePtr(TrustedImmPtr(jumpTarget), payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ReturnPC)));
         store32(Imm32(JSValue::Int32Tag), tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount)));
-        store32(Imm32(inlineCallFrame->numArgumentsIncludingThis), payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount)));
+        store32(Imm32(inlineCallFrame->arguments.size()), payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::ArgumentCount)));
         store32(Imm32(JSValue::CellTag), tagFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee)));
         storePtr(TrustedImmPtr(inlineCallFrame->callee.get()), payloadFor((VirtualRegister)(inlineCallFrame->stackOffset + RegisterFile::Callee)));
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGNode.h	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h	2011-11-03 08:06:42 UTC (rev 99148)
@@ -220,6 +220,11 @@
     /* Marker for arguments being set. */\
     macro(SetArgument, 0) \
     \
+    /* Hint that inlining begins here. No code is generated for this node. It's only */\
+    /* used for copying OSR data into inline frame data, to support reification of */\
+    /* call frames of inlined functions. */\
+    macro(InlineStart, 0) \
+    \
     /* Nodes for bitwise operations. */\
     macro(BitAnd, NodeResultInt32) \
     macro(BitOr, NodeResultInt32) \

Modified: trunk/Source/_javascript_Core/dfg/DFGPropagator.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGPropagator.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGPropagator.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -607,8 +607,9 @@
         case PutByOffset:
             break;
             
-        // This gets ignored because it doesn't do anything.
+        // These gets ignored because it doesn't do anything.
         case Phantom:
+        case InlineStart:
             break;
 #else
         default:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -263,8 +263,28 @@
 #if DFG_ENABLE(DEBUG_VERBOSE)
             fprintf(stderr, "SpeculativeJIT skipping Node @%d (bc#%u) at JIT offset 0x%x     ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
 #endif
-            if (node.op == SetLocal)
+            switch (node.op) {
+            case SetLocal:
                 compileMovHint(node);
+                break;
+
+            case InlineStart: {
+                InlineCallFrame* inlineCallFrame = node.codeOrigin.inlineCallFrame;
+                unsigned argumentsStart = inlineCallFrame->stackOffset - RegisterFile::CallFrameHeaderSize - inlineCallFrame->arguments.size();
+                for (unsigned i = 0; i < inlineCallFrame->arguments.size(); ++i) {
+                    ValueRecovery recovery = computeValueRecoveryFor(m_variables[argumentsStart + i]);
+                    // The recovery cannot point to registers, since the call frame reification isn't
+                    // as smart as OSR, so it can't handle that. The exception is the this argument,
+                    // which we don't really need to be able to recover.
+                    ASSERT(!i || !recovery.isInRegisters());
+                    inlineCallFrame->arguments[i] = recovery;
+                }
+                break;
+            }
+                
+            default:
+                break;
+            }
         } else {
             
 #if DFG_ENABLE(DEBUG_VERBOSE)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -2491,6 +2491,10 @@
         // This is a no-op.
         noResult(m_compileIndex);
         break;
+        
+    case InlineStart:
+        ASSERT_NOT_REACHED();
+        break;
     }
 
     if (node.hasResult() && node.mustGenerate())

Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.cpp (99147 => 99148)


--- trunk/Source/_javascript_Core/interpreter/CallFrame.cpp	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.cpp	2011-11-03 08:06:42 UTC (rev 99148)
@@ -110,7 +110,7 @@
             inlinedCaller->setCallerFrame(machineCaller);
         
         inlinedCaller->setInlineCallFrame(inlineCallFrame);
-        inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->numArgumentsIncludingThis);
+        inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->arguments.size());
         inlinedCaller->setCallee(calleeAsFunction);
         
         inlineCallFrame = nextInlineCallFrame;

Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.h (99147 => 99148)


--- trunk/Source/_javascript_Core/interpreter/CallFrame.h	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.h	2011-11-03 08:06:42 UTC (rev 99148)
@@ -105,7 +105,16 @@
         ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); }
 #endif
 #if ENABLE(DFG_JIT)
-        InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].inlineCallFrame(); }
+        InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].asInlineCallFrame(); }
+#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
+        // #if's, we make a dummy implementation available anyway.
+        InlineCallFrame* inlineCallFrame() const
+        {
+            ASSERT_NOT_REACHED();
+            return 0;
+        }
 #endif
 #if ENABLE(INTERPRETER)
         Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }

Modified: trunk/Source/_javascript_Core/interpreter/Register.h (99147 => 99148)


--- trunk/Source/_javascript_Core/interpreter/Register.h	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/interpreter/Register.h	2011-11-03 08:06:42 UTC (rev 99148)
@@ -71,7 +71,10 @@
         JSPropertyNameIterator* propertyNameIterator() const;
         ScopeChainNode* scopeChain() const;
         Instruction* vPC() const;
-        InlineCallFrame* inlineCallFrame() const;
+        InlineCallFrame* asInlineCallFrame() const;
+        int32_t unboxedInt32() const;
+        bool unboxedBoolean() const;
+        JSCell* unboxedCell() const;
 
         static Register withInt(int32_t i)
         {
@@ -88,6 +91,7 @@
             CodeBlock* codeBlock;
             Instruction* vPC;
             InlineCallFrame* inlineCallFrame;
+            EncodedValueDescriptor encodedValue;
         } u;
     };
 
@@ -165,11 +169,30 @@
         return u.vPC;
     }
 
-    ALWAYS_INLINE InlineCallFrame* Register::inlineCallFrame() const
+    ALWAYS_INLINE InlineCallFrame* Register::asInlineCallFrame() const
     {
         return u.inlineCallFrame;
     }
+        
+    ALWAYS_INLINE int32_t Register::unboxedInt32() const
+    {
+        return u.encodedValue.asBits.payload;
+    }
 
+    ALWAYS_INLINE bool Register::unboxedBoolean() const
+    {
+        return !!u.encodedValue.asBits.payload;
+    }
+
+    ALWAYS_INLINE JSCell* Register::unboxedCell() const
+    {
+#if USE(JSVALUE64)
+        return u.encodedValue.ptr;
+#else
+        return bitwise_cast<JSCell*>(u.encodedValue.asBits.payload);
+#endif
+    }
+
 } // namespace JSC
 
 namespace WTF {

Modified: trunk/Source/_javascript_Core/runtime/Arguments.h (99147 => 99148)


--- trunk/Source/_javascript_Core/runtime/Arguments.h	2011-11-03 07:37:34 UTC (rev 99147)
+++ trunk/Source/_javascript_Core/runtime/Arguments.h	2011-11-03 08:06:42 UTC (rev 99148)
@@ -259,8 +259,43 @@
             size_t registerArraySize = d->numParameters;
             
             OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]);
-            for (size_t i = 0; i < registerArraySize; ++i)
-                registerArray[i].set(callFrame->globalData(), this, callFrame->registers()[i - registerOffset].jsValue());
+            if (callFrame->isInlineCallFrame()) {
+                InlineCallFrame* inlineCallFrame = callFrame->inlineCallFrame();
+                for (size_t i = 0; i < registerArraySize; ++i) {
+                    ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
+                    // In the future we'll support displaced recoveries (indicating that the
+                    // argument was flushed to a different location), but for now we don't do
+                    // that so this code will fail if that were to happen. On the other hand,
+                    // it's much less likely that we'll support in-register recoveries since
+                    // this code does not (easily) have access to registers.
+                    JSValue value;
+                    Register* location = callFrame->registers() + i - registerOffset;
+                    switch (recovery.technique()) {
+                    case AlreadyInRegisterFile:
+                        value = location->jsValue();
+                        break;
+                    case AlreadyInRegisterFileAsUnboxedInt32:
+                        value = jsNumber(location->unboxedInt32());
+                        break;
+                    case AlreadyInRegisterFileAsUnboxedCell:
+                        value = location->unboxedCell();
+                        break;
+                    case AlreadyInRegisterFileAsUnboxedBoolean:
+                        value = jsBoolean(location->unboxedBoolean());
+                        break;
+                    case Constant:
+                        value = recovery.constant();
+                        break;
+                    default:
+                        ASSERT_NOT_REACHED();
+                        break;
+                    }
+                    registerArray[i].set(callFrame->globalData(), this, value);
+                }
+            } else {
+                for (size_t i = 0; i < registerArraySize; ++i)
+                    registerArray[i].set(callFrame->globalData(), this, callFrame->registers()[i - registerOffset].jsValue());
+            }
             d->registers = registerArray.get() + d->numParameters + RegisterFile::CallFrameHeaderSize;
             d->registerArray = registerArray.release();
         }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to