- Revision
- 266770
- Author
- [email protected]
- Date
- 2020-09-08 20:48:31 -0700 (Tue, 08 Sep 2020)
Log Message
[JSC] returnEarlyFromInfiniteLoopsForFuzzing should return object
https://bugs.webkit.org/show_bug.cgi?id=216289
<rdar://problem/68496533>
Reviewed by Saam Barati.
JSTests:
* stress/construct-return-early-from-infinite-loop-for-fuzzer.js: Added.
(foo):
Source/_javascript_Core:
When returning early with returnEarlyFromInfiniteLoopsForFuzzing, we are returning with undefined.
But this is wrong when the callee is constructor since constructor is strongly assumed that it returns an object.
We should return some object from returnEarlyFromInfiniteLoopsForFuzzing. In this patch, we return global object
associated to this callee instead of undefined
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::finishCreation):
(JSC::CodeBlock::~CodeBlock):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileLoopHint):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_loop_hint):
* llint/LowLevelInterpreter64.asm:
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (266769 => 266770)
--- trunk/JSTests/ChangeLog 2020-09-09 03:32:10 UTC (rev 266769)
+++ trunk/JSTests/ChangeLog 2020-09-09 03:48:31 UTC (rev 266770)
@@ -1,5 +1,16 @@
2020-09-08 Yusuke Suzuki <[email protected]>
+ [JSC] returnEarlyFromInfiniteLoopsForFuzzing should return object
+ https://bugs.webkit.org/show_bug.cgi?id=216289
+ <rdar://problem/68496533>
+
+ Reviewed by Saam Barati.
+
+ * stress/construct-return-early-from-infinite-loop-for-fuzzer.js: Added.
+ (foo):
+
+2020-09-08 Yusuke Suzuki <[email protected]>
+
[JSC] Special property caching should check Structure's cacheability
https://bugs.webkit.org/show_bug.cgi?id=216222
Added: trunk/JSTests/stress/construct-return-early-from-infinite-loop-for-fuzzer.js (0 => 266770)
--- trunk/JSTests/stress/construct-return-early-from-infinite-loop-for-fuzzer.js (rev 0)
+++ trunk/JSTests/stress/construct-return-early-from-infinite-loop-for-fuzzer.js 2020-09-09 03:48:31 UTC (rev 266770)
@@ -0,0 +1,6 @@
+//@ skip if $architecture != "arm64" and $architecture != "x86-64"
+//@ runDefault("--returnEarlyFromInfiniteLoopsForFuzzing=1")
+function foo() {
+ while(1);
+}
+Reflect.construct(foo, {});
Modified: trunk/Source/_javascript_Core/ChangeLog (266769 => 266770)
--- trunk/Source/_javascript_Core/ChangeLog 2020-09-09 03:32:10 UTC (rev 266769)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-09-09 03:48:31 UTC (rev 266770)
@@ -1,3 +1,27 @@
+2020-09-08 Yusuke Suzuki <[email protected]>
+
+ [JSC] returnEarlyFromInfiniteLoopsForFuzzing should return object
+ https://bugs.webkit.org/show_bug.cgi?id=216289
+ <rdar://problem/68496533>
+
+ Reviewed by Saam Barati.
+
+ When returning early with returnEarlyFromInfiniteLoopsForFuzzing, we are returning with undefined.
+ But this is wrong when the callee is constructor since constructor is strongly assumed that it returns an object.
+ We should return some object from returnEarlyFromInfiniteLoopsForFuzzing. In this patch, we return global object
+ associated to this callee instead of undefined
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::finishCreation):
+ (JSC::CodeBlock::~CodeBlock):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileLoopHint):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_loop_hint):
+ * llint/LowLevelInterpreter64.asm:
+
2020-09-08 Saam Barati <[email protected]>
re-enable TCSM on all OSs
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (266769 => 266770)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2020-09-09 03:32:10 UTC (rev 266769)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2020-09-09 03:48:31 UTC (rev 266770)
@@ -772,7 +772,7 @@
}
case op_loop_hint: {
- if (Options::returnEarlyFromInfiniteLoopsForFuzzing())
+ if (UNLIKELY(Options::returnEarlyFromInfiniteLoopsForFuzzing()))
vm.addLoopHintExecutionCounter(instruction.ptr());
break;
}
@@ -825,7 +825,7 @@
// So, we can access member UnlinkedCodeBlock safely here. We bypass the assertion by using unvalidatedGet.
UnlinkedCodeBlock* unlinkedCodeBlock = m_unlinkedCode.unvalidatedGet();
- if (Options::returnEarlyFromInfiniteLoopsForFuzzing() && JITCode::isBaselineCode(jitType())) {
+ if (UNLIKELY(Options::returnEarlyFromInfiniteLoopsForFuzzing() && JITCode::isBaselineCode(jitType()))) {
for (const auto& instruction : unlinkedCodeBlock->instructions()) {
if (instruction->is<OpLoopHint>())
vm.removeLoopHintExecutionCounter(instruction.ptr());
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (266769 => 266770)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2020-09-09 03:32:10 UTC (rev 266769)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2020-09-09 03:48:31 UTC (rev 266770)
@@ -5003,7 +5003,7 @@
break;
case LoopHint:
- if (Options::returnEarlyFromInfiniteLoopsForFuzzing()) {
+ if (UNLIKELY(Options::returnEarlyFromInfiniteLoopsForFuzzing())) {
CodeBlock* baselineCodeBlock = m_jit.graph().baselineCodeBlockFor(node->origin.semantic);
if (baselineCodeBlock->loopHintsAreEligibleForFuzzingEarlyReturn()) {
BytecodeIndex bytecodeIndex = node->origin.semantic.bytecodeIndex();
@@ -5023,7 +5023,7 @@
}
m_jit.popToRestore(GPRInfo::regT0);
- m_jit.move(CCallHelpers::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::returnValueGPR);
+ m_jit.moveValue(baselineCodeBlock->globalObject(), JSValueRegs { GPRInfo::returnValueGPR });
m_jit.emitRestoreCalleeSaves();
m_jit.emitFunctionEpilogue();
m_jit.ret();
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (266769 => 266770)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2020-09-09 03:32:10 UTC (rev 266769)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2020-09-09 03:48:31 UTC (rev 266770)
@@ -14743,7 +14743,7 @@
void compileLoopHint()
{
- if (!Options::returnEarlyFromInfiniteLoopsForFuzzing())
+ if (LIKELY(!Options::returnEarlyFromInfiniteLoopsForFuzzing()))
return;
CodeBlock* baselineCodeBlock = m_graph.baselineCodeBlockFor(m_origin.semantic);
@@ -14783,7 +14783,7 @@
}
}
restore();
- jit.move(CCallHelpers::TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::returnValueGPR);
+ jit.moveValue(baselineCodeBlock->globalObject(), JSValueRegs { GPRInfo::returnValueGPR });
params.code().emitEpilogue(jit);
skipEarlyReturn.link(&jit);
Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (266769 => 266770)
--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2020-09-09 03:32:10 UTC (rev 266769)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp 2020-09-09 03:48:31 UTC (rev 266770)
@@ -1163,12 +1163,12 @@
void JIT::emit_op_loop_hint(const Instruction* instruction)
{
#if USE(JSVALUE64)
- if (Options::returnEarlyFromInfiniteLoopsForFuzzing() && m_codeBlock->loopHintsAreEligibleForFuzzingEarlyReturn()) {
+ if (UNLIKELY(Options::returnEarlyFromInfiniteLoopsForFuzzing() && m_codeBlock->loopHintsAreEligibleForFuzzingEarlyReturn())) {
uint64_t* ptr = vm().getLoopHintExecutionCounter(instruction);
load64(ptr, regT0);
auto skipEarlyReturn = branch64(Below, regT0, TrustedImm64(Options::earlyReturnFromInfiniteLoopsLimit()));
- moveValue(jsUndefined(), JSValueRegs { GPRInfo::returnValueGPR });
+ moveValue(m_codeBlock->globalObject(), JSValueRegs { GPRInfo::returnValueGPR });
checkStackPointerAlignment();
emitRestoreCalleeSaves();
emitFunctionEpilogue();
Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (266769 => 266770)
--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2020-09-09 03:32:10 UTC (rev 266769)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2020-09-09 03:48:31 UTC (rev 266770)
@@ -2961,7 +2961,8 @@
end)
op(fuzzer_return_early_from_loop_hint, macro ()
- move ValueUndefined, r0
+ loadp CodeBlock[cfr], t0
+ loadp CodeBlock::m_globalObject[t0], t0
doReturn()
end)