Changeset 179840 in webkit
- Timestamp:
- Feb 9, 2015, 11:57:41 AM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 10 edited
-
ChangeLog (modified) (1 diff)
-
dfg/DFGClobberize.cpp (modified) (2 diffs)
-
dfg/DFGClobberize.h (modified) (2 diffs)
-
dfg/DFGDoesGC.cpp (modified) (3 diffs)
-
dfg/DFGFixupPhase.cpp (modified) (16 diffs)
-
dfg/DFGGraph.h (modified) (1 diff)
-
dfg/DFGNode.h (modified) (6 diffs)
-
dfg/DFGNodeFlags.cpp (modified) (1 diff)
-
dfg/DFGNodeFlags.h (modified) (2 diffs)
-
dfg/DFGNodeType.h (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r179831 r179840 1 2015-02-08 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should only have two mechanisms for describing effectfulness of nodes; previously there were three 4 https://bugs.webkit.org/show_bug.cgi?id=141369 5 6 Reviewed by Michael Saboff. 7 8 We previously used the NodeMightClobber and NodeClobbersWorld NodeFlags to describe 9 effectfulness. Starting over a year ago, we introduced a more powerful mechanism - the 10 DFG::clobberize() function. Now we only have one remaining client of the old NodeFlags, 11 and everyone else uses DFG::clobberize(). We should get rid of those NodeFlags and 12 finally switch everyone over to DFG::clobberize(). 13 14 Unfortunately there is still another place where effectfulness of nodes is described: the 15 AbstractInterpreter. This is because the AbstractInterpreter has special tuning both for 16 compile time performance and there are places where the AI is more precise than 17 clobberize() because of its flow-sensitivity. 18 19 This means that after this change there will be only two places, rather than three, where 20 the effectfulness of a node has to be described: 21 22 - DFG::clobberize() 23 - DFG::AbstractInterpreter 24 25 * dfg/DFGClobberize.cpp: 26 (JSC::DFG::clobbersWorld): 27 * dfg/DFGClobberize.h: 28 * dfg/DFGDoesGC.cpp: 29 (JSC::DFG::doesGC): 30 * dfg/DFGFixupPhase.cpp: 31 (JSC::DFG::FixupPhase::fixupNode): 32 (JSC::DFG::FixupPhase::attemptToMakeGetTypedArrayByteLength): 33 (JSC::DFG::FixupPhase::convertToGetArrayLength): 34 (JSC::DFG::FixupPhase::attemptToMakeGetTypedArrayByteOffset): 35 * dfg/DFGGraph.h: 36 (JSC::DFG::Graph::isPredictedNumerical): Deleted. 37 (JSC::DFG::Graph::byValIsPure): Deleted. 38 (JSC::DFG::Graph::clobbersWorld): Deleted. 39 * dfg/DFGNode.h: 40 (JSC::DFG::Node::convertToConstant): 41 (JSC::DFG::Node::convertToGetLocalUnlinked): 42 (JSC::DFG::Node::convertToGetByOffset): 43 (JSC::DFG::Node::convertToMultiGetByOffset): 44 (JSC::DFG::Node::convertToPutByOffset): 45 (JSC::DFG::Node::convertToMultiPutByOffset): 46 * dfg/DFGNodeFlags.cpp: 47 (JSC::DFG::dumpNodeFlags): 48 * dfg/DFGNodeFlags.h: 49 * dfg/DFGNodeType.h: 50 1 51 2015-02-09 Csaba Osztrogonác <ossy@webkit.org> 2 52 -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.cpp
r172129 r179840 1 1 /* 2 * Copyright (C) 2013 , 2014Apple Inc. All rights reserved.2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 57 57 } 58 58 59 bool clobbersWorld(Graph& graph, Node* node) 60 { 61 bool result = false; 62 clobberize( 63 graph, node, NoOpClobberize(), 64 [&] (AbstractHeap heap) { 65 if (heap == AbstractHeap(World)) 66 result = true; 67 }, 68 NoOpClobberize()); 69 return result; 70 } 71 59 72 } } // namespace JSC::DFG 60 73 -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r179478 r179840 1 1 /* 2 * Copyright (C) 2013 , 2014Apple Inc. All rights reserved.2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 935 935 bool writesOverlap(Graph&, Node*, AbstractHeap); 936 936 937 bool clobbersWorld(Graph&, Node*); 938 937 939 // We would have used bind() for these, but because of the overlaoding that we are doing, 938 940 // it's quite a bit of clearer to just write this out the traditional way. -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r179478 r179840 1 1 /* 2 * Copyright (C) 2014 Apple Inc. All rights reserved.2 * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #if ENABLE(DFG_JIT) 30 30 31 #include "DFGClobberize.h" 31 32 #include "DFGGraph.h" 32 33 #include "DFGNode.h" … … 37 38 bool doesGC(Graph& graph, Node* node) 38 39 { 39 if ( graph.clobbersWorld(node))40 if (clobbersWorld(graph, node)) 40 41 return true; 41 42 -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r179621 r179840 1 1 /* 2 * Copyright (C) 2012 , 2013, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 162 162 if (attemptToMakeIntegerAdd(node)) { 163 163 node->setOp(ArithAdd); 164 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);164 node->clearFlags(NodeMustGenerate); 165 165 break; 166 166 } … … 169 169 fixDoubleOrBooleanEdge(node->child2()); 170 170 node->setOp(ArithAdd); 171 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);171 node->clearFlags(NodeMustGenerate); 172 172 node->setResult(NodeResultDouble); 173 173 break; … … 383 383 fixEdge<BooleanUse>(node->child1()); 384 384 fixEdge<BooleanUse>(node->child2()); 385 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);385 node->clearFlags(NodeMustGenerate); 386 386 break; 387 387 } … … 389 389 fixIntOrBooleanEdge(node->child1()); 390 390 fixIntOrBooleanEdge(node->child2()); 391 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);391 node->clearFlags(NodeMustGenerate); 392 392 break; 393 393 } … … 396 396 fixEdge<Int52RepUse>(node->child1()); 397 397 fixEdge<Int52RepUse>(node->child2()); 398 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);398 node->clearFlags(NodeMustGenerate); 399 399 break; 400 400 } … … 402 402 fixDoubleOrBooleanEdge(node->child1()); 403 403 fixDoubleOrBooleanEdge(node->child2()); 404 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);404 node->clearFlags(NodeMustGenerate); 405 405 break; 406 406 } … … 410 410 fixEdge<StringIdentUse>(node->child1()); 411 411 fixEdge<StringIdentUse>(node->child2()); 412 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);412 node->clearFlags(NodeMustGenerate); 413 413 break; 414 414 } … … 416 416 fixEdge<StringUse>(node->child1()); 417 417 fixEdge<StringUse>(node->child2()); 418 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);418 node->clearFlags(NodeMustGenerate); 419 419 break; 420 420 } … … 422 422 fixEdge<ObjectUse>(node->child1()); 423 423 fixEdge<ObjectUse>(node->child2()); 424 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);424 node->clearFlags(NodeMustGenerate); 425 425 break; 426 426 } … … 428 428 fixEdge<ObjectUse>(node->child1()); 429 429 fixEdge<ObjectOrOtherUse>(node->child2()); 430 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);430 node->clearFlags(NodeMustGenerate); 431 431 break; 432 432 } … … 434 434 fixEdge<ObjectOrOtherUse>(node->child1()); 435 435 fixEdge<ObjectUse>(node->child2()); 436 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);436 node->clearFlags(NodeMustGenerate); 437 437 break; 438 438 } … … 830 830 if (node->child1()->shouldSpeculateInt32()) { 831 831 fixEdge<Int32Use>(node->child1()); 832 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);832 node->clearFlags(NodeMustGenerate); 833 833 break; 834 834 } … … 1948 1948 // that overflows int32. 1949 1949 node->setOp(BitLShift); 1950 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);1950 node->clearFlags(NodeMustGenerate); 1951 1951 observeUseKindOnNode(length, Int32Use); 1952 1952 observeUseKindOnNode(shiftAmount, Int32Use); … … 1959 1959 { 1960 1960 node->setOp(GetArrayLength); 1961 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);1961 node->clearFlags(NodeMustGenerate); 1962 1962 fixEdge<KnownCellUse>(node->child1()); 1963 1963 node->setArrayMode(arrayMode); … … 1992 1992 1993 1993 node->setOp(GetTypedArrayByteOffset); 1994 node->clearFlags(NodeMustGenerate | NodeClobbersWorld);1994 node->clearFlags(NodeMustGenerate); 1995 1995 fixEdge<KnownCellUse>(node->child1()); 1996 1996 return true; -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r174318 r179840 545 545 546 546 void killUnreachableBlocks(); 547 548 bool isPredictedNumerical(Node* node)549 {550 return isNumerical(node->child1().useKind()) && isNumerical(node->child2().useKind());551 }552 553 // Note that a 'true' return does not actually mean that the ByVal access clobbers nothing.554 // It really means that it will not clobber the entire world. It's still up to you to555 // carefully consider things like:556 // - PutByVal definitely changes the array it stores to, and may even change its length.557 // - PutByOffset definitely changes the object it stores to.558 // - and so on.559 bool byValIsPure(Node* node)560 {561 switch (node->arrayMode().type()) {562 case Array::Generic:563 return false;564 case Array::Int32:565 case Array::Double:566 case Array::Contiguous:567 case Array::ArrayStorage:568 return !node->arrayMode().isOutOfBounds();569 case Array::SlowPutArrayStorage:570 return !node->arrayMode().mayStoreToHole();571 case Array::String:572 return node->op() == GetByVal && node->arrayMode().isInBounds();573 #if USE(JSVALUE32_64)574 case Array::Arguments:575 if (node->op() == GetByVal)576 return true;577 return false;578 #endif // USE(JSVALUE32_64)579 default:580 return true;581 }582 }583 584 bool clobbersWorld(Node* node)585 {586 if (node->flags() & NodeClobbersWorld)587 return true;588 if (!(node->flags() & NodeMightClobber))589 return false;590 switch (node->op()) {591 case GetByVal:592 case PutByValDirect:593 case PutByVal:594 case PutByValAlias:595 return !byValIsPure(node);596 case ToString:597 switch (node->child1().useKind()) {598 case StringObjectUse:599 case StringOrStringObjectUse:600 return false;601 case CellUse:602 case UntypedUse:603 return true;604 default:605 RELEASE_ASSERT_NOT_REACHED();606 return true;607 }608 default:609 RELEASE_ASSERT_NOT_REACHED();610 return true; // If by some oddity we hit this case in release build it's safer to have CSE assume the worst.611 }612 }613 547 614 548 void determineReachability(); -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r179814 r179840 449 449 else 450 450 m_op = JSConstant; 451 m_flags &= ~ (NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);451 m_flags &= ~NodeMustGenerate; 452 452 m_opInfo = bitwise_cast<uintptr_t>(value); 453 453 children.reset(); … … 465 465 { 466 466 m_op = GetLocalUnlinked; 467 m_flags &= ~ (NodeMustGenerate | NodeMightClobber | NodeClobbersWorld);467 m_flags &= ~NodeMustGenerate; 468 468 m_opInfo = local.offset(); 469 469 m_opInfo2 = VirtualRegister().offset(); … … 479 479 children.setChild1(storage); 480 480 m_op = GetByOffset; 481 m_flags &= ~ (NodeClobbersWorld | NodeMustGenerate);481 m_flags &= ~NodeMustGenerate; 482 482 } 483 483 … … 488 488 child1().setUseKind(CellUse); 489 489 m_op = MultiGetByOffset; 490 m_flags &= ~NodeClobbersWorld;491 490 ASSERT(m_flags & NodeMustGenerate); 492 491 } … … 500 499 children.setChild1(storage); 501 500 m_op = PutByOffset; 502 m_flags &= ~NodeClobbersWorld;503 501 } 504 502 … … 508 506 m_opInfo = bitwise_cast<intptr_t>(data); 509 507 m_op = MultiPutByOffset; 510 m_flags &= ~NodeClobbersWorld;511 508 } 512 509 -
trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.cpp
r171613 r179840 75 75 out.print(comma, "VarArgs"); 76 76 77 if (flags & NodeClobbersWorld)78 out.print(comma, "Clobbers");79 80 if (flags & NodeMightClobber)81 out.print(comma, "MightClobber");82 83 77 if (flags & NodeResultMask) { 84 78 if (!(flags & NodeBytecodeUsesAsNumber) && !(flags & NodeBytecodeNeedsNegZero)) -
trunk/Source/JavaScriptCore/dfg/DFGNodeFlags.h
r174371 r179840 1 1 /* 2 * Copyright (C) 2012 , 2013, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 47 47 #define NodeMustGenerate 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE. 48 48 #define NodeHasVarArgs 0x0010 49 #define NodeClobbersWorld 0x0020 50 #define NodeMightClobber 0x0040 49 // 0x0020 and 0x0040 are free. 51 50 52 51 #define NodeBehaviorMask 0x0780 -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r179536 r179840 1 1 /* 2 * Copyright (C) 2012 , 2013, 2014Apple Inc. All rights reserved.2 * Copyright (C) 2012-2015 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 140 140 \ 141 141 /* Add of values may either be arithmetic, or result in string concatenation. */\ 142 macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \142 macro(ValueAdd, NodeResultJS | NodeMustGenerate) \ 143 143 \ 144 144 /* Property access. */\ … … 147 147 /* this must be the directly subsequent property put. Note that PutByVal */\ 148 148 /* opcodes use VarArgs beause they may have up to 4 children. */\ 149 macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \150 macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \151 macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \152 macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \153 macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \154 macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \155 macro(PutById, NodeMustGenerate | NodeClobbersWorld) \156 macro(PutByIdFlush, NodeMustGenerate | NodeMustGenerate | NodeClobbersWorld) \157 macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \149 macro(GetByVal, NodeResultJS | NodeMustGenerate) \ 150 macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs) \ 151 macro(PutByVal, NodeMustGenerate | NodeHasVarArgs) \ 152 macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs) \ 153 macro(GetById, NodeResultJS | NodeMustGenerate) \ 154 macro(GetByIdFlush, NodeResultJS | NodeMustGenerate) \ 155 macro(PutById, NodeMustGenerate) \ 156 macro(PutByIdFlush, NodeMustGenerate | NodeMustGenerate) \ 157 macro(PutByIdDirect, NodeMustGenerate) \ 158 158 macro(CheckStructure, NodeMustGenerate) \ 159 159 macro(GetExecutable, NodeResultJS) \ … … 194 194 \ 195 195 /* Optimizations for array mutation. */\ 196 macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \197 macro(ArrayPop, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \196 macro(ArrayPush, NodeResultJS | NodeMustGenerate) \ 197 macro(ArrayPop, NodeResultJS | NodeMustGenerate) \ 198 198 \ 199 199 /* Optimizations for regular expression matching. */\ … … 207 207 \ 208 208 /* Nodes for comparison operations. */\ 209 macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \210 macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \211 macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \212 macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \213 macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \209 macro(CompareLess, NodeResultBoolean | NodeMustGenerate) \ 210 macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate) \ 211 macro(CompareGreater, NodeResultBoolean | NodeMustGenerate) \ 212 macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate) \ 213 macro(CompareEq, NodeResultBoolean | NodeMustGenerate) \ 214 214 macro(CompareEqConstant, NodeResultBoolean) \ 215 215 macro(CompareStrictEq, NodeResultBoolean) \ 216 216 \ 217 217 /* Calls. */\ 218 macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \219 macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \220 macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \221 macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \218 macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \ 219 macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \ 220 macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \ 221 macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \ 222 222 \ 223 223 /* Allocations. */\ … … 226 226 macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \ 227 227 macro(NewArrayBuffer, NodeResultJS) \ 228 macro(NewTypedArray, NodeResultJS | Node ClobbersWorld | NodeMustGenerate) \228 macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \ 229 229 macro(NewRegexp, NodeResultJS) \ 230 230 \ … … 250 250 macro(TypeOf, NodeResultJS) \ 251 251 macro(LogicalNot, NodeResultBoolean) \ 252 macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \253 macro(ToString, NodeResultJS | NodeMustGenerate | NodeMightClobber) \252 macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \ 253 macro(ToString, NodeResultJS | NodeMustGenerate) \ 254 254 macro(NewStringObject, NodeResultJS) \ 255 255 macro(MakeRope, NodeResultJS) \ 256 macro(In, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \256 macro(In, NodeResultBoolean | NodeMustGenerate) \ 257 257 macro(ProfileType, NodeMustGenerate) \ 258 258 macro(ProfileControlFlow, NodeMustGenerate) \ … … 270 270 macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \ 271 271 macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \ 272 macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \273 macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \272 macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate) \ 273 macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate) \ 274 274 macro(CheckArgumentsNotCreated, NodeMustGenerate) \ 275 275 \
Note:
See TracChangeset
for help on using the changeset viewer.