[JSC] Add FuzzerAgent, which has a hooks to get feedback & inject fuzz data into JSC
authorysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Apr 2019 22:24:47 +0000 (22:24 +0000)
committerysuzuki@apple.com <ysuzuki@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Apr 2019 22:24:47 +0000 (22:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196530

Reviewed by Saam Barati.

This patch adds FuzzerAgent interface and simple RandomizingFuzzerAgent to JSC.
This RandomizingFuzzerAgent returns random SpeculatedType for value profiling to find
the issues in JSC. The seed for randomization can be specified by seedOfRandomizingFuzzerAgent.

I ran this with seedOfRandomizingFuzzerAgent=1 last night and it finds 3 failures in the current JSC tests,
they should be fixed in subsequent patches.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
* runtime/FuzzerAgent.cpp: Added.
(JSC::FuzzerAgent::~FuzzerAgent):
(JSC::FuzzerAgent::getPrediction):
* runtime/FuzzerAgent.h: Added.
* runtime/JSGlobalObjectFunctions.cpp:
* runtime/Options.h:
* runtime/RandomizingFuzzerAgent.cpp: Added.
(JSC::RandomizingFuzzerAgent::RandomizingFuzzerAgent):
(JSC::RandomizingFuzzerAgent::getPrediction):
* runtime/RandomizingFuzzerAgent.h: Added.
* runtime/RegExpCachedResult.h:
* runtime/RegExpGlobalData.cpp:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
(JSC::VM::fuzzerAgent const):
(JSC::VM::setFuzzerAgent):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243832 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Sources.txt
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/runtime/FuzzerAgent.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/FuzzerAgent.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
Source/JavaScriptCore/runtime/Options.h
Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/RegExpCachedResult.h
Source/JavaScriptCore/runtime/RegExpGlobalData.cpp
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h

index 6af11b3..244e46b 100644 (file)
@@ -806,6 +806,7 @@ set(JavaScriptCore_PRIVATE_FRAMEWORK_HEADERS
     runtime/FunctionHasExecutedCache.h
     runtime/FunctionPrototype.h
     runtime/FunctionRareData.h
+    runtime/FuzzerAgent.h
     runtime/GenericOffset.h
     runtime/GenericTypedArrayView.h
     runtime/GenericTypedArrayViewInlines.h
index 04fd8de..4c56808 100644 (file)
@@ -1,3 +1,40 @@
+2019-04-03  Yusuke Suzuki  <ysuzuki@apple.com>
+
+        [JSC] Add FuzzerAgent, which has a hooks to get feedback & inject fuzz data into JSC
+        https://bugs.webkit.org/show_bug.cgi?id=196530
+
+        Reviewed by Saam Barati.
+
+        This patch adds FuzzerAgent interface and simple RandomizingFuzzerAgent to JSC.
+        This RandomizingFuzzerAgent returns random SpeculatedType for value profiling to find
+        the issues in JSC. The seed for randomization can be specified by seedOfRandomizingFuzzerAgent.
+
+        I ran this with seedOfRandomizingFuzzerAgent=1 last night and it finds 3 failures in the current JSC tests,
+        they should be fixed in subsequent patches.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::getPredictionWithoutOSRExit):
+        * runtime/FuzzerAgent.cpp: Added.
+        (JSC::FuzzerAgent::~FuzzerAgent):
+        (JSC::FuzzerAgent::getPrediction):
+        * runtime/FuzzerAgent.h: Added.
+        * runtime/JSGlobalObjectFunctions.cpp:
+        * runtime/Options.h:
+        * runtime/RandomizingFuzzerAgent.cpp: Added.
+        (JSC::RandomizingFuzzerAgent::RandomizingFuzzerAgent):
+        (JSC::RandomizingFuzzerAgent::getPrediction):
+        * runtime/RandomizingFuzzerAgent.h: Added.
+        * runtime/RegExpCachedResult.h:
+        * runtime/RegExpGlobalData.cpp:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        (JSC::VM::fuzzerAgent const):
+        (JSC::VM::setFuzzerAgent):
+
 2019-04-03  Myles C. Maxfield  <mmaxfield@apple.com>
 
         Remove support for -apple-trailing-word
index ea5ab40..4c3000d 100644 (file)
                E334CBB521FD96A9000EB178 /* RegExpGlobalData.h in Headers */ = {isa = PBXBuildFile; fileRef = E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E337B967224324EA0093A820 /* WasmCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = E337B966224324E50093A820 /* WasmCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               E33A94962255323000D42B06 /* RandomizingFuzzerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = E33A94942255322900D42B06 /* RandomizingFuzzerAgent.h */; };
+               E33A94972255323300D42B06 /* FuzzerAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = E33A94922255322900D42B06 /* FuzzerAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E33B3E261B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */; };
                E33E8D1D1B9013C300346B52 /* JSNativeStdFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = E33E8D1B1B9013C300346B52 /* JSNativeStdFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E33E8D211B9013DE00346B52 /* NativeStdFunctionCell.h in Headers */ = {isa = PBXBuildFile; fileRef = E33E8D1F1B9013DE00346B52 /* NativeStdFunctionCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E33637A31B63220200EE0840 /* ReflectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReflectObject.cpp; sourceTree = "<group>"; };
                E33637A41B63220200EE0840 /* ReflectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.h; sourceTree = "<group>"; };
                E337B966224324E50093A820 /* WasmCapabilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmCapabilities.h; sourceTree = "<group>"; };
+               E33A94922255322900D42B06 /* FuzzerAgent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FuzzerAgent.h; sourceTree = "<group>"; };
+               E33A94932255322900D42B06 /* RandomizingFuzzerAgent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RandomizingFuzzerAgent.cpp; sourceTree = "<group>"; };
+               E33A94942255322900D42B06 /* RandomizingFuzzerAgent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RandomizingFuzzerAgent.h; sourceTree = "<group>"; };
+               E33A94952255322A00D42B06 /* FuzzerAgent.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FuzzerAgent.cpp; sourceTree = "<group>"; };
                E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentationObject.lut.h; sourceTree = "<group>"; };
                E33E8D1A1B9013C300346B52 /* JSNativeStdFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNativeStdFunction.cpp; sourceTree = "<group>"; };
                E33E8D1B1B9013C300346B52 /* JSNativeStdFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNativeStdFunction.h; sourceTree = "<group>"; };
                                F692A85D0255597D01FF60F7 /* FunctionPrototype.h */,
                                62D2D38D1ADF103F000206C1 /* FunctionRareData.cpp */,
                                62D2D38E1ADF103F000206C1 /* FunctionRareData.h */,
+                               E33A94952255322A00D42B06 /* FuzzerAgent.cpp */,
+                               E33A94922255322900D42B06 /* FuzzerAgent.h */,
                                70B791851C024432002481E2 /* GeneratorFunctionConstructor.cpp */,
                                70B791861C024432002481E2 /* GeneratorFunctionConstructor.h */,
                                70B791871C024432002481E2 /* GeneratorFunctionPrototype.cpp */,
                                0F5780A118FE1E98001E72D9 /* PureNaN.h */,
                                0F0CD4C015F1A6040032F1C0 /* PutDirectIndexMode.h */,
                                147B84620E6DE6B1004775A4 /* PutPropertySlot.h */,
+                               E33A94932255322900D42B06 /* RandomizingFuzzerAgent.cpp */,
+                               E33A94942255322900D42B06 /* RandomizingFuzzerAgent.h */,
                                E33637A31B63220200EE0840 /* ReflectObject.cpp */,
                                E33637A41B63220200EE0840 /* ReflectObject.h */,
                                F692A87D0255597D01FF60F7 /* RegExp.cpp */,
                                0FBE0F7716C1DB120082C5E8 /* DFGUnificationPhase.h in Headers */,
                                0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */,
                                0F3B3A2C15475002003ED0FF /* DFGValidate.h in Headers */,
+                               52C55566224C2AEA0099F5CC /* DFGValueRepReductionPhase.h in Headers */,
                                0F2BDC481522802900CD8910 /* DFGValueSource.h in Headers */,
                                0F0123331944EA1B00843A0C /* DFGValueStrength.h in Headers */,
                                0FE254F71ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.h in Headers */,
                                BC18C4050E16F5CD00B34460 /* FunctionPrototype.h in Headers */,
                                62D2D3901ADF103F000206C1 /* FunctionRareData.h in Headers */,
                                FEA0C4031CDD7D1D00481991 /* FunctionWhitelist.h in Headers */,
+                               E33A94972255323300D42B06 /* FuzzerAgent.h in Headers */,
                                2AACE63D18CA5A0300ED0191 /* GCActivityCallback.h in Headers */,
                                BCBE2CAE14E985AA000593AD /* GCAssertions.h in Headers */,
                                0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
                                D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */,
                                996B73201BDA08EF00331B84 /* JSModuleLoader.lut.h in Headers */,
                                E318CBC11B8AEF5100A2929D /* JSModuleNamespaceObject.h in Headers */,
-                               52C55566224C2AEA0099F5CC /* DFGValueRepReductionPhase.h in Headers */,
                                E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */,
                                E33E8D1D1B9013C300346B52 /* JSNativeStdFunction.h in Headers */,
                                E38D999C221B78BB00D50474 /* JSNonDestructibleProxy.h in Headers */,
                                0F0CD4C215F1A6070032F1C0 /* PutDirectIndexMode.h in Headers */,
                                0F9FC8C514E1B60400D52AE0 /* PutKind.h in Headers */,
                                147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
+                               E33A94962255323000D42B06 /* RandomizingFuzzerAgent.h in Headers */,
                                0F44A7B320BF68D10022B171 /* RecordedStatuses.h in Headers */,
                                0FF60AC216740F8300029779 /* ReduceWhitespace.h in Headers */,
                                E33637A61B63220200EE0840 /* ReflectObject.h in Headers */,
index 48e7ed9..daadc06 100644 (file)
@@ -764,6 +764,7 @@ runtime/FunctionExecutableDump.cpp
 runtime/FunctionHasExecutedCache.cpp
 runtime/FunctionPrototype.cpp
 runtime/FunctionRareData.cpp
+runtime/FuzzerAgent.cpp
 runtime/GeneratorFunctionConstructor.cpp
 runtime/GeneratorFunctionPrototype.cpp
 runtime/GeneratorPrototype.cpp
@@ -900,6 +901,7 @@ runtime/PropertyTable.cpp
 runtime/ProxyConstructor.cpp
 runtime/ProxyObject.cpp
 runtime/ProxyRevoke.cpp
+runtime/RandomizingFuzzerAgent.cpp
 runtime/ReflectObject.cpp
 runtime/RegExp.cpp
 runtime/RegExpCache.cpp
index 4cbe394..3e5c4b6 100644 (file)
@@ -832,12 +832,20 @@ private:
     
     SpeculatedType getPredictionWithoutOSRExit(unsigned bytecodeIndex)
     {
-        SpeculatedType prediction;
+        auto getValueProfilePredictionFromForCodeBlockAndBytecodeOffset = [&] (CodeBlock* codeBlock, int bytecodeIndex)
         {
-            ConcurrentJSLocker locker(m_inlineStackTop->m_profiledBlock->m_lock);
-            prediction = m_inlineStackTop->m_profiledBlock->valueProfilePredictionForBytecodeOffset(locker, bytecodeIndex);
-        }
+            SpeculatedType prediction;
+            {
+                ConcurrentJSLocker locker(codeBlock->m_lock);
+                prediction = codeBlock->valueProfilePredictionForBytecodeOffset(locker, bytecodeIndex);
+            }
+            auto* fuzzerAgent = m_vm->fuzzerAgent();
+            if (UNLIKELY(fuzzerAgent))
+                return fuzzerAgent->getPrediction(codeBlock, bytecodeIndex, prediction);
+            return prediction;
+        };
 
+        SpeculatedType prediction = getValueProfilePredictionFromForCodeBlockAndBytecodeOffset(m_inlineStackTop->m_profiledBlock, bytecodeIndex);
         if (prediction != SpecNone)
             return prediction;
 
@@ -871,10 +879,7 @@ private:
             while (stack->m_inlineCallFrame != codeOrigin->inlineCallFrame())
                 stack = stack->m_caller;
 
-            bytecodeIndex = codeOrigin->bytecodeIndex();
-            CodeBlock* profiledBlock = stack->m_profiledBlock;
-            ConcurrentJSLocker locker(profiledBlock->m_lock);
-            return profiledBlock->valueProfilePredictionForBytecodeOffset(locker, bytecodeIndex);
+            return getValueProfilePredictionFromForCodeBlockAndBytecodeOffset(stack->m_profiledBlock, codeOrigin->bytecodeIndex());
         }
 
         default:
diff --git a/Source/JavaScriptCore/runtime/FuzzerAgent.cpp b/Source/JavaScriptCore/runtime/FuzzerAgent.cpp
new file mode 100644 (file)
index 0000000..8aa7322
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+#include "config.h"
+#include "FuzzerAgent.h"
+
+namespace JSC {
+
+FuzzerAgent::~FuzzerAgent()
+{
+}
+
+SpeculatedType FuzzerAgent::getPrediction(CodeBlock*, int, SpeculatedType result)
+{
+    return result;
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/FuzzerAgent.h b/Source/JavaScriptCore/runtime/FuzzerAgent.h
new file mode 100644 (file)
index 0000000..999e7e3
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+#pragma once
+
+#include "SpeculatedType.h"
+#include <wtf/Locker.h>
+
+namespace JSC {
+
+class CodeBlock;
+
+class FuzzerAgent {
+public:
+    JS_EXPORT_PRIVATE virtual ~FuzzerAgent();
+
+    JS_EXPORT_PRIVATE virtual SpeculatedType getPrediction(CodeBlock*, int bytecodeOffset, SpeculatedType);
+};
+
+} // namespace JSC
index 1090980..8edf49f 100644 (file)
@@ -44,6 +44,7 @@
 #include "Lexer.h"
 #include "LiteralParser.h"
 #include "Nodes.h"
+#include "ObjectConstructor.h"
 #include "JSCInlines.h"
 #include "ParseInt.h"
 #include "Parser.h"
index 1a1cf05..9837989 100644 (file)
@@ -434,6 +434,9 @@ constexpr bool enableWebAssemblyStreamingApi = false;
     v(unsigned, fireOSRExitFuzzAt, 0, Normal, nullptr) \
     v(unsigned, fireOSRExitFuzzAtOrAfter, 0, Normal, nullptr) \
     \
+    v(bool, useRandomizingFuzzerAgent, false, Normal, nullptr) \
+    v(unsigned, seedOfRandomizingFuzzerAgent, 1, Normal, nullptr) \
+    \
     v(bool, logPhaseTimes, false, Normal, nullptr) \
     v(double, rareBlockPenalty, 0.001, Normal, nullptr) \
     v(bool, airLinearScanVerbose, false, Normal, nullptr) \
diff --git a/Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.cpp b/Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.cpp
new file mode 100644 (file)
index 0000000..747ad6a
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+#include "config.h"
+#include "RandomizingFuzzerAgent.h"
+
+namespace JSC {
+
+RandomizingFuzzerAgent::RandomizingFuzzerAgent(VM&)
+    : m_random(Options::seedOfRandomizingFuzzerAgent())
+{
+}
+
+SpeculatedType RandomizingFuzzerAgent::getPrediction(CodeBlock*, int, SpeculatedType)
+{
+    auto locker = holdLock(m_lock);
+    uint32_t high = m_random.getUint32();
+    uint32_t low = m_random.getUint32();
+    uint64_t result = (static_cast<uint64_t>(high) << 32) | low;
+    return static_cast<SpeculatedType>(result) & SpecFullTop;
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.h b/Source/JavaScriptCore/runtime/RandomizingFuzzerAgent.h
new file mode 100644 (file)
index 0000000..75523d5
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 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 INC. ``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 INC. OR
+ * 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.
+ */
+
+#pragma once
+
+#include "FuzzerAgent.h"
+#include <wtf/Lock.h>
+#include <wtf/WeakRandom.h>
+
+namespace JSC {
+
+class VM;
+
+class RandomizingFuzzerAgent final : public FuzzerAgent {
+public:
+    RandomizingFuzzerAgent(VM&);
+
+    SpeculatedType getPrediction(CodeBlock*, int bytecodeOffset, SpeculatedType) override;
+
+private:
+    WeakRandom m_random;
+    Lock m_lock;
+};
+
+} // namespace JSC
index a5b0391..5aa8a39 100644 (file)
@@ -25,6 +25,8 @@
 
 #pragma once
 
+#include "Heap.h"
+#include "JSObject.h"
 #include "RegExp.h"
 
 namespace JSC {
index d4c2dc5..2dde618 100644 (file)
@@ -26,6 +26,9 @@
 #include "config.h"
 #include "RegExpGlobalData.h"
 
+#include "JSCJSValueInlines.h"
+#include "JSString.h"
+
 namespace JSC {
 
 void RegExpGlobalData::visitAggregate(SlotVisitor& visitor)
index 3ed6de9..65af3a0 100644 (file)
 #include "PromiseDeferredTimer.h"
 #include "PropertyMapHashTable.h"
 #include "ProxyRevoke.h"
+#include "RandomizingFuzzerAgent.h"
 #include "RegExpCache.h"
 #include "RegExpObject.h"
 #include "RegisterAtOffsetList.h"
@@ -456,6 +457,8 @@ VM::VM(VMType vmType, HeapType heapType)
         m_samplingProfiler->start();
     }
 #endif // ENABLE(SAMPLING_PROFILER)
+    if (Options::useRandomizingFuzzerAgent())
+        setFuzzerAgent(std::make_unique<RandomizingFuzzerAgent>(*this));
 
     if (Options::alwaysGeneratePCToCodeOriginMap())
         setShouldBuildPCToCodeOriginMapping();
index 06dec07..c5fbe5e 100644 (file)
@@ -38,6 +38,7 @@
 #include "ExceptionEventLocation.h"
 #include "ExecutableAllocator.h"
 #include "FunctionHasExecutedCache.h"
+#include "FuzzerAgent.h"
 #include "Heap.h"
 #include "Intrinsic.h"
 #include "IsoCellSet.h"
@@ -294,6 +295,12 @@ public:
     JS_EXPORT_PRIVATE SamplingProfiler& ensureSamplingProfiler(RefPtr<Stopwatch>&&);
 #endif
 
+    FuzzerAgent* fuzzerAgent() const { return m_fuzzerAgent.get(); }
+    void setFuzzerAgent(std::unique_ptr<FuzzerAgent>&& fuzzerAgent)
+    {
+        m_fuzzerAgent = WTFMove(fuzzerAgent);
+    }
+
     static unsigned numberOfIDs() { return s_numberOfIDs.load(); }
     unsigned id() const { return m_id; }
     bool isEntered() const { return !!entryScope; }
@@ -1024,6 +1031,7 @@ private:
 #if ENABLE(SAMPLING_PROFILER)
     RefPtr<SamplingProfiler> m_samplingProfiler;
 #endif
+    std::unique_ptr<FuzzerAgent> m_fuzzerAgent;
     std::unique_ptr<ShadowChicken> m_shadowChicken;
     std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry;