Skip to content

Commit

Permalink
Merge r224539 - AccessCase::generateImpl() should exclude the result …
Browse files Browse the repository at this point in the history
…register when restoring registers after a call.

https://bugs.webkit.org/show_bug.cgi?id=179355
<rdar://problem/35263053>

Reviewed by Saam Barati.

JSTests:

* stress/regress-179355.js: Added.

Source/JavaScriptCore:

In the Transition case in AccessCase::generateImpl(), we were restoring registers
using restoreLiveRegistersFromStackForCall() without excluding the scratchGPR
where we previously stashed the reallocated butterfly.  If the generated code is
under heavy register pressure, scratchGPR could have been from the set of preserved
registers, and hence, would be restored by restoreLiveRegistersFromStackForCall().
As a result, the restoration would trash the butterfly result we stored there.
This patch fixes the issue by excluding the scratchGPR in the restoration.

* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):
  • Loading branch information
Mark Lam authored and carlosgcampos committed Jan 24, 2018
1 parent bc05fce commit 035fd11
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
10 changes: 10 additions & 0 deletions JSTests/ChangeLog
@@ -1,3 +1,13 @@
2017-11-07 Mark Lam <mark.lam@apple.com>

AccessCase::generateImpl() should exclude the result register when restoring registers after a call.
https://bugs.webkit.org/show_bug.cgi?id=179355
<rdar://problem/35263053>

Reviewed by Saam Barati.

* stress/regress-179355.js: Added.

2017-11-02 Filip Pizlo <fpizlo@apple.com>

AI does not correctly model the clobber case of ArithClz32
Expand Down
25 changes: 25 additions & 0 deletions JSTests/stress/regress-179355.js
@@ -0,0 +1,25 @@
var arr0 = [1,2,3,4];
var arr1 = new Array(1000);

Array.prototype.__defineGetter__(1, function() {
[].concat(arr1); //generate to invalid JIT code here?
});

Array.prototype.__defineGetter__(Symbol.isConcatSpreadable, (function() {
for(var i=0;i<10000;i++) {
if(i==0)
arr1[i];
this.x = 1.1;
arr1.legnth = 1;
}
}));

var exception;
try {
arr1[1].toString();
} catch (e) {
exception = e;
}

if (exception != "RangeError: Maximum call stack size exceeded.")
throw "FAILED";
19 changes: 19 additions & 0 deletions Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,22 @@
2017-11-07 Mark Lam <mark.lam@apple.com>

AccessCase::generateImpl() should exclude the result register when restoring registers after a call.
https://bugs.webkit.org/show_bug.cgi?id=179355
<rdar://problem/35263053>

Reviewed by Saam Barati.

In the Transition case in AccessCase::generateImpl(), we were restoring registers
using restoreLiveRegistersFromStackForCall() without excluding the scratchGPR
where we previously stashed the reallocated butterfly. If the generated code is
under heavy register pressure, scratchGPR could have been from the set of preserved
registers, and hence, would be restored by restoreLiveRegistersFromStackForCall().
As a result, the restoration would trash the butterfly result we stored there.
This patch fixes the issue by excluding the scratchGPR in the restoration.

* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):

2017-11-03 Michael Saboff <msaboff@apple.com>

The Abstract Interpreter needs to change similar to clobberize() in r224366
Expand Down
4 changes: 3 additions & 1 deletion Source/JavaScriptCore/bytecode/AccessCase.cpp
Expand Up @@ -945,7 +945,9 @@ void AccessCase::generateImpl(AccessGenerationState& state)
state.emitExplicitExceptionHandler();

noException.link(&jit);
state.restoreLiveRegistersFromStackForCall(spillState);
RegisterSet resultRegisterToExclude;
resultRegisterToExclude.set(scratchGPR);
state.restoreLiveRegistersFromStackForCall(spillState, resultRegisterToExclude);
}
}

Expand Down

0 comments on commit 035fd11

Please sign in to comment.