Title: [153290] trunk/Source/_javascript_Core
Revision
153290
Author
[email protected]
Date
2013-07-24 21:05:20 -0700 (Wed, 24 Jul 2013)

Log Message

fourthTier: each DFG node that relies on other nodes to do their type checks should be able to tell you if those type checks happened
https://bugs.webkit.org/show_bug.cgi?id=118866

Reviewed by Sam Weinig.

Adds a safeToExecute() method that takes a node and an abstract state and tells you
if the node will run without crashing under that state.

* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::CodeBlock):
* dfg/DFGCFAPhase.cpp:
(CFAPhase):
(JSC::DFG::CFAPhase::CFAPhase):
(JSC::DFG::CFAPhase::run):
(JSC::DFG::CFAPhase::performBlockCFA):
(JSC::DFG::CFAPhase::performForwardCFA):
* dfg/DFGSafeToExecute.h: Added.
(DFG):
(SafeToExecuteEdge):
(JSC::DFG::SafeToExecuteEdge::SafeToExecuteEdge):
(JSC::DFG::SafeToExecuteEdge::operator()):
(JSC::DFG::SafeToExecuteEdge::result):
(JSC::DFG::safeToExecute):
* dfg/DFGStructureAbstractValue.h:
(JSC::DFG::StructureAbstractValue::isValidOffset):
(StructureAbstractValue):
* runtime/Options.h:
(JSC):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (153289 => 153290)


--- trunk/Source/_javascript_Core/ChangeLog	2013-07-25 04:05:18 UTC (rev 153289)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-07-25 04:05:20 UTC (rev 153290)
@@ -1,5 +1,37 @@
 2013-07-20  Filip Pizlo  <[email protected]>
 
+        fourthTier: each DFG node that relies on other nodes to do their type checks should be able to tell you if those type checks happened
+        https://bugs.webkit.org/show_bug.cgi?id=118866
+
+        Reviewed by Sam Weinig.
+        
+        Adds a safeToExecute() method that takes a node and an abstract state and tells you
+        if the node will run without crashing under that state.
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::CodeBlock):
+        * dfg/DFGCFAPhase.cpp:
+        (CFAPhase):
+        (JSC::DFG::CFAPhase::CFAPhase):
+        (JSC::DFG::CFAPhase::run):
+        (JSC::DFG::CFAPhase::performBlockCFA):
+        (JSC::DFG::CFAPhase::performForwardCFA):
+        * dfg/DFGSafeToExecute.h: Added.
+        (DFG):
+        (SafeToExecuteEdge):
+        (JSC::DFG::SafeToExecuteEdge::SafeToExecuteEdge):
+        (JSC::DFG::SafeToExecuteEdge::operator()):
+        (JSC::DFG::SafeToExecuteEdge::result):
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGStructureAbstractValue.h:
+        (JSC::DFG::StructureAbstractValue::isValidOffset):
+        (StructureAbstractValue):
+        * runtime/Options.h:
+        (JSC):
+
+2013-07-20  Filip Pizlo  <[email protected]>
+
         fourthTier: FTL should be able to generate LLVM IR that uses an intrinsic for OSR exit
         https://bugs.webkit.org/show_bug.cgi?id=118948
 

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (153289 => 153290)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-07-25 04:05:18 UTC (rev 153289)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2013-07-25 04:05:20 UTC (rev 153290)
@@ -839,6 +839,8 @@
 		A7E5AB381799E4B200D2833D /* LLVMDisassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E5AB341799E4B200D2833D /* LLVMDisassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */ = {isa = PBXBuildFile; fileRef = A7E5AB351799E4B200D2833D /* UDis86Disassembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A7E5AB3A1799E4B200D2833D /* X86Disassembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E5AB361799E4B200D2833D /* X86Disassembler.cpp */; };
+		A7F2996B17A0BB670010417A /* FTLFail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F2996917A0BB670010417A /* FTLFail.cpp */; };
+		A7F2996C17A0BB670010417A /* FTLFail.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F2996A17A0BB670010417A /* FTLFail.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		A7F9935F0FD7325100A0B2D0 /* JSONObject.h in Headers */ = {isa = PBXBuildFile; fileRef = A7F9935D0FD7325100A0B2D0 /* JSONObject.h */; };
 		A7F993600FD7325100A0B2D0 /* JSONObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7F9935E0FD7325100A0B2D0 /* JSONObject.cpp */; };
 		A7FB60A4103F7DC20017A286 /* PropertyDescriptor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7FB60A3103F7DC20017A286 /* PropertyDescriptor.cpp */; };
@@ -1909,6 +1911,8 @@
 		A7E5AB341799E4B200D2833D /* LLVMDisassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLVMDisassembler.h; path = disassembler/LLVMDisassembler.h; sourceTree = "<group>"; };
 		A7E5AB351799E4B200D2833D /* UDis86Disassembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UDis86Disassembler.h; path = disassembler/UDis86Disassembler.h; sourceTree = "<group>"; };
 		A7E5AB361799E4B200D2833D /* X86Disassembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = X86Disassembler.cpp; path = disassembler/X86Disassembler.cpp; sourceTree = "<group>"; };
+		A7F2996917A0BB670010417A /* FTLFail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLFail.cpp; path = ftl/FTLFail.cpp; sourceTree = "<group>"; };
+		A7F2996A17A0BB670010417A /* FTLFail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLFail.h; path = ftl/FTLFail.h; sourceTree = "<group>"; };
 		A7F8690E0F9584A100558697 /* CachedCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedCall.h; sourceTree = "<group>"; };
 		A7F869EC0F95C2EC00558697 /* CallFrameClosure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrameClosure.h; sourceTree = "<group>"; };
 		A7F9935D0FD7325100A0B2D0 /* JSONObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONObject.h; sourceTree = "<group>"; };
@@ -2169,9 +2173,9 @@
 		034768DFFF38A50411DB9C8B /* Products */ = {
 			isa = PBXGroup;
 			children = (
-				932F5BD90822A1C700736975 /* _javascript_Core.framework */,
 				932F5BE10822A1C700736975 /* jsc */,
 				0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
+				932F5BD90822A1C700736975 /* _javascript_Core.framework */,
 				141211200A48793C00480255 /* minidom */,
 				14BD59BF0A3E8F9000BAF59C /* testapi */,
 				6511230514046A4C002B101D /* testRegExp */,
@@ -2290,6 +2294,8 @@
 				0F235BC317178E1C00690C7F /* FTLExitThunkGenerator.h */,
 				0F235BC417178E1C00690C7F /* FTLExitValue.cpp */,
 				0F235BC517178E1C00690C7F /* FTLExitValue.h */,
+				A7F2996917A0BB670010417A /* FTLFail.cpp */,
+				A7F2996A17A0BB670010417A /* FTLFail.h */,
 				0FEA0A2B170B661900BB722C /* FTLFormattedValue.h */,
 				A78A977C179738D5009DF744 /* FTLGeneratedFunction.h */,
 				0FEA0A261709623B00BB722C /* FTLIntrinsicRepository.cpp */,
@@ -3623,6 +3629,7 @@
 				0F235BD717178E1C00690C7F /* FTLExitArgumentList.h in Headers */,
 				0F235BD917178E1C00690C7F /* FTLExitThunkGenerator.h in Headers */,
 				0F235BDB17178E1C00690C7F /* FTLExitValue.h in Headers */,
+				A7F2996C17A0BB670010417A /* FTLFail.h in Headers */,
 				0FEA0A2C170B661900BB722C /* FTLFormattedValue.h in Headers */,
 				A78A977F179738D5009DF744 /* FTLGeneratedFunction.h in Headers */,
 				0FEA0A241709606900BB722C /* FTLIntrinsicRepository.h in Headers */,
@@ -4455,6 +4462,7 @@
 				0F235BD517178E1C00690C7F /* FTLExitArgumentForOperand.cpp in Sources */,
 				0F235BD817178E1C00690C7F /* FTLExitThunkGenerator.cpp in Sources */,
 				0F235BDA17178E1C00690C7F /* FTLExitValue.cpp in Sources */,
+				A7F2996B17A0BB670010417A /* FTLFail.cpp in Sources */,
 				0FEA0A281709623B00BB722C /* FTLIntrinsicRepository.cpp in Sources */,
 				0FEA0A0D170513DB00BB722C /* FTLJITCode.cpp in Sources */,
 				A78A9780179738D5009DF744 /* FTLJITFinalizer.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (153289 => 153290)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2013-07-25 04:05:18 UTC (rev 153289)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2013-07-25 04:05:20 UTC (rev 153290)
@@ -1819,7 +1819,8 @@
         || Options::validateGraphAtEachPhase()
         || Options::verboseOSR()
         || Options::verboseCompilationQueue()
-        || Options::reportCompileTimes())
+        || Options::reportCompileTimes()
+        || Options::verboseCFA())
         hash();
 
     if (Options::dumpGeneratedBytecodes())

Modified: trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp (153289 => 153290)


--- trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp	2013-07-25 04:05:18 UTC (rev 153289)
+++ trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp	2013-07-25 04:05:20 UTC (rev 153290)
@@ -32,22 +32,18 @@
 #include "DFGGraph.h"
 #include "DFGInPlaceAbstractState.h"
 #include "DFGPhase.h"
+#include "DFGSafeToExecute.h"
 #include "Operations.h"
 
 namespace JSC { namespace DFG {
 
 class CFAPhase : public Phase {
 public:
-#if DFG_ENABLE(DFG_PROPAGATION_VERBOSE)
-    static const bool verbose = true;
-#else
-    static const bool verbose = false;
-#endif
-
     CFAPhase(Graph& graph)
         : Phase(graph, "control flow analysis")
         , m_state(graph)
         , m_interpreter(graph, m_state)
+        , m_verbose(Options::verboseCFA())
     {
     }
     
@@ -59,6 +55,11 @@
         
         m_count = 0;
         
+        if (m_verbose && !shouldDumpGraphAtEachPhase()) {
+            dataLog("Graph before CFA:\n");
+            m_graph.dump();
+        }
+        
         // This implements a pseudo-worklist-based forward CFA, except that the visit order
         // of blocks is the bytecode program order (which is nearly topological), and
         // instead of a worklist we just walk all basic blocks checking if cfaShouldRevisit
@@ -87,37 +88,42 @@
             return;
         if (!block->cfaShouldRevisit)
             return;
-        if (verbose)
+        if (m_verbose)
             dataLog("   Block ", *block, ":\n");
         m_state.beginBasicBlock(block);
-        if (verbose) {
+        if (m_verbose) {
             dataLogF("      head vars: ");
             dumpOperands(block->valuesAtHead, WTF::dataFile());
             dataLogF("\n");
         }
         for (unsigned i = 0; i < block->size(); ++i) {
-            if (verbose) {
+            if (m_verbose) {
                 Node* node = block->at(i);
                 dataLogF("      %s @%u: ", Graph::opName(node->op()), node->index());
+                
+                if (!safeToExecute(m_state, m_graph, node))
+                    dataLog("(UNSAFE) ");
+                
                 m_interpreter.dump(WTF::dataFile());
+                
                 if (m_state.haveStructures())
                     dataLog(" (Have Structures)");
                 dataLogF("\n");
             }
             if (!m_interpreter.execute(i)) {
-                if (verbose)
+                if (m_verbose)
                     dataLogF("         Expect OSR exit.\n");
                 break;
             }
         }
-        if (verbose) {
+        if (m_verbose) {
             dataLogF("      tail regs: ");
             m_interpreter.dump(WTF::dataFile());
             dataLogF("\n");
         }
         m_changed |= m_state.endBasicBlock(MergeToSuccessors);
         
-        if (verbose) {
+        if (m_verbose) {
             dataLogF("      tail vars: ");
             dumpOperands(block->valuesAtTail, WTF::dataFile());
             dataLogF("\n");
@@ -127,7 +133,7 @@
     void performForwardCFA()
     {
         ++m_count;
-        if (verbose)
+        if (m_verbose)
             dataLogF("CFA [%u]\n", ++m_count);
         
         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex)
@@ -138,6 +144,8 @@
     InPlaceAbstractState m_state;
     AbstractInterpreter<InPlaceAbstractState> m_interpreter;
     
+    bool m_verbose;
+    
     bool m_changed;
     unsigned m_count;
 };

Added: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (0 => 153290)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2013-07-25 04:05:20 UTC (rev 153290)
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2013 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. 
+ */
+
+#ifndef DFGSafeToExecute_h
+#define DFGSafeToExecute_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGGraph.h"
+
+namespace JSC { namespace DFG {
+
+template<typename AbstractStateType>
+class SafeToExecuteEdge {
+public:
+    SafeToExecuteEdge(AbstractStateType& state)
+        : m_state(state)
+        , m_result(true)
+    {
+    }
+    
+    void operator()(Node*, Edge edge)
+    {
+        switch (edge.useKind()) {
+        case UntypedUse:
+        case Int32Use:
+        case RealNumberUse:
+        case NumberUse:
+        case BooleanUse:
+        case CellUse:
+        case ObjectUse:
+        case ObjectOrOtherUse:
+        case StringIdentUse:
+        case StringUse:
+        case StringObjectUse:
+        case StringOrStringObjectUse:
+        case NotCellUse:
+        case OtherUse:
+            return;
+            
+        case KnownInt32Use:
+            if (m_state.forNode(edge).m_type & ~SpecInt32)
+                m_result = false;
+            return;
+            
+        case KnownNumberUse:
+            if (m_state.forNode(edge).m_type & ~SpecNumber)
+                m_result = false;
+            return;
+            
+        case KnownCellUse:
+            if (m_state.forNode(edge).m_type & ~SpecCell)
+                m_result = false;
+            return;
+            
+        case KnownStringUse:
+            if (m_state.forNode(edge).m_type & ~SpecString)
+                m_result = false;
+            return;
+            
+        case LastUseKind:
+            RELEASE_ASSERT_NOT_REACHED();
+            break;
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+    
+    bool result() const { return m_result; }
+private:
+    AbstractStateType& m_state;
+    bool m_result;
+};
+
+// Determines if it's safe to execute a node within the given abstract state. This may
+// return false conservatively. If it returns true, then you can hoist the given node
+// up to the given point and expect that it will not crash. This doesn't guarantee that
+// the node will produce the result you wanted other than not crashing.
+template<typename AbstractStateType>
+bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node)
+{
+    SafeToExecuteEdge<AbstractStateType> safeToExecuteEdge(state);
+    DFG_NODE_DO_TO_CHILDREN(graph, node, safeToExecuteEdge);
+    if (!safeToExecuteEdge.result())
+        return false;
+
+    switch (node->op()) {
+    case JSConstant:
+    case WeakJSConstant:
+    case Identity:
+    case ToThis:
+    case CreateThis:
+    case GetCallee:
+    case SetCallee:
+    case GetLocal:
+    case SetLocal:
+    case MovHintAndCheck:
+    case MovHint:
+    case ZombieHint:
+    case GetArgument:
+    case Phantom:
+    case Upsilon:
+    case Phi:
+    case Flush:
+    case PhantomLocal:
+    case GetLocalUnlinked:
+    case SetArgument:
+    case InlineStart:
+    case BitAnd:
+    case BitOr:
+    case BitXor:
+    case BitLShift:
+    case BitRShift:
+    case BitURShift:
+    case ValueToInt32:
+    case UInt32ToNumber:
+    case Int32ToDouble:
+    case ForwardInt32ToDouble:
+    case DoubleAsInt32:
+    case ArithAdd:
+    case ArithSub:
+    case ArithNegate:
+    case ArithMul:
+    case ArithIMul:
+    case ArithDiv:
+    case ArithMod:
+    case ArithAbs:
+    case ArithMin:
+    case ArithMax:
+    case ArithSqrt:
+    case ValueAdd:
+    case GetById:
+    case GetByIdFlush:
+    case PutById:
+    case PutByIdDirect:
+    case CheckStructure:
+    case CheckExecutable:
+    case ForwardCheckStructure:
+    case GetButterfly:
+    case CheckArray:
+    case ForwardCheckArray:
+    case Arrayify:
+    case ArrayifyToStructure:
+    case GetScope:
+    case GetMyScope:
+    case SetMyScope:
+    case SkipTopScope:
+    case SkipScope:
+    case GetClosureRegisters:
+    case GetClosureVar:
+    case PutClosureVar:
+    case GetGlobalVar:
+    case PutGlobalVar:
+    case GlobalVarWatchpoint:
+    case VarInjectionWatchpoint:
+    case CheckFunction:
+    case AllocationProfileWatchpoint:
+    case RegExpExec:
+    case RegExpTest:
+    case CompareLess:
+    case CompareLessEq:
+    case CompareGreater:
+    case CompareGreaterEq:
+    case CompareEq:
+    case CompareEqConstant:
+    case CompareStrictEq:
+    case CompareStrictEqConstant:
+    case Call:
+    case Construct:
+    case NewObject:
+    case NewArray:
+    case NewArrayWithSize:
+    case NewArrayBuffer:
+    case NewRegexp:
+    case Breakpoint:
+    case CheckHasInstance:
+    case InstanceOf:
+    case IsUndefined:
+    case IsBoolean:
+    case IsNumber:
+    case IsString:
+    case IsObject:
+    case IsFunction:
+    case TypeOf:
+    case LogicalNot:
+    case ToPrimitive:
+    case ToString:
+    case NewStringObject:
+    case MakeRope:
+    case In:
+    case CreateActivation:
+    case TearOffActivation:
+    case CreateArguments:
+    case PhantomArguments:
+    case TearOffArguments:
+    case GetMyArgumentsLength:
+    case GetMyArgumentByVal:
+    case GetMyArgumentsLengthSafe:
+    case GetMyArgumentByValSafe:
+    case CheckArgumentsNotCreated:
+    case NewFunctionNoCheck:
+    case NewFunction:
+    case NewFunctionExpression:
+    case Jump:
+    case Branch:
+    case Switch:
+    case Return:
+    case Throw:
+    case ThrowReferenceError:
+    case CountExecution:
+    case ForceOSRExit:
+    case ForwardForceOSRExit:
+    case CheckWatchdogTimer:
+    case StringFromCharCode:
+        return true;
+        
+    case GetByVal:
+    case GetIndexedPropertyStorage:
+    case GetArrayLength:
+    case ArrayPush:
+    case ArrayPop:
+    case StringCharAt:
+    case StringCharCodeAt:
+        return node->arrayMode().alreadyChecked(graph, node, state.forNode(node->child1()));
+        
+    case PutByVal:
+    case PutByValAlias:
+        return node->arrayMode().modeForPut().alreadyChecked(
+            graph, node, state.forNode(graph.varArgChild(node, 0)));
+
+    case StructureTransitionWatchpoint:
+    case ForwardStructureTransitionWatchpoint:
+        return state.forNode(node->child1()).m_futurePossibleStructure.isSubsetOf(
+            StructureSet(node->structure()));
+        
+    case PutStructure:
+    case PhantomPutStructure:
+    case AllocatePropertyStorage:
+    case ReallocatePropertyStorage:
+        return state.forNode(node->child1()).m_currentKnownStructure.isSubsetOf(
+            StructureSet(node->structureTransitionData().previousStructure));
+        
+    case GetByOffset:
+    case PutByOffset:
+        return state.forNode(node->child1()).m_currentKnownStructure.isValidOffset(
+            graph.m_storageAccessData[node->storageAccessDataIndex()].offset);
+        
+    case LastNodeType:
+        RELEASE_ASSERT_NOT_REACHED();
+        return false;
+    }
+    
+    RELEASE_ASSERT_NOT_REACHED();
+    return false;
+}
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGSafeToExecute_h
+

Modified: trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.h (153289 => 153290)


--- trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.h	2013-07-25 04:05:18 UTC (rev 153289)
+++ trunk/Source/_javascript_Core/dfg/DFGStructureAbstractValue.h	2013-07-25 04:05:20 UTC (rev 153290)
@@ -282,6 +282,15 @@
         return speculationFromStructure(m_structure);
     }
     
+    bool isValidOffset(PropertyOffset offset)
+    {
+        if (isTop())
+            return false;
+        if (isClear())
+            return true;
+        return m_structure->isValidOffset(offset);
+    }
+    
     bool hasSingleton() const
     {
         return isNeitherClearNorTop();

Modified: trunk/Source/_javascript_Core/runtime/Options.h (153289 => 153290)


--- trunk/Source/_javascript_Core/runtime/Options.h	2013-07-25 04:05:18 UTC (rev 153289)
+++ trunk/Source/_javascript_Core/runtime/Options.h	2013-07-25 04:05:20 UTC (rev 153290)
@@ -113,6 +113,7 @@
     v(bool, verboseCallLink, false) \
     v(bool, verboseCompilationQueue, false) \
     v(bool, reportCompileTimes, false) \
+    v(bool, verboseCFA, false) \
     \
     v(bool, enableOSREntryInLoops, true) \
     \
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to