Diff
Modified: branches/safari-600.1-branch/Source/_javascript_Core/ChangeLog (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/ChangeLog 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/ChangeLog 2014-07-23 05:44:59 UTC (rev 171411)
@@ -1,5 +1,56 @@
2014-07-22 Dana Burkart <dburk...@apple.com>
+ Merge r171213.
+
+ 2014-07-15 Filip Pizlo <fpi...@apple.com>
+
+ Need ability to fuzz exception throwing
+ https://bugs.webkit.org/show_bug.cgi?id=134945
+ <rdar://problem/17722027>
+
+ Reviewed by Sam Weinig.
+
+ Adds the ability to instrument exception checks, and to force some random
+ exception check to artificially throw an exception. Also adds new tests that
+ are suitable for testing this. Note that this is closely tied to the Tools
+ directory changes that are also part of this changeset.
+
+ This also fixes an activation tear-off bug that arises if we ever throw an
+ exception from operationOptimize, or if due to some other bug it's only due
+ to the operationOptimize exception check that we realize that there is an
+ exception to be thrown.
+
+ * dfg/DFGJITCompiler.h:
+ (JSC::DFG::JITCompiler::fastExceptionCheck):
+ * ftl/FTLIntrinsicRepository.h:
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::callCheck):
+ * interpreter/Interpreter.cpp:
+ (JSC::unwindCallFrame):
+ * jit/AssemblyHelpers.cpp:
+ (JSC::AssemblyHelpers::callExceptionFuzz):
+ (JSC::AssemblyHelpers::emitExceptionCheck):
+ * jit/AssemblyHelpers.h:
+ (JSC::AssemblyHelpers::emitExceptionCheck): Deleted.
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_enter):
+ * jit/JITOperations.cpp:
+ (JSC::numberOfExceptionFuzzChecks):
+ * jit/JITOperations.h:
+ * jsc.cpp:
+ (jscmain):
+ * runtime/Options.h:
+ * runtime/TestRunnerUtils.h:
+ * tests/exceptionFuzz.yaml: Added.
+ * tests/exceptionFuzz: Added.
+ * tests/exceptionFuzz/3d-cube.js: Added.
+ * tests/exceptionFuzz/date-format-xparb.js: Added.
+ * tests/exceptionFuzz/earley-boyer.js: Added.
+
+2014-07-22 Dana Burkart <dburk...@apple.com>
+
Merge r171204.
2014-07-17 Joseph Pecoraro <pecor...@apple.com>
Modified: branches/safari-600.1-branch/Source/_javascript_Core/dfg/DFGJITCompiler.h (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/dfg/DFGJITCompiler.h 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/dfg/DFGJITCompiler.h 2014-07-23 05:44:59 UTC (rev 171411)
@@ -186,6 +186,7 @@
// Add a call out from JIT code, with a fast exception check that tests if the return value is zero.
void fastExceptionCheck()
{
+ callExceptionFuzz();
m_exceptionChecks.append(branchTestPtr(Zero, GPRInfo::returnValueGPR));
}
Modified: branches/safari-600.1-branch/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h 2014-07-23 05:44:59 UTC (rev 171411)
@@ -84,6 +84,7 @@
macro(S_JITOperation_EJ, functionType(intPtr, intPtr, int64)) \
macro(S_JITOperation_EJJ, functionType(intPtr, intPtr, int64, int64)) \
macro(S_JITOperation_J, functionType(intPtr, int64)) \
+ macro(V_JITOperation, functionType(voidType)) \
macro(V_JITOperation_EJJJ, functionType(voidType, intPtr, int64, int64, int64)) \
macro(V_JITOperation_EOZD, functionType(voidType, intPtr, intPtr, int32, doubleType)) \
macro(V_JITOperation_EOZJ, functionType(voidType, intPtr, intPtr, int32, int64)) \
Modified: branches/safari-600.1-branch/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -5760,6 +5760,9 @@
if (mode == NoExceptions)
return;
+ if (Options::enableExceptionFuzz())
+ m_out.call(m_out.operation(operationExceptionFuzz));
+
LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Exception check continuation"));
m_out.branch(
Modified: branches/safari-600.1-branch/Source/_javascript_Core/interpreter/Interpreter.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/interpreter/Interpreter.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/interpreter/Interpreter.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -457,13 +457,19 @@
RELEASE_ASSERT(!visitor->isInlinedFrame());
#endif
activation = callFrame->uncheckedActivation();
- if (activation)
- jsCast<JSActivation*>(activation)->tearOff(*scope->vm());
+ // Protect against the activation not being created, or the variable still being
+ // initialized to Undefined inside op_enter.
+ if (activation && activation.isCell()) {
+ JSActivation* activationObject = jsCast<JSActivation*>(activation);
+ // Protect against throwing exceptions after tear-off.
+ if (!activationObject->isTornOff())
+ activationObject->tearOff(*scope->vm());
+ }
}
if (codeBlock->codeType() == FunctionCode && codeBlock->usesArguments()) {
if (Arguments* arguments = visitor->existingArguments()) {
- if (activation)
+ if (activation && activation.isCell())
arguments->didTearOffActivation(callFrame, jsCast<JSActivation*>(activation));
#if ENABLE(DFG_JIT)
else if (visitor->isInlinedFrame())
Modified: branches/safari-600.1-branch/Source/_javascript_Core/interpreter/StackVisitor.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/interpreter/StackVisitor.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/interpreter/StackVisitor.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -278,7 +278,7 @@
reg = codeBlock()->argumentsRegister();
JSValue result = callFrame()->r(unmodifiedArgumentsRegister(reg).offset()).jsValue();
- if (!result)
+ if (!result || !result.isCell()) // Protect against Undefined in case we throw in op_enter.
return 0;
return jsCast<Arguments*>(result);
}
Modified: branches/safari-600.1-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/jit/AssemblyHelpers.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -28,6 +28,7 @@
#if ENABLE(JIT)
+#include "JITOperations.h"
#include "JSCInlines.h"
namespace JSC {
@@ -195,6 +196,33 @@
}
#endif // !ASSERT_DISABLED
+void AssemblyHelpers::callExceptionFuzz()
+{
+ if (!Options::enableExceptionFuzz())
+ return;
+
+ ASSERT(stackAlignmentBytes() >= sizeof(void*) * 2);
+ subPtr(TrustedImm32(stackAlignmentBytes()), stackPointerRegister);
+ poke(GPRInfo::returnValueGPR, 0);
+ poke(GPRInfo::returnValueGPR2, 1);
+ move(TrustedImmPtr(bitwise_cast<void*>(operationExceptionFuzz)), GPRInfo::nonPreservedNonReturnGPR);
+ call(GPRInfo::nonPreservedNonReturnGPR);
+ peek(GPRInfo::returnValueGPR, 0);
+ peek(GPRInfo::returnValueGPR2, 1);
+ addPtr(TrustedImm32(stackAlignmentBytes()), stackPointerRegister);
+}
+
+AssemblyHelpers::Jump AssemblyHelpers::emitExceptionCheck(ExceptionCheckKind kind)
+{
+ callExceptionFuzz();
+
+#if USE(JSVALUE64)
+ return branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(vm()->addressOfException()));
+#elif USE(JSVALUE32_64)
+ return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(vm()->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
+#endif
+}
+
void AssemblyHelpers::emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, TrustedImmPtr structure, RegisterID dest)
{
const Structure* structurePtr = static_cast<const Structure*>(structure.m_value);
Modified: branches/safari-600.1-branch/Source/_javascript_Core/jit/AssemblyHelpers.h (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/jit/AssemblyHelpers.h 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/jit/AssemblyHelpers.h 2014-07-23 05:44:59 UTC (rev 171411)
@@ -481,15 +481,10 @@
}
#endif
+ void callExceptionFuzz();
+
enum ExceptionCheckKind { NormalExceptionCheck, InvertedExceptionCheck };
- Jump emitExceptionCheck(ExceptionCheckKind kind = NormalExceptionCheck)
- {
-#if USE(JSVALUE64)
- return branchTest64(kind == NormalExceptionCheck ? NonZero : Zero, AbsoluteAddress(vm()->addressOfException()));
-#elif USE(JSVALUE32_64)
- return branch32(kind == NormalExceptionCheck ? NotEqual : Equal, AbsoluteAddress(reinterpret_cast<char*>(vm()->addressOfException()) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
-#endif
- }
+ Jump emitExceptionCheck(ExceptionCheckKind kind = NormalExceptionCheck);
#if ENABLE(SAMPLING_COUNTERS)
static void emitCount(MacroAssembler& jit, AbstractSamplingCounter& counter, int32_t increment = 1)
Modified: branches/safari-600.1-branch/Source/_javascript_Core/jit/JIT.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/jit/JIT.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/jit/JIT.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -167,7 +167,10 @@
AbsoluteAddress(m_compilation->executionCounterFor(Profiler::OriginStack(Profiler::Origin(
m_compilation->bytecodes(), m_bytecodeOffset)))->address()));
}
-
+
+ if (Options::eagerlyUpdateTopCallFrame())
+ updateTopCallFrame();
+
switch (opcodeID) {
DEFINE_SLOW_OP(del_by_val)
DEFINE_SLOW_OP(in)
Modified: branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOpcodes.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOpcodes.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOpcodes.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -762,8 +762,6 @@
void JIT::emit_op_enter(Instruction*)
{
- emitEnterOptimizationCheck();
-
// Even though CTI doesn't use them, we initialize our constant
// registers to zap stale pointers, to avoid unnecessarily prolonging
// object lifetime and increasing GC pressure.
@@ -772,6 +770,8 @@
emitInitRegister(virtualRegisterForLocal(j).offset());
emitWriteBarrier(m_codeBlock->ownerExecutable());
+
+ emitEnterOptimizationCheck();
}
void JIT::emit_op_create_activation(Instruction* currentInstruction)
Modified: branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOperations.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOperations.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOperations.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -51,10 +51,14 @@
#include "JSCInlines.h"
#include "Repatch.h"
#include "RepatchBuffer.h"
+#include "TestRunnerUtils.h"
#include <wtf/InlineASM.h>
namespace JSC {
+static unsigned s_numberOfExceptionFuzzChecks;
+unsigned numberOfExceptionFuzzChecks() { return s_numberOfExceptionFuzzChecks; }
+
extern "C" {
#if COMPILER(MSVC)
@@ -1028,7 +1032,7 @@
DeferGCForAWhile deferGC(vm.heap);
CodeBlock* codeBlock = exec->codeBlock();
-
+
if (bytecodeIndex) {
// If we're attempting to OSR from a loop, assume that this should be
// separately optimized.
@@ -1799,6 +1803,31 @@
genericUnwind(vm, exec, vm->exception());
}
+// This function "should" just take the ExecState*, but doing so would make it more difficult
+// to call from exception check sites. So, unlike all of our other functions, we allow
+// ourselves to play some gnarly ABI tricks just to simplify the calling convention. This is
+// particularly safe here since this is never called on the critical path - it's only for
+// testing.
+void JIT_OPERATION operationExceptionFuzz()
+{
+ ASSERT(Options::enableExceptionFuzz());
+
+ // This probably "just works" for GCC also, but I haven't tried.
+#if COMPILER(CLANG)
+ ExecState* exec = static_cast<ExecState*>(__builtin_frame_address(1));
+ DeferGCForAWhile deferGC(exec->vm().heap);
+
+ s_numberOfExceptionFuzzChecks++;
+
+ unsigned fireTarget = Options::fireExceptionFuzzAt();
+ if (fireTarget == s_numberOfExceptionFuzzChecks) {
+ printf("JSC EXCEPTION FUZZ: Throwing fuzz exception with call frame %p and return address %p.\n", exec, __builtin_return_address(0));
+ exec->vm().throwException(
+ exec, createError(exec->lexicalGlobalObject(), ASCIILiteral("Exception Fuzz")));
+ }
+#endif // COMPILER(CLANG)
+}
+
} // extern "C"
// Note: getHostCallReturnValueWithExecState() needs to be placed before the
Modified: branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOperations.h (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOperations.h 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/jit/JITOperations.h 2014-07-23 05:44:59 UTC (rev 171411)
@@ -143,6 +143,7 @@
typedef size_t JIT_OPERATION (*S_JITOperation_EOJss)(ExecState*, JSObject*, JSString*);
typedef size_t JIT_OPERATION (*S_JITOperation_J)(EncodedJSValue);
typedef SlowPathReturnType JIT_OPERATION (*Sprt_JITOperation_EZ)(ExecState*, int32_t);
+typedef void JIT_OPERATION (*V_JITOperation)();
typedef void JIT_OPERATION (*V_JITOperation_E)(ExecState*);
typedef void JIT_OPERATION (*V_JITOperation_EC)(ExecState*, JSCell*);
typedef void JIT_OPERATION (*V_JITOperation_ECb)(ExecState*, CodeBlock*);
@@ -300,6 +301,8 @@
void JIT_OPERATION operationInitGlobalConst(ExecState*, Instruction*);
+void JIT_OPERATION operationExceptionFuzz();
+
} // extern "C"
inline P_JITOperation_ECli operationLinkFor(
Modified: branches/safari-600.1-branch/Source/_javascript_Core/jsc.cpp (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/jsc.cpp 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/jsc.cpp 2014-07-23 05:44:59 UTC (rev 171411)
@@ -1273,6 +1273,9 @@
if (!vm->m_perBytecodeProfiler->save(options.m_profilerOutput.utf8().data()))
fprintf(stderr, "could not save profiler output.\n");
}
+
+ if (Options::enableExceptionFuzz())
+ printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks());
}
return result;
Modified: branches/safari-600.1-branch/Source/_javascript_Core/runtime/Options.h (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/runtime/Options.h 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/runtime/Options.h 2014-07-23 05:44:59 UTC (rev 171411)
@@ -141,6 +141,7 @@
v(bool, testTheFTL, false) \
v(bool, verboseSanitizeStack, false) \
v(bool, alwaysDoFullCollection, false) \
+ v(bool, eagerlyUpdateTopCallFrame, false) \
\
v(bool, enableOSREntryToDFG, true) \
v(bool, enableOSREntryToFTL, true) \
@@ -269,7 +270,10 @@
v(bool, disableGC, false) \
v(unsigned, gcMaxHeapSize, 0) \
v(bool, recordGCPauseTimes, false) \
- v(bool, logHeapStatisticsAtExit, false)
+ v(bool, logHeapStatisticsAtExit, false) \
+ \
+ v(bool, enableExceptionFuzz, false) \
+ v(unsigned, fireExceptionFuzzAt, 0)
class Options {
public:
Modified: branches/safari-600.1-branch/Source/_javascript_Core/runtime/TestRunnerUtils.h (171410 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/runtime/TestRunnerUtils.h 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Source/_javascript_Core/runtime/TestRunnerUtils.h 2014-07-23 05:44:59 UTC (rev 171411)
@@ -44,6 +44,8 @@
JS_EXPORT_PRIVATE JSValue setNeverInline(ExecState*);
JS_EXPORT_PRIVATE JSValue optimizeNextInvocation(ExecState*);
+JS_EXPORT_PRIVATE unsigned numberOfExceptionFuzzChecks();
+
} // namespace JSC
#endif // TestRunnerUtils_h
Copied: branches/safari-600.1-branch/Source/_javascript_Core/tests/exceptionFuzz.yaml (from rev 171213, trunk/Source/_javascript_Core/tests/exceptionFuzz.yaml) (0 => 171411)
--- branches/safari-600.1-branch/Source/_javascript_Core/tests/exceptionFuzz.yaml (rev 0)
+++ branches/safari-600.1-branch/Source/_javascript_Core/tests/exceptionFuzz.yaml 2014-07-23 05:44:59 UTC (rev 171411)
@@ -0,0 +1,30 @@
+# Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+
+- path: exceptionFuzz
+ cmd: |
+ if $architecture !~ /x86/i and $hostOS == "darwin"
+ skip
+ else
+ runExceptionFuzz
+ end
Modified: branches/safari-600.1-branch/Tools/ChangeLog (171410 => 171411)
--- branches/safari-600.1-branch/Tools/ChangeLog 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Tools/ChangeLog 2014-07-23 05:44:59 UTC (rev 171411)
@@ -1,5 +1,28 @@
2014-07-22 Dana Burkart <dburk...@apple.com>
+ Merge r171213.
+
+ 2014-07-15 Filip Pizlo <fpi...@apple.com>
+
+ Need ability to fuzz exception throwing
+ https://bugs.webkit.org/show_bug.cgi?id=134945
+ <rdar://problem/17722027>
+
+ Reviewed by Sam Weinig.
+
+ Adds a new script, js-exception-fuzz, which will run some jsc command-line using
+ exception fuzzing. This means that we will force exceptions to be thrown in random
+ places to see how the engine reacts. This is now integrated with the various test
+ drivers, so run-_javascript_core-tests will run some exception fuzzing tests by
+ default.
+
+ * Scripts/jsc-stress-test-helpers/js-exception-fuzz: Added.
+ (fail):
+ * Scripts/run-_javascript_core-tests:
+ * Scripts/run-jsc-stress-tests:
+
+2014-07-22 Dana Burkart <dburk...@apple.com>
+
Merge r171167.
2014-07-16 Alexey Proskuryakov <a...@apple.com>
Copied: branches/safari-600.1-branch/Tools/Scripts/jsc-stress-test-helpers/js-exception-fuzz (from rev 171213, trunk/Tools/Scripts/jsc-stress-test-helpers/js-exception-fuzz) (0 => 171411)
--- branches/safari-600.1-branch/Tools/Scripts/jsc-stress-test-helpers/js-exception-fuzz (rev 0)
+++ branches/safari-600.1-branch/Tools/Scripts/jsc-stress-test-helpers/js-exception-fuzz 2014-07-23 05:44:59 UTC (rev 171411)
@@ -0,0 +1,141 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2014 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 AND ITS CONTRIBUTORS "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 OR ITS 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.
+
+use strict;
+use FindBin;
+use Getopt::Long qw(:config pass_through);
+use POSIX;
+use String::ShellQuote;
+
+# We first want to run the test once to determine what the number of encountered
+# checks is. Then we want to run it again some number of times with random check
+# amounts. The test is successful if after printing a message that we're
+# intending to throw the fuzz exception, it prints another message saying that it
+# caught the exception.
+
+my $repeat = 100;
+my $seed = time();
+my $verbose = 0;
+
+# We allow flags to be passed via environment variables, which is rather useful for
+# running with the run-jsc-stress-tests harness.
+if (defined($ENV{JS_EFUZZ_REPEAT})) {
+ $repeat = $ENV{JS_EFUZZ_REPEAT};
+}
+if (defined($ENV{JS_EFUZZ_SEED})) {
+ $seed = $ENV{JS_EFUZZ_SEED};
+}
+if (defined($ENV{JS_EFUZZ_VERBOSE})) {
+ $verbose = $ENV{JS_EFUZZ_VERBOSE};
+}
+
+GetOptions(
+ 'repeat=s' => \$repeat,
+ 'seed=s' => \$seed,
+ 'verbose' => \$verbose
+);
+
+my $commandString = shell_quote @ARGV;
+
+my $checkCount;
+
+sub fail {
+ my $context = shift;
+ flush STDOUT;
+ flush STDERR;
+ die "Failure for command $commandString with seed $seed, repeat $repeat: $context";
+}
+
+open (my $testInput, "$commandString --enableExceptionFuzz=true |") or fail("Cannot execute initial command when getting check count");
+while (my $inputLine = <$testInput>) {
+ chomp($inputLine);
+ my $handled = 0;
+ if ($inputLine =~ /^JSC EXCEPTION FUZZ:/) {
+ if ($' =~ /encountered ([0-9]+) checks\./) {
+ $checkCount = $1;
+ }
+ $handled = 1;
+ }
+ if (!$handled || $verbose) {
+ print "checkCount: $inputLine\n";
+ }
+}
+close($testInput);
+
+if ($verbose) {
+ print "Check count: $checkCount\n";
+ print "Seed: $seed\n";
+}
+
+srand($seed);
+
+for (my $iteration = 0; $iteration < $repeat; ++$iteration) {
+ my $target = int(rand() * $checkCount);
+ if ($verbose) {
+ print "iteration($iteration) target($target): Running.\n";
+ }
+ open ($testInput, "$commandString --enableExceptionFuzz=true --fireExceptionFuzzAt=$target |") or fail("Cannot execute command on iteration $iteration");
+ my $state = "waiting";
+ while (my $inputLine = <$testInput>) {
+ chomp($inputLine);
+ my $handled = 0;
+ if ($inputLine =~ /^JSC EXCEPTION FUZZ:/) {
+ if ($' =~ /Throwing fuzz exception/) {
+ if ($verbose) {
+ print "iteration($iteration) target($target): Threw fuzz exception.\n";
+ }
+ if ($state eq "waiting") {
+ $state = "thrown";
+ } else {
+ fail("Unexpected $inputLine while in state $state for target $target");
+ }
+ } elsif ($' =~ /Caught exception/) {
+ if ($verbose) {
+ print "iteration($iteration) target($target): Caught fuzz exception.\n";
+ }
+ if ($state eq "thrown") {
+ $state = "waiting";
+ } else {
+ fail("Unexpected $inputLine while in state $state for target $target");
+ }
+ }
+ $handled = 1;
+ }
+ if (!$handled || $verbose) {
+ print "iteration($iteration) target($target): $inputLine\n";
+ }
+ }
+ if ($state ne "waiting") {
+ fail("Unexpected state $state at end for target $target");
+ }
+ close($testInput);
+ if ($? != 0) {
+ fail("Unexpected exit status $? for target $target");
+ }
+}
+
+if ($verbose) {
+ print "Success!\n";
+}
Modified: branches/safari-600.1-branch/Tools/Scripts/run-_javascript_core-tests (171410 => 171411)
--- branches/safari-600.1-branch/Tools/Scripts/run-_javascript_core-tests 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Tools/Scripts/run-_javascript_core-tests 2014-07-23 05:44:59 UTC (rev 171411)
@@ -237,6 +237,7 @@
"/usr/bin/env", "ruby", "Tools/Scripts/run-jsc-stress-tests",
"-j", jscPath($productDir), "-o", $jscStressResultsDir,
"PerformanceTests/SunSpider/tests/sunspider-1.0",
+ "Source/_javascript_Core/tests/exceptionFuzz.yaml",
"PerformanceTests/SunSpider/no-architecture-specific-optimizations.yaml",
"PerformanceTests/SunSpider/tests/v8-v6",
"Source/_javascript_Core/tests/mozilla/mozilla-tests.yaml",
Modified: branches/safari-600.1-branch/Tools/Scripts/run-jsc-stress-tests (171410 => 171411)
--- branches/safari-600.1-branch/Tools/Scripts/run-jsc-stress-tests 2014-07-23 05:41:28 UTC (rev 171410)
+++ branches/safari-600.1-branch/Tools/Scripts/run-jsc-stress-tests 2014-07-23 05:44:59 UTC (rev 171411)
@@ -733,6 +733,10 @@
end
end
+def runExceptionFuzz
+ addRunCommand("exception-fuzz", ["perl", (HELPERS_PATH + "js-exception-fuzz").to_s, pathToVM.to_s, $benchmark.to_s], silentOutputHandler, simpleErrorHandler)
+end
+
def runLayoutTest(kind, *options)
raise unless $benchmark.to_s =~ /\.js$/
testName = $~.pre_match