Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Specialize args prototype #4

Open
wants to merge 41 commits into
base: master-spec
Choose a base branch
from

Conversation

caiolima
Copy link
Owner

No description provided.

Caio Lima and others added 30 commits April 4, 2017 17:31
caiolima added a commit that referenced this pull request Apr 3, 2018
caiolima added a commit that referenced this pull request Apr 3, 2018
caiolima added a commit that referenced this pull request Apr 4, 2018
caiolima pushed a commit that referenced this pull request Apr 4, 2018
caiolima added a commit that referenced this pull request Apr 8, 2018
caiolima pushed a commit that referenced this pull request Apr 9, 2018
caiolima pushed a commit that referenced this pull request Nov 14, 2018
…llFrame.

https://bugs.webkit.org/show_bug.cgi?id=191579
<rdar://problem/45942472>

Reviewed by Saam Barati.

JSTests:

* stress/regress-191579.js: Added.

Source/JavaScriptCore:

Both of these functions do a lot of work.  It would be good for the topCallFrame
to be correct should we need to throw an exception.

For example, we've observed the following crash trace:

  * frame #0: WTFCrash() at Assertions.cpp:253
    frame #1: ...
    frame #2: JSC::StructureIDTable::get(this=0x00006040000162f0, structureID=1874583248) at StructureIDTable.h:129
    frame #3: JSC::VM::getStructure(this=0x0000604000016210, id=4022066896) at VM.h:705
    frame #4: JSC::JSCell::structure(this=0x00007ffeefbbde30, vm=0x0000604000016210) const at JSCellInlines.h:125
    frame #5: JSC::JSCell::classInfo(this=0x00007ffeefbbde30, vm=0x0000604000016210) const at JSCellInlines.h:335
    frame #6: JSC::JSCell::inherits(this=0x00007ffeefbbde30, vm=0x0000604000016210, info=0x0000000105eaf020) const at JSCellInlines.h:302
    frame WebKit#7: JSC::JSObject* JSC::jsCast<JSC::JSObject*, JSC::JSCell>(from=0x00007ffeefbbde30) at JSCast.h:36
    frame WebKit#8: JSC::asObject(cell=0x00007ffeefbbde30) at JSObject.h:1299
    frame WebKit#9: JSC::asObject(value=JSValue @ 0x00007ffeefbba380) at JSObject.h:1304
    frame WebKit#10: JSC::Register::object(this=0x00007ffeefbbdd58) const at JSObject.h:1514
    frame WebKit#11: JSC::ExecState::jsCallee(this=0x00007ffeefbbdd40) const at CallFrame.h:107
    frame WebKit#12: JSC::ExecState::isStackOverflowFrame(this=0x00007ffeefbbdd40) const at CallFrameInlines.h:36
    frame WebKit#13: JSC::StackVisitor::StackVisitor(this=0x00007ffeefbba860, startFrame=0x00007ffeefbbdd40, vm=0x0000631000000800) at StackVisitor.cpp:52
    frame WebKit#14: JSC::StackVisitor::StackVisitor(this=0x00007ffeefbba860, startFrame=0x00007ffeefbbdd40, vm=0x0000631000000800) at StackVisitor.cpp:41
    frame WebKit#15: void JSC::StackVisitor::visit<(JSC::StackVisitor::EmptyEntryFrameAction)0, JSC::Interpreter::getStackTrace(JSC::JSCell*, WTF::Vector<JSC::StackFrame, 0ul, WTF::CrashOnOverflow, 16ul>&, unsigned long, unsigned long)::$_3>(startFrame=0x00007ffeefbbdd40, vm=0x0000631000000800, functor=0x00007ffeefbbaa60)::$_3 const&) at StackVisitor.h:147
    frame WebKit#16: JSC::Interpreter::getStackTrace(this=0x0000602000005db0, owner=0x000062d00020cbe0, results=0x00006020000249d0, framesToSkip=0, maxStackSize=1) at Interpreter.cpp:437
    frame WebKit#17: JSC::getStackTrace(exec=0x000062d00002c048, vm=0x0000631000000800, obj=0x000062d00020cbe0, useCurrentFrame=true) at Error.cpp:170
    frame WebKit#18: JSC::ErrorInstance::finishCreation(this=0x000062d00020cbe0, exec=0x000062d00002c048, vm=0x0000631000000800, message=0x00007ffeefbbb800, useCurrentFrame=true) at ErrorInstance.cpp:119
    frame WebKit#19: JSC::ErrorInstance::create(exec=0x000062d00002c048, vm=0x0000631000000800, structure=0x000062d0000f5730, message=0x00007ffeefbbb800, appender=0x0000000000000000, type=TypeNothing, useCurrentFrame=true)(WTF::String const&, WTF::String const&, JSC::RuntimeType, JSC::ErrorInstance::SourceTextWhereErrorOccurred), JSC::RuntimeType, bool) at ErrorInstance.h:49
    frame WebKit#20: JSC::createRangeError(exec=0x000062d00002c048, globalObject=0x000062d00002c000, message=0x00007ffeefbbb800, appender=0x0000000000000000)(WTF::String const&, WTF::String const&, JSC::RuntimeType, JSC::ErrorInstance::SourceTextWhereErrorOccurred)) at Error.cpp:68
    frame WebKit#21: JSC::createRangeError(exec=0x000062d00002c048, globalObject=0x000062d00002c000, message=0x00007ffeefbbb800) at Error.cpp:316
    frame WebKit#22: JSC::createStackOverflowError(exec=0x000062d00002c048, globalObject=0x000062d00002c000) at ExceptionHelpers.cpp:77
    frame WebKit#23: JSC::createStackOverflowError(exec=0x000062d00002c048) at ExceptionHelpers.cpp:72
    frame WebKit#24: JSC::throwStackOverflowError(exec=0x000062d00002c048, scope=0x00007ffeefbbbaa0) at ExceptionHelpers.cpp:335
    frame WebKit#25: JSC::ProxyObject::getOwnPropertySlotCommon(this=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbba80, slot=0x00007ffeefbbc720) at ProxyObject.cpp:372
    frame WebKit#26: JSC::ProxyObject::getOwnPropertySlot(object=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbbd40, slot=0x00007ffeefbbc720) at ProxyObject.cpp:395
    frame WebKit#27: JSC::JSObject::getNonIndexPropertySlot(this=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbbea0, slot=0x00007ffeefbbc720) at JSObjectInlines.h:150
    frame WebKit#28: bool JSC::JSObject::getPropertySlot<false>(this=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbc320, slot=0x00007ffeefbbc720) at JSObject.h:1424
    frame WebKit#29: JSC::JSObject::calculatedClassName(object=0x000062d000200e40) at JSObject.cpp:535
    frame WebKit#30: JSC::Structure::toStructureShape(this=0x000062d000007410, value=JSValue @ 0x00007ffeefbbcae0, sawPolyProtoStructure=0x00007ffeefbbcf60) at Structure.cpp:1142
    frame WebKit#31: JSC::TypeProfilerLog::processLogEntries(this=0x000060400000a950, reason=0x00007ffeefbbd5c0) at TypeProfilerLog.cpp:89
    frame WebKit#32: JSC::JIT::doMainThreadPreparationBeforeCompile(this=0x0000619000034da0) at JIT.cpp:951
    frame WebKit#33: JSC::JITWorklist::Plan::Plan(this=0x0000619000034d80, codeBlock=0x000062d0001d88c0, loopOSREntryBytecodeOffset=0) at JITWorklist.cpp:43
    frame WebKit#34: JSC::JITWorklist::Plan::Plan(this=0x0000619000034d80, codeBlock=0x000062d0001d88c0, loopOSREntryBytecodeOffset=0) at JITWorklist.cpp:42
    frame WebKit#35: JSC::JITWorklist::compileLater(this=0x0000616000001b80, codeBlock=0x000062d0001d88c0, loopOSREntryBytecodeOffset=0) at JITWorklist.cpp:256
    frame WebKit#36: JSC::LLInt::jitCompileAndSetHeuristics(codeBlock=0x000062d0001d88c0, exec=0x00007ffeefbbde30, loopOSREntryBytecodeOffset=0) at LLIntSlowPaths.cpp:391
    frame WebKit#37: llint_replace(exec=0x00007ffeefbbde30, pc=0x00006040000161ba) at LLIntSlowPaths.cpp:516
    frame WebKit#38: llint_entry at LowLevelInterpreter64.asm:98
    frame #39: vmEntryToJavaScript at LowLevelInterpreter64.asm:296
    ...

This crash occurred because StackVisitor was seeing an invalid topCallFrame while
trying to capture the Error stack while throwing a StackOverflowError below
llint_replace.  While in this specific example, it is questionable whether we
should be executing JS code below TypeProfilerLog::processLogEntries(), it is
correct to have set the topCallFrame in llint_replace.  We do this by calling
LLINT_BEGIN_NO_SET_PC() at the top of llint_replace.

We also do the same for llint_osr.
        
Note: both of these LLInt slow path functions are called with a fully initialized
CallFrame.  Hence, there's no issue with setting topCallFrame to their CallFrames
for these functions.

* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@238141 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Mar 8, 2019
https://bugs.webkit.org/show_bug.cgi?id=195444

Reviewed by Saam Barati.

Previously, we are merging must handle values as a proven constant in CFA. This is OK as long as this proven AbstractValue is blurred by merging the other legit AbstractValues
from the successors. But let's consider the following code, this is actually generated DFG graph from the attached test in r242626.

    Block #2 (loop header) succ #3, #4
    ...
    1: ForceOSRExit
    ...
    2: JSConstant(0)
    3: SetLocal(@2, loc6)
    ...
    4: Branch(#3, #4)

    Block #3 (This is OSR entry target) pred #2, #3, must handle value for loc6 => JSConstant(Int32, 31)
    ...
    5: GetLocal(loc6)
    6: StringFromCharCode(@5)
    ...

Block #3 is OSR entry target. So we have must handle value for loc6 and it is Int32 constant 31. Then we merge this constant as a proven value in #3's loc6 AbstractValue.
If the value from #2 blurs the value, it is OK. However, #2 has ForceOSRExit. So must handle value suddenly becomes the only source of loc6 in #3. Then we use this constant
as a proven value. But this is not expected behavior since must handle value is just a snapshot of the locals when we kick off the concurrent compilation. In the above example,
we assume that loop index is an constant 31, but it is wrong, and OSR entry fails. Because there is no strong assumption that the must handle value is the proven type or value,
we should not merge it in CFA.

Since (1) this is just an optimization, (2) type information is already propagated in prediction injection phase, and (3) the must handle value does not show the performance
progression in r211461 and we no longer see type misprediction in marsaglia-osr-entry.js, this patch simply removes must handle value type widening in CFA.

* dfg/DFGCFAPhase.cpp:
(JSC::DFG::CFAPhase::run):
(JSC::DFG::CFAPhase::performBlockCFA):
(JSC::DFG::CFAPhase::injectOSR): Deleted.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@242627 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Mar 25, 2019
https://bugs.webkit.org/show_bug.cgi?id=196025

Reviewed by Simon Fraser.

SVG attributes like "fill" and "stroke" do not have reflecting properties
in SVGElement but they are animatable by SMIL. Animating such attributes
is different from animating the SVG animated properties. These new classes
will be added to handle the first type of this kind of attribute: the Color:

-- SVGPropertyAnimatorCreator is added to SVGElement. It is responsible 
   for creating SVGPropertyAnimators for the attribute which do not have
   reflecting animated properties stored by SVGElement. It will maintain
   a HashMap for the animated values for these attributes which is indexed
   by the attribute name. The animated values has to be RefCounted because
   the same attribute can be animated by multiple animators. So the values
   of this HashMap will be of type Ref<SVGProperty>, e.g.
    <circle cx="80" cy="120" r="35">
        <animate attributeName="fill" values="#080" begin="2s" />
        <animate attributeName="fill" values="#602;#4" begin="4s" dur="5s"/>
    </circle>

-- SVGPropertyAnimator is the a new type which animates an attribute with
   no reflecting animated property.

-- SVGPrimitivePropertyAnimator is a template class which is responsible
   for animating attributes with primitive types, e.g. Color, string and 
   float. It is derived form SVGPropertyAnimator and it is initialized 
   with a Ref<SVGValueProperty<PropertyType>> which is created and maintained
   by SVGPropertyAnimatorFactory.

-- SVGAnimationColorFunction is the animation function that animates the
   attributes whose type are Color. Note the conversion form String to 
   Color in this class has to handle the case when its value is "attributeName="
   e.g. <animate attributeName="fill" from="attributeName="r"/>

-- SVGColorAnimator will be defined to be
   SVGPrimitivePropertyAnimator<Color, SVGAnimationColorFunction>.

The life cycle of the RefCounted properties can be explained as follows:

-- SVGPropertyAnimatorFactory checks whether its HashMap has an entry
   for the given attribute name. If it does not have, it will create a
   new value through the value creation method for this attribute.

-- SVGPropertyAnimatorFactory passes the shared animated value to the
   animator creation method. So multiple animators will be accessing the
   same value through their RefCounted pointers.

-- When the animator is about to be deleted, it will notify the target
   SVGElement which will notify its SVGPropertyAnimatorFactory.
   SVGPropertyAnimatorFactory will check its HashMap and retrieves the
   entry for the given attribute name. If the refCount is 2, it is going
   to remove the entry form the HashMap.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* svg/SVGAnimateColorElement.cpp:
(WebCore::attributeValueIsCurrentColor): Deleted.
(WebCore::SVGAnimateColorElement::determinePropertyValueTypes): Deleted.
* svg/SVGAnimateColorElement.h:
* svg/SVGAnimateElementBase.cpp:
(WebCore::SVGAnimateElementBase::attributeAnimationController):
* svg/SVGAnimatedColor.cpp: Removed.
* svg/SVGAnimatedColor.h: Removed.
* svg/SVGAnimatorFactory.h:
(WebCore::SVGAnimatorFactory::create):
* svg/SVGAttributeAnimationController.cpp:
(WebCore::SVGAttributeAnimationController::~SVGAttributeAnimationController):
* svg/SVGAttributeAnimationController.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::SVGElement):
(WebCore::SVGElement::isAnimatedAttribute const):
(WebCore::SVGElement::createAnimator):
(WebCore::SVGElement::animatorWillBeDeleted):
* svg/SVGElement.h:
(WebCore::SVGElement::propertyAnimatorFactory):
* svg/SVGFitToViewBox.h:
* svg/SVGMPathElement.cpp:
* svg/graphics/filters/SVGFEImage.h:
* svg/properties/SVGAnimationAdditiveValueFunctionImpl.cpp: Added.
(WebCore::SVGAnimationColorFunction::colorFromString):
* svg/properties/SVGAnimationAdditiveValueFunctionImpl.h:
(WebCore::SVGAnimationColorFunction::progress):
* svg/properties/SVGAnimationFunction.h:
* svg/properties/SVGAttributeAnimator.cpp:
(WebCore::SVGAttributeAnimator::applyAnimatedStylePropertyChange):
(WebCore::SVGAttributeAnimator::removeAnimatedStyleProperty):
* svg/properties/SVGAttributeAnimator.h:
* svg/properties/SVGPrimitivePropertyAnimator.h: Added.
(WebCore::SVGPrimitivePropertyAnimator::create):
(WebCore::SVGPrimitivePropertyAnimator::SVGPrimitivePropertyAnimator):
* svg/properties/SVGPrimitivePropertyAnimatorImpl.h: Added.
* svg/properties/SVGPropertyAnimator.h: Added.
(WebCore::SVGPropertyAnimator::SVGPropertyAnimator):
(WebCore::SVGPropertyAnimator::adjustForInheritance const):
(WebCore::SVGPropertyAnimator::computeCSSPropertyValue const):
(WebCore::SVGPropertyAnimator::computeInheritedCSSPropertyValue const):
* svg/properties/SVGPropertyAnimatorFactory.h: Added.
(WebCore::SVGPropertyAnimatorFactory::isKnownAttribute):
(WebCore::SVGPropertyAnimatorFactory::createAnimator):
(WebCore::SVGPropertyAnimatorFactory::animatorWillBeDeleted):
(WebCore::SVGPropertyAnimatorFactory::createColorAnimator):
(WebCore::SVGPropertyAnimatorFactory::attributeAnimatorCreator):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@243259 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Aug 5, 2019
https://bugs.webkit.org/show_bug.cgi?id=200426
<rdar://problem/53912607>

Reviewed by Antti Koivisto.

The intrinsic width for a formatting root box has 2 sets of values now. One set(min/max) is stored in the established formatting context's state
while the other is in the formatting context's state where the box lives.

<div style="position: absolute"><div style="float: left; border: 1px solid green">foobar</div></div>

The float box participates in the formatting context established by the absolutely position box, but it also establishes an inline formatting context.
The min/max width pair in the established context is the width of the "foobar" (same value for min/max). This set is stored in the inline formatting state.
However the float box has horizontal border so the "final" min/max width pair is expanded by this border value and stored in the formatting state where
the box lives (which is different from the one it establishes).

This and the "remove the formatting context type classes from the tree" changes open up interesting optimization opportunities.
Here is a very simple case:
<div style="display: inline-block; width: auto;">
  <div style="float: left">some text</div>
  <div style="float: left">some super long .... text</div>
  <div></div>
</div>
In order to lay out this content properly, we
1. Compute the min/max width of the first float (expensive text measuring)
2. Compute the min/max width of the second float (some more expensive text measuring)
3. Compute the min/max width of the inline-block (that is pretty much the 2 float's min/max)
4. Lay out the 2 floats, the empty div and the inline-block using these min/max width pairs.

Now if the inline-block box's display value is changed to "block" and the positioning is to absolute (style="display: box; position: absolute;")
we currently(on trunk) tear down the render tree, build a new one and run all the steps again from #1 to #4.

In LFC, we start with the following layout tree
<container> -> block formatting context
  <container> -> inline formatting context
    <anonymous inline box>
  <container> -> inline formatting context
    <anonymous inline box>
  <container> -> inline formatting context
and when the style change happens, we don't need to tear down the tree at all. Not only that, but since every formatting contexts stay the same
we can just reuse their states and actually skip all the steps (even the positioning since the absolutely positioned container has static top/bottom/left/right).

Surprisingly the final layout produces the exact same "display boxes" as the original layout.

* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::IntrinsicWidthConstraints::expand):
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::shrinkToFitWidth):
* layout/FormattingState.h:
(WebCore::Layout::FormattingState::setIntrinsicWidthConstraints):
(WebCore::Layout::FormattingState::intrinsicWidthConstraints const):
(WebCore::Layout::FormattingState::setIntrinsicWidthConstraintsForBox):
(WebCore::Layout::FormattingState::clearIntrinsicWidthConstraints):
(WebCore::Layout::FormattingState::intrinsicWidthConstraintsForBox const):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::computedIntrinsicWidthConstraints const):
(WebCore::Layout::BlockFormattingContext::computeIntrinsicWidthConstraints const): Deleted.
* layout/blockformatting/BlockFormattingContext.h:
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::intrinsicWidthConstraints):
(WebCore::Layout::BlockFormattingContext::Geometry::intrinsicWidthConstraintsNeedChildrenWidth): Deleted.
* layout/displaytree/DisplayBox.h:
(WebCore::Display::Box::horizontalMarginBorderAndPadding const):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::nextInPreOrder):
(WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthConstraints const):
(WebCore::Layout::InlineFormattingContext::computeIntrinsicWidthForFormattingRoot const):
(WebCore::Layout::InlineFormattingContext::computeIntrinsicWidthConstraints const): Deleted.
(WebCore::Layout::InlineFormattingContext::computeIntrinsicWidthForFloatBox const): Deleted.
(WebCore::Layout::InlineFormattingContext::computeIntrinsicWidthForInlineBlock const): Deleted.
* layout/inlineformatting/InlineFormattingContext.h:
* layout/tableformatting/TableFormattingContext.cpp:
(WebCore::Layout::TableFormattingContext::computedIntrinsicWidthConstraints const):
* layout/tableformatting/TableFormattingContext.h:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@248262 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Jan 7, 2020
…wind and lldb.

https://bugs.webkit.org/show_bug.cgi?id=205050

Reviewed by Michael Saboff.

Before this patch, the stack trace from inside a probe function is cut off at ctiMasmProbeTrampoline:

    (lldb) bt
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbbadbeef)
        ...
        frame #4: 0x0000000100824607 JavaScriptCore`WTF::Function<void (JSC::Probe::Context&)>::operator(this=0x000000010b88bd00, in=0x00007ffeefbfd400)(JSC::Probe::Context&) const at Function.h:79:35
        frame #5: 0x0000000100823996 JavaScriptCore`JSC::stdFunctionCallback(context=0x00007ffeefbfd400) at MacroAssembler.cpp:53:5
        frame #6: 0x000000010082701e JavaScriptCore`JSC::Probe::executeProbe(state=0x00007ffeefbfd480) at ProbeContext.cpp:51:5
        frame WebKit#7: 0x000000010082614b JavaScriptCore`ctiMasmProbeTrampoline + 299
    (lldb) 

After this patch, we'll now get the full stack trace from inside the probe function:

    (lldb) bt
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbbadbeef)
        ...
        frame #4: 0x0000000100826d17 JavaScriptCore`WTF::Function<void (JSC::Probe::Context&)>::operator(this=0x0000000106b878f8, in=0x00007ffeefbfd400)(JSC::Probe::Context&) const at Function.h:79:35
        frame #5: 0x0000000100826106 JavaScriptCore`JSC::stdFunctionCallback(context=0x00007ffeefbfd400) at MacroAssembler.cpp:53:5
        frame #6: 0x000000010082986e JavaScriptCore`JSC::Probe::executeProbe(state=0x00007ffeefbfd480) at ProbeContext.cpp:51:5
        frame WebKit#7: 0x00000001008289a2 JavaScriptCore`ctiMasmProbeTrampoline + 338
        frame WebKit#8: 0x0000466db28025be
        frame WebKit#9: 0x0000000100754ffc JavaScriptCore`llint_entry at LowLevelInterpreter.asm:994
        frame WebKit#10: 0x0000000100738173 JavaScriptCore`vmEntryToJavaScript at LowLevelInterpreter64.asm:307
        frame WebKit#11: 0x0000000101489307 JavaScriptCore`JSC::JITCode::execute(this=0x0000000106ba1520, vm=0x0000000106d00000, protoCallFrame=0x00007ffeefbfd9b8) at JITCodeInlines.h:38:38
        frame WebKit#12: 0x0000000101488982 JavaScriptCore`JSC::Interpreter::executeProgram(this=0x0000000106bfd1f8, source=0x00007ffeefbff090, (null)=0x000000010d0e0000, thisObj=0x000000010d0e8020) at Interpreter.cpp:847:51
        frame WebKit#13: 0x00000001017d1f9c JavaScriptCore`JSC::evaluate(globalObject=0x000000010d0e0000, source=0x00007ffeefbff090, thisValue=JSValue @ 0x00007ffeefbfef60, returnedException=0x00007ffeefbff0b0) at Completion.cpp:146:38
        frame WebKit#14: 0x000000010005838f jsc`runWithOptions(globalObject=0x000000010d0e0000, options=0x00007ffeefbff620, success=0x00007ffeefbff48b) at jsc.cpp:2670:35
        frame WebKit#15: 0x000000010002a0da jsc`jscmain(this=0x00007ffeefbff5a0, vm=0x0000000106d00000, globalObject=0x000000010d0e0000, success=0x00007ffeefbff48b)::$_6::operator()(JSC::VM&, GlobalObject*, bool&) const at jsc.cpp:3157:13
        frame WebKit#16: 0x0000000100006eff jsc`int runJSC<jscmain(int, char**)::$_6>(options=0x00007ffeefbff620, isWorker=false, func=0x00007ffeefbff5a0)::$_6 const&) at jsc.cpp:3003:9
        frame WebKit#17: 0x0000000100005988 jsc`jscmain(argc=10, argv=0x00007ffeefbff6c8) at jsc.cpp:3150:18
        frame WebKit#18: 0x000000010000575e jsc`main(argc=10, argv=0x00007ffeefbff6c8) at jsc.cpp:2498:15
        frame WebKit#19: 0x00007fff6cfc4da9 libdyld.dylib`start + 1
        frame WebKit#20: 0x00007fff6cfc4da9 libdyld.dylib`start + 1
    (lldb)

The difference is that the x86_64 ctiMasmProbeTrampoline now uses the standard
function prologue, and keeps %rbp pointing to trampoline function's semblance of
a frame that libunwind can understand while it calls the probe function.

* assembler/MacroAssemblerX86Common.cpp:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@253320 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Feb 11, 2020
…rchability.

https://bugs.webkit.org/show_bug.cgi?id=207024

Reviewed by Saam Barati.

This patch applies the following changes:

1. Prefix Air and B2 dumps with a tierName prefix.
   The tierName prefix strings are as follows:

       "FTL ", "DFG ", "b3  ", "Air ", "asm "

   The choice to use a lowercase "b3" and "asm" with upper case "Air" is
   deliberate because I found this combination to be easier to read and scan as
   prefixes of the dump lines.  See dump samples below.

2. Make DFG node IDs consistently expressed as D@<node index> e.g. D@104.
   The definition of the node will be the id followed by a colon e.g. D@104:
   This makes it easy to search references to this node anywhere in the dump.

   Make B3 nodes expressed as b@<node index> e.g. b@542.
   This also makes it searchable since there's now no ambiguity between b@542 and
   D@542.

   The choice to use a lowercase "b" and an uppercase "D" is intentional because
   "b@542" and "d@542" looks too similar, and I prefer to not use too much
   uppercase.  Plus this makes the node consistent in capitalization with the
   tierName prefixes above of "b3  " and "DFG " respectively.

Here's a sample of what the dumps now look like:

DFG graph dump:
<code>
    ...
         6 55:   <-- foo#DFndCW:<0x62d0000b8140, bc#65, Call, known callee: Object: 0x62d000035920 with butterfly 0x0 (Structure %AN:Function), StructureID: 12711, numArgs+this = 1, numFixup = 0, stackOffset = -16 (loc0 maps to loc16)>
      3  6 55:   D@79:< 3:->    ArithAdd(Int32:Kill:D@95, Int32:D@42, Int32|PureNum|UseAsOther, Int32, CheckOverflow, Exits, bc#71, ExitValid)
      4  6 55:    D@3:<!0:->    KillStack(MustGen, loc7, W:Stack(loc7), ClobbersExit, bc#71, ExitInvalid)
      5  6 55:   D@85:<!0:->    MovHint(Check:Untyped:D@79, MustGen, loc7, W:SideState, ClobbersExit, bc#71, ExitInvalid)
      6  6 55:  D@102:< 1:->    CompareLess(Int32:D@79, Int32:D@89, Boolean|UseAsOther, Bool, Exits, bc#74, ExitValid)
      7  6 55:  D@104:<!0:->    Branch(KnownBoolean:Kill:D@102, MustGen, T:#1/w:10.000000, F:WebKit#7/w:1.000000, W:SideState, bc#74, ExitInvalid)
    ...
</code>

B3 graph dump:
<code>
    ...
    b3  BB#14: ; frequency = 10.000000
    b3    Predecessors: WebKit#13
    b3      Int32 b@531 = CheckAdd(b@10:WarmAny, $1(b@1):WarmAny, b@64:ColdAny, b@10:ColdAny, generator = 0x606000022e80, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, D@79)
    b3      Int32 b@539 = LessThan(b@531, $100(b@578), D@102)
    b3      Void b@542 = Branch(b@539, Terminal, D@104)
    b3    Successors: Then:#2, Else:WebKit#15
    ...
</code>

Air graph dump:
<code>
    ...
    Air BB#5: ; frequency = 10.000000
    Air   Predecessors: #4
    Air     Move -96(%rbp), %rax, b@531
    Air     Patch &BranchAdd32(3,ForceLateUseUnlessRecoverable)3, Overflow, $1, %rax, -104(%rbp), -96(%rbp), b@531
    Air     Branch32 LessThan, %rax, $100, b@542
    Air   Successors: #1, #6
    ...
</code>

FTL disassembly dump:
<code>
    ...
    Air BB#5: ; frequency = 10.000000
    Air   Predecessors: #4
    DFG       D@42:< 2:->   JSConstant(JS|PureInt, Int32, Int32: 1, bc#0, ExitInvalid)
    DFG       D@79:< 3:->   ArithAdd(Int32:Kill:D@95, Int32:D@42, Int32|PureNum|UseAsOther, Int32, CheckOverflow, Exits, bc#71, ExitValid)
    b3            Int32 b@1 = Const32(1)
    b3            Int32 b@531 = CheckAdd(b@10:WarmAny, $1(b@1):WarmAny, b@64:ColdAny, b@10:ColdAny, generator = 0x606000022e80, earlyClobbered = [], lateClobbered = [], usedRegisters = [%rax, %rbx, %rbp, %r12], ExitsSideways|Reads:Top, D@79)
    Air               Move -96(%rbp), %rax, b@531
    asm                   0x4576b9c04712: mov -0x60(%rbp), %rax
    Air               Patch &BranchAdd32(3,ForceLateUseUnlessRecoverable)3, Overflow, $1, %rax, -104(%rbp), -96(%rbp), b@531
    asm                   0x4576b9c04716: inc %eax
    asm                   0x4576b9c04718: jo 0x4576b9c04861
    DFG       D@89:< 1:->   JSConstant(JS|PureNum|UseAsOther, NonBoolInt32, Int32: 100, bc#0, ExitInvalid)
    DFG      D@102:< 1:->   CompareLess(Int32:D@79, Int32:D@89, Boolean|UseAsOther, Bool, Exits, bc#74, ExitValid)
    DFG      D@104:<!0:->   Branch(KnownBoolean:Kill:D@102, MustGen, T:#1/w:10.000000, F:WebKit#7/w:1.000000, W:SideState, bc#74, ExitInvalid)
    b3            Int32 b@578 = Const32(100, D@89)
    b3            Int32 b@539 = LessThan(b@531, $100(b@578), D@102)
    b3            Void b@542 = Branch(b@539, Terminal, D@104)
    Air               Branch32 LessThan, %rax, $100, b@542
    asm                   0x4576b9c0471e: cmp $0x64, %eax
    asm                   0x4576b9c04721: jl 0x4576b9c0462f
    Air   Successors: #1, #6
    ...
</code>

* b3/B3BasicBlock.cpp:
(JSC::B3::BasicBlock::deepDump const):
* b3/B3Common.cpp:
* b3/B3Common.h:
* b3/B3Generate.cpp:
(JSC::B3::generateToAir):
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::dump const):
* b3/B3Value.cpp:
* b3/air/AirBasicBlock.cpp:
(JSC::B3::Air::BasicBlock::deepDump const):
(JSC::B3::Air::BasicBlock::dumpHeader const):
(JSC::B3::Air::BasicBlock::dumpFooter const):
* b3/air/AirCode.cpp:
(JSC::B3::Air::Code::dump const):
* b3/air/AirCode.h:
* b3/air/AirDisassembler.cpp:
(JSC::B3::Air::Disassembler::dump):
* b3/air/AirGenerate.cpp:
(JSC::B3::Air::prepareForGeneration):
* dfg/DFGCommon.cpp:
* dfg/DFGCommon.h:
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::dump):
(JSC::DFG::Graph::dumpBlockHeader):
* dfg/DFGNode.cpp:
(WTF::printInternal):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLCompile.h:
* ftl/FTLState.cpp:
(JSC::FTL::State::State):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@255482 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Apr 19, 2020
Unreviewed.

* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::platformInitializeWebProcess):
- Add #if ENABLE(VIDEO_PRESENTATION_MODE)/#endif to protect
  function defined in WebCore/PictureInPictureSupport.h.
- See previous build fixes in r260307, r260308 and r260313.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@260328 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Jul 6, 2020
https://bugs.webkit.org/show_bug.cgi?id=213436

Reviewed by Antti Koivisto.

Source/WebCore:

1. The table generates a principal block container box called the table wrapper box that contains the table box itself and any caption boxes.
2. The table wrapper box establishes a block formatting context, and the table box establishes a table formatting context.
3. The computed values of properties 'position', 'float', 'margin-*', 'top', 'right', 'bottom', and 'left' on
   the table element are used on the table wrapper box and not the table box; all other values of non-inheritable
   properties are used on the table box and not the table wrapper box.
4. In a block formatting context, each box's left outer edge touches the left edge of the containing block.
   This is true even in the presence of floats, unless the box establishes a new block formatting context (in which case the
   box itself may become narrower due to the floats)

Now consider the following case:
<div style="display: block; width: 500px;">
    <div style="float: left; width: 100px;"></div>
    <div style="display: table; width: 10%;"></div>
</div>
1. We create a table wrapper box to wrap the "display: table" block level box (#1).
2. The table wrapper box's width property is set to auto (#3).
3. Since it establishes a new block formatting context, the available horizontal space gets shrunk by the float (#4)
4. The table wrapper box's used width computes to 500px - 100px -> 400px;

Now we are inside the BFC established by the table wrapper box and try to resolve the table's width -> %10.
According to the normal BFC rules, it should compute to 10% of the containing block's logical width: 400px -> 40px.
However in practice it computes to 50px (10% of 500px).

Similar setup with non-table content would resolve the inner block level box's width to 40px;
<div style="display: block; width: 500px">
    <div style="float: left; width: 100px;"></div>
    <div style="display: block; overflow: hidden;">
        <div style="display: block; width: 10%"></div>
    </div>
</div>
This needs clarification.

Test: fast/layoutformattingcontext/float-avoider-available-horizontal-space3.html

* layout/FormattingContext.h:
(WebCore::Layout::FormattingContext::isTableWrapperBlockFormattingContext const):
* layout/blockformatting/BlockFormattingContext.cpp:
(WebCore::Layout::BlockFormattingContext::layoutInFlowContent):
* layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.cpp:
(WebCore::Layout::TableWrapperBlockFormattingContext::computeWidthAndMarginForTableBox):
* layout/blockformatting/tablewrapper/TableWrapperBlockFormattingContext.h:

LayoutTests:

* fast/layoutformattingcontext/float-avoider-available-horizontal-space3-expected.html: Added.
* fast/layoutformattingcontext/float-avoider-available-horizontal-space3.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263327 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Jul 6, 2020
https://bugs.webkit.org/show_bug.cgi?id=213669

Reviewed by Yusuke Suzuki.

This makes the bytecode control flow graphs much easier to understand, and
puts bytecode dumping in more in line with how we dump other IRs.

The new dumps look like this:
```
foo#Ahf63N:[0x1035bc120->0x1035e5100, NoneFunctionCall, 36]: 13 instructions (0 16-bit instructions, 0 32-bit instructions, 1 instructions with metadata); 156 bytes (120 metadata bytes); 2 parameter(s); 8 callee register(s); 6 variable(s); scope at loc4

bb#1
[   0] enter
[   1] get_scope          loc4
[   3] mov                loc5, loc4
[   6] check_traps
[   7] mov                loc6, <JSValue()>(const0)
[  10] mov                loc6, Undefined(const1)
[  13] mod                loc7, arg1, Int32: 2(const2)
[  17] jfalse             loc7, 8(->25)
Successors: [ #3 #2 ]

bb#2
[  20] mov                loc6, Int32: 42(const3)
[  23] jmp                5(->28)
Successors: [ #4 ]

bb#3
[  25] mov                loc6, Int32: 77(const4)
Successors: [ #4 ]

bb#4
[  28] add                loc7, arg1, loc6, OperandTypes(126, 126)
[  34] ret                loc7
Successors: [ ]
```

* bytecode/BytecodeDumper.cpp:
(JSC::dumpHeader):
(JSC::dumpFooter):
(JSC::CodeBlockBytecodeDumper<Block>::dumpBlock):
(JSC::CodeBlockBytecodeDumper<Block>::dumpGraph):
* bytecode/BytecodeDumper.h:
* bytecode/BytecodeGraph.h:
(JSC::BytecodeGraph::dump):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@263618 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Aug 31, 2020
https://bugs.webkit.org/show_bug.cgi?id=215672

Reviewed by Saam Barati.

Currently we only validate OSR exit availability if a node would
say `mayExit(graph, node) != DoesNotExit` and the node is marked
as exitOK. However, it would be perfectly valid to insert a node
that exits anywhere we have a node marked exitOK. So with this
patch we now validate all places where it would ever be possible
to OSR exit.

Relaxing our criteria revealed a number of bugs however. Which I
will describe below in, IMO, increasing complexity/subtly.

First, we currently don't mark arity fixup during inlining as not
exitOK. However, since our arity code says its code origin is
OpEnter, we assume arity fixup has already happened.

Second, OpGetScope, should not mark its first argument as used
since it's not actually used. This is problematic because we could
have a loop where OpGetScope is the first bytecode, namely when
doing tail recursive inlining. If we were in that position, there
could be a local that was used at a merge point at the loop
backedge that had two MovHint defs from both predecessors. In DFG
IR this would look like:

BB#1:
@1: MovHint(Undefined, loc1)
...
Jump(#2)

BB#2:
... // loc1 is live here in bytecode
@2: MovHint(@scopeObject, loc1)
@3: SetLocal(@scopeObject, loc1)
Branch(#3, #4) // #4 is the successor of the tail call loop

BB#3:
@4 MovHint(Undefined, loc1)
...
Jump(#2)

When we do CPS conversion the MovHints at @1 and @4 will be seen
as different variables (there's no GetLocal). Then, after, during
SSA conversion we won't insert a phi connecting them, making the
argument to OpGetScope, in this case loc1, unrecoverable there are
conflicting nodes and the value isn't saved on the stack.

There were also issues with MovHintRemoval Phase but rather than
fix them we opted to just remove the phase as it didn't show any
performance impact. I'll describe the issues I found below for
completeness, however.

Third, MovHint removal phase had a bug where it would not mark
sections where a zombied MovHint has yet to be killed as not
exitOK. So in theory another phase could come along and insert an
exiting node there.

Fourth, MovHint removal phase had a second bug where a MovHint
that was not killed in the current block would be zombied, which
is wrong for SSA. It's wrong because the MovHinted value could
still be live for OSR exit in a successor block.

Lastly, this patch adds some new verbose options as well as the ability to
dump a DFG::BasicBlock without dereferencing it.

* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
* dfg/DFGBasicBlock.cpp:
(WTF::printInternal):
* dfg/DFGBasicBlock.h:
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::inlineCall):
* dfg/DFGCPSRethreadingPhase.cpp:
(JSC::DFG::CPSRethreadingPhase::propagatePhis):
* dfg/DFGEpoch.h:
(JSC::DFG::Epoch::operator bool const):
* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
* dfg/DFGSSACalculator.cpp:
(JSC::DFG::SSACalculator::dump const):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@266242 268f45cc-cd09-0410-ab3c-d52691b4dbfc
caiolima pushed a commit that referenced this pull request Sep 24, 2020
https://bugs.webkit.org/show_bug.cgi?id=202582

Reviewed by Yusuke Suzuki and Keith Miller.

JSTests:

Provided microbenchmarks test receivers that are half-sorted: 50% of their
items and item pairs (to accomodate merge sort) are at the right place.

Arrays of multiple sizes (8/24/64 items) are tested with both userland
and default comparator (to cover bucket sort).

* ChakraCore/test/Array/array_sort.baseline-jsc: Fix typo in error message.
* microbenchmarks/array-prototype-sort-large-array-comparator.js: Added.
* microbenchmarks/array-prototype-sort-large-array.js: Added.
* microbenchmarks/array-prototype-sort-medium-array-comparator.js: Added.
* microbenchmarks/array-prototype-sort-medium-array.js: Added.
* microbenchmarks/array-prototype-sort-small-array-comparator.js: Added.
* microbenchmarks/array-prototype-sort-small-array.js: Added.
* mozilla/js1_5/Array/regress-157652.js: Skip sorting sparse array of UINT_MAX size.
* stress/regress-188577.js: Replace sort() with unshift() and refactor.

Source/JavaScriptCore:

This patch implements the spec change [1] that reduces amount of cases resulting
in an implementation-defined sort order, aligning JSC with V8 and SpiderMonkey.

To achieve this, we collect all existing non-undefined receiver elements to a
temporary array, sort it, and write back sorted items, followed by `undefined`
values and holes.

This change is proven to be web-compatible (shipping since Chrome 76) and neutral
on peak memory consumption in the wild.

Although we can unobservably detect sparse receivers, we can't avoid creating a
temporary array for common case since userland comparators may throw; string
sorting won't measurably benefit from this, only increasing code complexity.

This change uses @putByValDirect unless the spec requires [[Set]], avoids using
closure variables, and adds a few drive-by optimizations, resulting in ~22%
faster string sorting and 13% speed-up for userland comparators.
Dromaeo/jslib is neutral.

[1]: tc39/ecma262#1585

* builtins/ArrayPrototype.js:
(sort.stringComparator):
Optimization #1: replace char-by-char comparison loop with > operator, aligning
JSC with V8 and SpiderMonkey. This semantically equivalent change alone is a ~15%
progression for string sort.

(sort.compact):
(sort.commit):
Optimization #2: copy large non-numeric arrays in a loop rather than @appendMemcpy.
Using the latter unconditionally regresses provided microbenchmarks.

(sort.merge):
Optimization #3: replace `typeof` check and negation with strict equality.

(sort.mergeSort):
Optimization #4: always return sorted array instead of copying, even if it's the buffer.
Tweak: create the buffer with correct length.

(sort.bucketSort):
Optimization #5: avoid emitting 2 extra get_by_val ops by saving bucket lookup to a variable.
Tweak: create new bucket via array literal.

(sort): Fix typo in error message.
(sort.compactSparse): Deleted.
(sort.compactSlow): Deleted.
(sort.comparatorSort): Deleted.
(sort.stringSort): Deleted.
* runtime/ObjectConstructor.cpp:
(JSC::ObjectConstructor::finishCreation):
Remove @object.@getPrototypeOf as it's now unused and we have @getPrototypeOf intrinsic anyway.

LayoutTests:

While adding new LayoutTests for JS-only features is undesirable, it's a
quick-and-dirty way to import the tests [1] and fix the call count/order
of observable operations via debug() and text expectations.

The tests are imported into LayoutTests/js/dom instead of LayoutTests/js for
run-javascriptcore-tests to ignore them as they require array-sort-harness.js.

These files will be removed shortly in favor of thorough test262 coverage,
which is required for the proposal [2] to be merged.

[1]: https://gist.github.com/szuend/05ae15b4e1329b264ab4c9a1cda09242
[2]: tc39/ecma262#1585

* TestExpectations: Mark a test as slow.
* js/dom/array-sort-*-expected.txt: Added.
* js/dom/array-sort-*.html: Added.
* js/dom/script-tests/array-sort-*.js: Added.
* js/resources/array-sort-harness.js: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@267514 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant