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

Fix build with gcc 5.4, x86_64. #1

Merged
merged 1 commit into from
Jul 7, 2016
Merged

Conversation

korli
Copy link

@korli korli commented Jul 7, 2016

  • std::isnan isn't found in math.h, replace with cmath.

* std::isnan isn't found in math.h, replace with cmath.
@kallisti5
Copy link

Looks good. I ran into this one a few days ago and didn't have the bandwidth to fix.

@kallisti5 kallisti5 merged commit 4c8e865 into haiku:rebased Jul 7, 2016
pulkomandy pushed a commit that referenced this pull request Aug 1, 2017
https://bugs.webkit.org/show_bug.cgi?id=153694

Reviewed by Filip Pizlo.

Let's say we have:
    Move(FP, Tmp1)
    Add64(#1, Tmp1)

If we were to coalesce the Move, we would modify the frame pointer.
Well, that's exactly what was happening with IRC.

Since the epilogue is not know to Air before IRC, the liveness analysis
never discovers that FP is live when Tmp1 is UseDef by Add64. Adding
FP would a be a problem anyway for a bunch of reasons.

I tried two ways to prevent IRC to override IRC:
1) Add an interference edge with FP for all non-duplication Defs.
2) Let coalesce() know about FP and constraint any coalescing with a re-Def.

The two are within margin of error for performance. The second one was considerably
more complicated. This patch implements the first one.

Some extra note:
-It is very important to not increment the degree of a Tmp when making it interfere
 with FP. FP is not a valid color, it is not counted in the "K" colors considered
 for coloring. Increasing the degree with the edge to FP would make every stage
 pessimistic since there is an extra degree that can never be removed.
-I put "interferenceEdges" and "adjacencyList" in an inconsistent state.
 This is intentional, "interferenceEdges" is used to test the existence of an edge,
 "adjacencyList" is used to go over all the edges. In this case, we don't want
 the edge with FP to be considered when pruning the graph.

* b3/air/AirIteratedRegisterCoalescing.cpp:
One branch could be transformed into an assertion: TmpLiveness is type specific now.
* b3/testb3.cpp:
(JSC::B3::testOverrideFramePointer):
(JSC::B3::run):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@195981 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Aug 1, 2017
https://bugs.webkit.org/show_bug.cgi?id=154110

Reviewed by Darin Adler.

No new tests (Currently untestable).

The lifetime of IDBObjectStore and IDBIndex are closely intertwined, but we have to break the ref cycle.

This patch does a few semi-gnarly things:
1 - Makes both IDBIndex and IDBObjectStore have a custom marking function so they can add each other as
    opaque roots.
2 - Adds a lock to protect IDBObjectStore's collection of referenced indexes to support #1, as GC marking
    can happen on any thread.
3 - Makes IDBIndex not be traditionally RefCounted; Instead, IDBIndex::ref()/deref() simply ref()/deref()
    the owning IDBObjectStore.
4 - ...Except when somebody deletes an IDBIndex from its IDBObjectStore. Once that happens, the object
    store no longer has a reference back to the index, but the index still needs a reference back to the
    object store. To support this, the IDBIndex becomes "traditionally RefCounted" while holding a ref to
    its IDBObjectStore.

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* Modules/indexeddb/IDBIndex.h:
(WebCore::IDBIndex::isModern):
* Modules/indexeddb/IDBIndex.idl:

* Modules/indexeddb/IDBObjectStore.h:
(WebCore::IDBObjectStore::isModern):
* Modules/indexeddb/IDBObjectStore.idl:

* Modules/indexeddb/client/IDBIndexImpl.cpp:
(WebCore::IDBClient::IDBIndex::objectStore):
(WebCore::IDBClient::IDBIndex::openCursor):
(WebCore::IDBClient::IDBIndex::doCount):
(WebCore::IDBClient::IDBIndex::openKeyCursor):
(WebCore::IDBClient::IDBIndex::doGet):
(WebCore::IDBClient::IDBIndex::doGetKey):
(WebCore::IDBClient::IDBIndex::markAsDeleted):
(WebCore::IDBClient::IDBIndex::ref):
(WebCore::IDBClient::IDBIndex::deref):
(WebCore::IDBClient::IDBIndex::create): Deleted.
* Modules/indexeddb/client/IDBIndexImpl.h:
(WebCore::IDBClient::IDBIndex::modernObjectStore):

* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::createIndex):
(WebCore::IDBClient::IDBObjectStore::index):
(WebCore::IDBClient::IDBObjectStore::deleteIndex):
(WebCore::IDBClient::IDBObjectStore::visitReferencedIndexes):
* Modules/indexeddb/client/IDBObjectStoreImpl.h:

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::createIndex):
* Modules/indexeddb/client/IDBTransactionImpl.h:

* Modules/indexeddb/legacy/LegacyIndex.cpp:
(WebCore::LegacyIndex::ref):
(WebCore::LegacyIndex::deref):
* Modules/indexeddb/legacy/LegacyIndex.h:

* bindings/js/JSIDBIndexCustom.cpp: Added.
(WebCore::JSIDBIndex::visitAdditionalChildren):

* bindings/js/JSIDBObjectStoreCustom.cpp:
(WebCore::JSIDBObjectStore::visitAdditionalChildren):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@196482 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Oct 26, 2017
…rges

https://bugs.webkit.org/show_bug.cgi?id=155828
rdar://problem/25155460

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-03-24
Reviewed by Filip Pizlo.

In certain conditions, the integer range optimization phase continuously
changes the representation of the same truth, preventing it from
converging to a stable state.

The bug starts by having the same ground truth incomming into a block
in different valid forms. For example, you can have x < 42 coming as:
    1) x < 42
    2) x < 41 + 1
    3) x < 43 - 1

Having those 3 alone coming from predecessors would be okay, we would
just accumulate them. The problem is when you have a combination
of rule that filter out the previously obtained truth, then add a new
form of the same truth.

Let's use the test case as an example. We have two incoming blocks:
    Block #1:
      -i < 42
      -i != 41
    Block #2:
      -i < 41
      -i == 42 - 42 (i == 0 refining the rule above).

Let say that our conditions at head are now [i < 41, i < 42 - 1].

If we merge block #2:
      -i < 42 and i < 41      -> i < 42
      -i < 42 and i < 42 - 1  -> i < 42
      -i != 41 and i < 41     -> i < 41
      -i != 41 and i < 42 - 1 -> nothing

The new head is: [i < 41, i < 42]

If we merge block #1:
      -i < 41 and i < 41       -> i < 41
      -i < 41 and i < 42       -> i < 42
      -i == 42 - 42 and i < 41 -> (i < 41 and i < 42 - 1)
      -i == 42 - 42 and i < 42 -> i < 42

After filter, we are back to [i < 41, i < 42 - 1].

There are several variations of this idea where the same truth
rotate different forms with each merge().

One possible solution is to make filter() more aggressive
to avoid the better form occuring at merge(). I'll probably
do that at some point but that seems fragile since the same
problem could reappear if merge() is later improved.

For this patch, I went with a more generic solution after
merge(): if the generated form is equivalent to one that
previously existed at head, pick the existing form.

In the previous example, what happens is we only have
either [i < 41] or [i < 42 - 1] but never both simultaneously.

* dfg/DFGIntegerRangeOptimizationPhase.cpp:
* tests/stress/integer-range-optimization-constant-representation-1.js: Added.
* tests/stress/integer-range-optimization-constant-representation-2.js: Added.
Two variation. One timeout in release because of the additional flags.
The other is gets more type of run but only assert in debug.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@198621 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Dec 27, 2017
…lling

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

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-04-11
Reviewed by Filip Pizlo.

Spilling had issues when replacing arguments in place.

The problems are:
1) If we have a 32bit stackslot, a x86 instruction could still try to load 64bits from it.
2) If we have a 64bit stackslot, Move32 would only set half the bits.
3) We were reducing Move to Move32 even if the top bits are read from the stack slot.

The case 1 appear with something like this:
    Move32 %tmp0, %tmp1
    Op64 %tmp1, %tmp2, %tmp3
When we spill %tmp1, the stack slot is 32bit, Move32 sets 32bits
but Op64 supports addressing for %tmp1. When we substitute %tmp1 in Op64,
we are creating a 64bit read for a 32bit stack slot.

The case 2 is an other common one. If we have:
    BB#1
        Move32 %tmp0, %tmp1
        Jump #3
    BB#2
        Op64 %tmp0, %tmp1
        Jump #3
    BB#3
        Use64 %tmp1

We have a stack slot of 64bits. When spilling %tmp1 in #1, we are
effectively doing a 32bit store on the stack slot, leaving the top bits undefined.

Case 3 is pretty much the same as 2 but we create the Move32 ourself
because the source is a 32bit with ZDef.

Case (1) is solved by requiring that the stack slot is at least as large as the largest
use/def of that tmp.

Case (2) and (3) are solved by not replacing a Tmp by an Address if the Def
is smaller than the stack slot.

* b3/air/AirIteratedRegisterCoalescing.cpp:
* b3/testb3.cpp:
(JSC::B3::testSpillDefSmallerThanUse):
(JSC::B3::testSpillUseLargerThanDef):
(JSC::B3::run):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@199337 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Dec 27, 2017
https://bugs.webkit.org/show_bug.cgi?id=156603
<rdar://problem/25736205>

Patch by Benjamin Poulain <bpoulain@apple.com> on 2016-04-17
Reviewed by Saam Barati and Filip Pizlo.

This patch extends B3's ReduceDoubleToFloat phase to work accross
Upsilon-Phis. This is important to optimize loops and some crazy cases.

In its simplest form, we can have conversion propagated from something
like this:
    Double @1 = Phi()
    Float @2 = DoubleToFloat(@1)

When that happens, we just need to propagate that the result only
need float precision accross all values coming to this Phi.


There are more complicated cases when the value produced is effectively Float
but the user of the value does not do DoubleToFloat.

Typically, we have something like:
    #1
        @1 = ConstDouble(1)
        @2 = Upsilon(@1, ^5)
    #2
        @3 = FloatToDouble(@x)
        @4 = Upsilon(@3, ^5)
    #3
        @5 = Phi()
        @6 = Add(@5, @somethingFloat)
        @7 = DoubleToFloat(@6)

Here with a Phi-Upsilon that is a Double but can be represented
as Float without loss of precision.

It is valuable to convert such Phis to float if and only if the value
is used as float. Otherwise, you may be just adding useless conversions
(for example, two double constants that flow into a double Add should not
turn into two float constant flowing into a FloatToDouble then Add).


ReduceDoubleToFloat do two analysis passes to gather the necessary
meta information. Then we have a simplify() phase to actually reduce
operation. Finally, the cleanup() pass put the graph into a valid
state again.

The two analysis passes work by disproving that something is float.
-findCandidates() accumulates anything used as Double.
-findPhisContainingFloat() accumulates phis that would lose precision
 by converting the input to float.

With this change, Unity3D improves by ~1.5%, box2d-f32 improves
by ~2.8% (on Haswell).

* b3/B3ReduceDoubleToFloat.cpp:
(JSC::B3::reduceDoubleToFloat):
* b3/testb3.cpp:
(JSC::B3::testCompareTwoFloatToDouble):
(JSC::B3::testCompareOneFloatToDouble):
(JSC::B3::testCompareFloatToDoubleThroughPhi):
(JSC::B3::testDoubleToFloatThroughPhi):
(JSC::B3::testDoubleProducerPhiToFloatConversion):
(JSC::B3::testDoubleProducerPhiToFloatConversionWithDoubleConsumer):
(JSC::B3::testDoubleProducerPhiWithNonFloatConst):
(JSC::B3::testStoreDoubleConstantAsFloat):
(JSC::B3::run):
* tests/stress/double-compare-to-float.js: Added.
(canSimplifyToFloat):
(canSimplifyToFloatWithConstant):
(cannotSimplifyA):
(cannotSimplifyB):
* tests/stress/double-to-float.js: Added.
(upsilonReferencingItsPhi):
(upsilonReferencingItsPhiAllFloat):
(upsilonReferencingItsPhiWithoutConversion):
(conversionPropagages):
(chainedUpsilonBothConvert):
(chainedUpsilonFirstConvert):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@199648 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Feb 10, 2018
https://bugs.webkit.org/show_bug.cgi?id=163760

Reviewed by Yusuke Suzuki.

JSTests:

* stress/async-await-basic.js: Added.
(shouldBe):
(shouldBeAsync):
(shouldThrow):
(shouldThrowAsync):
(shouldThrowSyntaxError):
(let.AsyncFunction.async):
(async.asyncFunctionForProto):
(Object.getPrototypeOf.async):
(Object.getPrototypeOf.async.method):
(async):
(async.method):
(async.asyncNonConstructorDecl):
(shouldThrow.new.async):
(shouldThrow.new.async.nonConstructor):
(async.asyncDecl):
(async.f):
(MyError):
(async.asyncDeclThrower):
(shouldThrowAsync.async):
(resolveLater):
(rejectLater):
(async.resumeAfterNormal):
(O.async.resumeAfterNormal):
(resumeAfterNormalArrow.async):
(async.resumeAfterThrow):
(O.async.resumeAfterThrow):
(resumeAfterThrowArrow.async):
(catch):
* stress/async-await-module-reserved-word.js: Added.
(shouldThrow):
(SyntaxError.Canstring_appeared_hereawait.checkModuleSyntaxError.String.raw.await):
(checkModuleSyntaxError.String.raw.await):
(checkModuleSyntaxError.String.raw.async.await):
(SyntaxError.Cannot.declare.named):
* stress/async-await-mozilla.js: Added.
(shouldBe):
(shouldBeAsync):
(shouldThrow):
(shouldThrowAsync):
(assert):
(shouldThrowSyntaxError):
(mozSemantics.async.empty):
(mozSemantics.async.simpleReturn):
(mozSemantics.async.simpleAwait):
(mozSemantics.async.simpleAwaitAsync):
(mozSemantics.async.returnOtherAsync):
(mozSemantics.async.simpleThrower):
(mozSemantics.async.delegatedThrower):
(mozSemantics.async.tryCatch):
(mozSemantics.async.tryCatchThrow):
(mozSemantics.async.wellFinally):
(mozSemantics.async.finallyMayFail):
(mozSemantics.async.embedded.async.inner):
(mozSemantics.async.embedded):
(mozSemantics.async.fib):
(mozSemantics.async.isOdd.async.isEven):
(mozSemantics.async.isOdd):
(mozSemantics.hardcoreFib.async.fib2):
(mozSemantics.namedAsyncExpr.async.simple):
(mozSemantics.async.executionOrder.async.first):
(mozSemantics.async.executionOrder.async.second):
(mozSemantics.async.executionOrder.async.third):
(mozSemantics.async.executionOrder):
(mozSemantics.async.miscellaneous):
(mozSemantics.thrower):
(mozSemantics.async.defaultArgs):
(mozSemantics.shouldThrow):
(mozSemantics):
(mozMethods.X):
(mozMethods.X.prototype.async.getValue):
(mozMethods.X.prototype.setValue):
(mozMethods.X.prototype.async.increment):
(mozMethods.X.prototype.async.getBaseClassName):
(mozMethods.X.async.getStaticValue):
(mozMethods.Y.prototype.async.getBaseClassName):
(mozMethods.Y):
(mozFunctionNameInferrence.async.test):
(mozSyntaxErrors):
* stress/async-await-reserved-word.js: Added.
(assert):
(shouldThrowSyntaxError):
(AsyncFunction.async):
* stress/async_arrow_functions_lexical_arguments_binding.js: Added.
(shouldBe):
(shouldBeAsync):
(shouldThrowAsync):
(noArgumentsArrow2.async):
* stress/async_arrow_functions_lexical_new.target_binding.js: Added.
(shouldBe):
(shouldBeAsync):
(shouldThrowAsync):
(C1):
(C2):
(shouldThrowAsync.async):
* stress/async_arrow_functions_lexical_super_binding.js: Added.
(shouldBe):
(shouldBeAsync):
(BaseClass.prototype.baseClassValue):
(BaseClass.prototype.get property):
(BaseClass):
(ChildClass.prototype.asyncSuperProp):
(ChildClass.prototype.asyncSuperProp2):
(ChildClass):
(ChildClass2):
* stress/async_arrow_functions_lexical_this_binding.js: Added.
(shouldBe):
(shouldBeAsync):
(d.y):

Source/JavaScriptCore:

Async functions generate bytecode equivalent to the following, which is
highly dependent on the Generator implementation:

```
// Before translation:
async function asyncfn() {}

// After translation:
function asyncfn() {
    let generator = {
        @GeneratorNext: function(@Generator, @generatorState, @generatorValue, @generatorResumeMode, @generatorFrameState) {
            // Body of async function
        },
        @generatorState: 0,
        @generatorThis: this,
        @generatorFrameState: <frame state>,
    };
    return @asyncFunctionResume(generator, undefined, GeneratorResumeMode::NormalMode);
}
```

Await Expressions are equivalent to non-delegating Yield expressions, and emit identical bytecode.

There are some caveats to be addressed later:

1) the `op_to_this` is always performed, whether it's used or not, like normal generators. (https://bugs.webkit.org/show_bug.cgi?id=151586)

2) for async arrow functions, the home object is always stored on the "body" function, regardless of whether it's needed or
not, for the same reason as #1 (and should also be fixed as part of https://bugs.webkit.org/show_bug.cgi?id=151586)

* CMakeLists.txt:
* DerivedSources.make:
* JavaScriptCore.xcodeproj/project.pbxproj:
* builtins/AsyncFunctionPrototype.js: Added.
(asyncFunctionResume):
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::isArrowFunction):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitNewFunctionExpressionCommon):
(JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
(JSC::BytecodeGenerator::emitNewFunction):
* bytecompiler/NodesCodegen.cpp:
(JSC::FunctionNode::emitBytecode):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOpcodes.cpp:
(JSC::JIT::emitNewFuncCommon):
(JSC::JIT::emit_op_new_async_func):
(JSC::JIT::emitNewFuncExprCommon):
(JSC::JIT::emit_op_new_async_func_exp):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
(JSC::Parser<LexerType>::parseFunctionInfo):
* parser/Parser.h:
(JSC::Scope::setSourceParseMode):
* parser/ParserModes.h:
(JSC::isGeneratorOrAsyncFunctionBodyParseMode):
(JSC::isGeneratorOrAsyncFunctionWrapperParseMode):
* runtime/AsyncFunctionConstructor.cpp: Added.
(JSC::AsyncFunctionConstructor::AsyncFunctionConstructor):
(JSC::AsyncFunctionConstructor::finishCreation):
(JSC::callAsyncFunctionConstructor):
(JSC::constructAsyncFunctionConstructor):
(JSC::AsyncFunctionConstructor::getCallData):
(JSC::AsyncFunctionConstructor::getConstructData):
* runtime/AsyncFunctionConstructor.h: Added.
(JSC::AsyncFunctionConstructor::create):
(JSC::AsyncFunctionConstructor::createStructure):
* runtime/AsyncFunctionPrototype.cpp: Added.
(JSC::AsyncFunctionPrototype::AsyncFunctionPrototype):
(JSC::AsyncFunctionPrototype::finishCreation):
* runtime/AsyncFunctionPrototype.h: Added.
(JSC::AsyncFunctionPrototype::create):
(JSC::AsyncFunctionPrototype::createStructure):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunctionSkippingEvalEnabledCheck):
* runtime/FunctionConstructor.h:
* runtime/JSAsyncFunction.cpp: Added.
(JSC::JSAsyncFunction::JSAsyncFunction):
(JSC::JSAsyncFunction::createImpl):
(JSC::JSAsyncFunction::create):
(JSC::JSAsyncFunction::createWithInvalidatedReallocationWatchpoint):
* runtime/JSAsyncFunction.h: Added.
(JSC::JSAsyncFunction::allocationSize):
(JSC::JSAsyncFunction::createStructure):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::lazyAsyncFunctionStructure):
(JSC::JSGlobalObject::asyncFunctionPrototype):
(JSC::JSGlobalObject::asyncFunctionPrototypeConcurrently):
(JSC::JSGlobalObject::asyncFunctionStructure):
(JSC::JSGlobalObject::asyncFunctionStructureConcurrently):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@208052 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Mar 4, 2018
…when emitting a PutHint of a materialized object into a PromotedHeapLocation of a still sunken object

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

Reviewed by Filip Pizlo.

JSTests:

* stress/allocation-sinking-puthint-control-flow.js: Added.
(e):
(bar):
(let.y):
(else.let.y):
(baz):
(foo):
(catch):

Source/JavaScriptCore:

This patch fixes a bug in allocation sinking phase where
we don't properly handle control flow when materializing
an object and also PutHinting that materialization into
a still sunken object. We were performing the PutHint
for the materialization at the point of materialization,
however, we may have materialized along both edges
of a control flow diamond, in which case, we need to
also PutHint at the join point. Consider this program:

```
bb#0:
b: PhantomActivation()
a: PhantomNewFunction()
c: PutHint(@A, @b, ActivationLoc)
Branch(#1, #2)

bb#1:
d: MaterializeActivation()
e: PutHint(@A, @d, ActivationLoc)
f: Upsilon(@d, ^p)
Jump(#3)

bb#2:
g: MaterializeActivation()
h: PutHint(@A, @g, ActivationLoc)
i: Upsilon(@d, ^p)
Jump(#3)

bb#3:
p: Phi()
// What is PromotedHeapLocation(@A, ActivationLoc) here?
// What would we do if we exited?
```
Before this patch, we didn't perform a PutHint of the Phi.
However, we need to, otherwise when exit, we won't know
the value of PromotedHeapLocation(@A, ActivationLoc)

The program we need then, for correctness, is this:
```
bb#0:
b: PhantomActivation()
a: PhantomNewFunction()
c: PutHint(@A, @b, ActivationLoc)
Branch(#1, #2)

bb#1:
d: MaterializeActivation()
e: PutHint(@A, @d, ActivationLoc)
f: Upsilon(@d, ^p)
Jump(#3)

bb#2:
g: MaterializeActivation()
h: PutHint(@A, @g, ActivationLoc)
i: Upsilon(@d, ^p)
Jump(#3)

bb#3:
p: Phi()
j: PutHint(@A, @p, ActivationLoc)
```

This patch makes it so that we emit the necessary PutHint at node `j`.
I've also added more validation to the OSRAvailabilityAnalysisPhase
to catch this problem during validation.

* dfg/DFGOSRAvailabilityAnalysisPhase.cpp:
(JSC::DFG::OSRAvailabilityAnalysisPhase::run):
* dfg/DFGObjectAllocationSinkingPhase.cpp:
* ftl/FTLOperations.cpp:
(JSC::FTL::operationMaterializeObjectInOSR):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@212177 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Mar 5, 2018
…s and zero reg

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

Reviewed by Filip Pizlo.

Added support for data processing 1 source instructions like rbit, rev, clz and cls.
Added support for the FP conditional select instruction, fcsel.  Consolidated the
two classes for handling dmb instructions into one class.  Fixed the instruction
selection mask in the integer conditional select class, A64DOpcodeConditionalSelect.
Fixed the processing of extract instruction (extr) including the rotate right (ror)
pseudo instruction.  Changed the printing of x31 and w31 to xzr and wzr as operands
according to the spec.  Added support for common pseudo instructions.  This includes:
- mvn x1, X2 in place of orn x1, xzr, x2
- lsl x3, x4, #count in place of ubfiz x3, x4, #count, #count
- smull x5, w6, w7 in place of smaddl x5, w6, w7, XZR
- More understandable mov x8, #-304 in place of movn x8, #0x12f
- Eliminated xzr from register index loads and stores, outputing
  ldr x10, [x11] instead of ldr x10, [x11, xzr]

Changed the move wide instructions to use hex literals for movz and movk.
This makes it much easier to decifer sequences of wide moves for large literals.
        Before                       After
  movz   x17, #26136           movz   x17, #0x6618
  movk   x17, #672, lsl #16    movk   x17, #0x2a0, lsl #16
  movk   x17, #1, lsl #32      movk   x17, #0x1, lsl #32

Verified that all instructions currently generated by the JSC stress tests are
disassembled.

* disassembler/ARM64/A64DOpcode.cpp:
(JSC::ARM64Disassembler::A64DOpcodeBitfield::format):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::format):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing2Source::format):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing3Source::format):
(JSC::ARM64Disassembler::A64DOpcodeExtract::format):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::format):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointIntegerConversions::format):
(JSC::ARM64Disassembler::A64DOpcodeDmb::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreImmediate::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterOffset::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreRegisterPair::format):
(JSC::ARM64Disassembler::A64DOpcodeLoadStoreUnsignedImmediate::format):
(JSC::ARM64Disassembler::A64DOpcodeLogicalShiftedRegister::format):
(JSC::ARM64Disassembler::A64DOpcodeMoveWide::format):
(JSC::ARM64Disassembler::A64DOpcodeDmbIsh::format): Deleted.
(JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::format): Deleted.
* disassembler/ARM64/A64DOpcode.h:
(JSC::ARM64Disassembler::A64DOpcode::appendSignedImmediate64):
(JSC::ARM64Disassembler::A64DOpcode::appendUnsignedHexImmediate):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opName):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::sBit):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opCode):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opCode2):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing1Source::opNameIndex):
(JSC::ARM64Disassembler::A64DOpcodeDataProcessing3Source::opName):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::opName):
(JSC::ARM64Disassembler::A64DOpcodeFloatingPointConditionalSelect::condition):
(JSC::ARM64Disassembler::A64DOpcodeDmb::option):
(JSC::ARM64Disassembler::A64DOpcodeDmb::crM):
(JSC::ARM64Disassembler::A64DOpcodeLogicalShiftedRegister::isMov):
(JSC::ARM64Disassembler::A64DOpcodeDmbIsh::opName): Deleted.
(JSC::ARM64Disassembler::A64DOpcodeDmbIshSt::opName): Deleted.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@212592 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Mar 5, 2018
https://bugs.webkit.org/show_bug.cgi?id=168629

Reviewed by Filip Pizlo.

This will make dumping FTL disassembly dump Air intermixed
with the assembly generated by each Air Inst. This is similar
to how dumpDFGDisassembly dumps the generated assembly for each
Node.
        
Here is what the output will look like:
        
Generated FTL JIT code for foo#CUaFiQ:[0x10b76c960->0x10b76c2d0->0x10b7b6da0, FTLFunctionCall, 40 (NeverInline)], instruction count = 40:
BB#0: ; frequency = 1.000000
        0x469004e02e00: push %rbp
        0x469004e02e01: mov %rsp, %rbp
        0x469004e02e04: add $0xffffffffffffffd0, %rsp
    Move $0x10b76c960, %rax, $4487301472(@16)
        0x469004e02e08: mov $0x10b76c960, %rax
    Move %rax, 16(%rbp), @19
        0x469004e02e12: mov %rax, 0x10(%rbp)
    Patch &Patchpoint2, %rbp, %rax, @20
        0x469004e02e16: lea -0x50(%rbp), %rax
        0x469004e02e1a: mov $0x1084081e0, %r11
        0x469004e02e24: cmp %rax, (%r11)
        0x469004e02e27: ja 0x469004e02e9a
    Move 56(%rbp), %rdx, @23
        0x469004e02e2d: mov 0x38(%rbp), %rdx
    Move $0xffff000000000002, %rax, $-281474976710654(@15)
        0x469004e02e31: mov $0xffff000000000002, %rax
    Patch &BranchTest64(3,SameAsRep)1, NonZero, %rdx, %rax, %rdx, @26
        0x469004e02e3b: test %rdx, %rax
        0x469004e02e3e: jnz 0x469004e02f08
    Move 48(%rbp), %rax, @29
        0x469004e02e44: mov 0x30(%rbp), %rax
    Move %rax, %rcx, @31
        0x469004e02e48: mov %rax, %rcx
    Xor64 $6, %rcx, @31
        0x469004e02e4b: xor $0x6, %rcx
    Patch &BranchTest64(3,SameAsRep)1, NonZero, %rcx, $-2, %rax, @35
        0x469004e02e4f: test $0xfffffffffffffffe, %rcx
        0x469004e02e56: jnz 0x469004e02f12
    Patch &Branch32(3,SameAsRep)0, NotEqual, (%rdx), $266, %rdx, @45
        0x469004e02e5c: cmp $0x10a, (%rdx)
        0x469004e02e62: jnz 0x469004e02f1c
    BranchTest32 NonZero, %rax, $1, @49
        0x469004e02e68: test $0x1, %al
        0x469004e02e6a: jnz 0x469004e02e91
  Successors: #3, #1
BB#1: ; frequency = 1.000000
  Predecessors: #0
    Move $0, %rcx, @65
        0x469004e02e70: xor %rcx, %rcx
    Jump @66
  Successors: #2
BB#2: ; frequency = 1.000000
  Predecessors: #1, #3
    Move 24(%rdx), %rax, @58
        0x469004e02e73: mov 0x18(%rdx), %rax
    Patch &BranchAdd32(4,ForceLateUseUnlessRecoverable)3, Overflow, %rcx, %rax, %rcx, %rcx, %rax, @60
        0x469004e02e77: add %eax, %ecx
        0x469004e02e79: jo 0x469004e02f26
    Move $0xffff000000000000, %rax, $-281474976710656(@14)
        0x469004e02e7f: mov $0xffff000000000000, %rax
    Add64 %rcx, %rax, %rax, @62
        0x469004e02e89: add %rcx, %rax
    Ret64 %rax, @63
        0x469004e02e8c: mov %rbp, %rsp
        0x469004e02e8f: pop %rbp
        0x469004e02e90: ret 
BB#3: ; frequency = 1.000000
  Predecessors: #0
    Move 16(%rdx), %rcx, @52
        0x469004e02e91: mov 0x10(%rdx), %rcx
    Jump @55
        0x469004e02e95: jmp 0x469004e02e73
  Successors: #2

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/air/AirCode.h:
(JSC::B3::Air::Code::setDisassembler):
(JSC::B3::Air::Code::disassembler):
* b3/air/AirDisassembler.cpp: Added.
(JSC::B3::Air::Disassembler::startEntrypoint):
(JSC::B3::Air::Disassembler::endEntrypoint):
(JSC::B3::Air::Disassembler::startLatePath):
(JSC::B3::Air::Disassembler::endLatePath):
(JSC::B3::Air::Disassembler::startBlock):
(JSC::B3::Air::Disassembler::addInst):
(JSC::B3::Air::Disassembler::dump):
* b3/air/AirDisassembler.h: Added.
* b3/air/AirGenerate.cpp:
(JSC::B3::Air::generate):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@212775 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Apr 7, 2018
https://bugs.webkit.org/show_bug.cgi?id=172288

Patch by Romain Bellessort <romain.bellessort@crf.canon.fr> on 2017-05-23
Reviewed by Chris Dumez.

Two changes are implemented in this patch:
- Change #1: An issue was reported to GH [1] while working on respondInClosedState
implementation. This issue has now been fixed, and this patch aligns implementation
with spec [2].
- Change #2: In addition, this patch also fixes a bug that went unnoticed as code
is not yet reachable (usage of controller.@reader is not valid and is therefore
replaced by controller.@controlledReadableStream.@reader).

[1] whatwg/streams#686
[2] https://streams.spec.whatwg.org/#readable-byte-stream-controller-respond-in-closed-state

No added test as:
- Change #1 does not change behavior;
- Change #2 is not testable as the code is not yet reachable.

* Modules/streams/ReadableByteStreamInternals.js:
(readableByteStreamControllerRespondInClosedState): Aligned with spec.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@217279 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Oct 20, 2018
…iled on Windows Python

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

Reviewed by Daniel Bates.

There are two failures in this test case:
1. proc.poll() doesn't return 0.
2. stderr is not output.

For failure #1, this is expected. the process should not exit at
the time. proc.poll() should return None because the process is
still alive.

This change added a new test to check proc.poll() becomes 0 after
the process successfully exits.

For failure #2, stderr is not flushed even though stdout is
flushed. This change uses '-u' command switch to force stdin,
stdout and stderr to be totally unbuffered.

* Scripts/webkitpy/port/server_process_unittest.py:
(TestServerProcess.test_basic): Added -u command switch. Do not
flush stdout. Removed the special condition for Windows. Add a new
test to check proc.poll() returns 0.
(TestServerProcess.test_process_crashing): Added -u command
switch. Do not flush stdout.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@234130 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Dec 5, 2018
…nd the marker item renderer.

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

Reviewed by Antti Koivisto.

Source/WebCore:

While moving the marker item renderer to its correct subtree, we accidentally remove the soon-to-be parent anonymous block.
Moving a renderer is a 2 step process:
1. Detach the renderer from its current parent
2. Attach it to its new parent.
During step #1, we check if there is a chance to collapse anonymous blocks. In this case the soon-to-be-parent is a sibling anonymous block which, after detaching the marker sibling
is not needed anymore (except we use it as the new parent).

Test: fast/inline/marker-list-item-move-should-not-crash.html

* rendering/updating/RenderTreeBuilder.cpp:
(WebCore::RenderTreeBuilder::detach):
* rendering/updating/RenderTreeBuilder.h:
* rendering/updating/RenderTreeBuilderBlock.cpp:
(WebCore::RenderTreeBuilder::Block::detach):
* rendering/updating/RenderTreeBuilderBlock.h:
* rendering/updating/RenderTreeBuilderList.cpp:
(WebCore::RenderTreeBuilder::List::updateItemMarker):

LayoutTests:

* fast/inline/marker-list-item-move-should-not-crash-expected.txt: Added.
* fast/inline/marker-list-item-move-should-not-crash.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@238119 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Dec 5, 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 #7: JSC::JSObject* JSC::jsCast<JSC::JSObject*, JSC::JSCell>(from=0x00007ffeefbbde30) at JSCast.h:36
    frame #8: JSC::asObject(cell=0x00007ffeefbbde30) at JSObject.h:1299
    frame #9: JSC::asObject(value=JSValue @ 0x00007ffeefbba380) at JSObject.h:1304
    frame #10: JSC::Register::object(this=0x00007ffeefbbdd58) const at JSObject.h:1514
    frame #11: JSC::ExecState::jsCallee(this=0x00007ffeefbbdd40) const at CallFrame.h:107
    frame #12: JSC::ExecState::isStackOverflowFrame(this=0x00007ffeefbbdd40) const at CallFrameInlines.h:36
    frame #13: JSC::StackVisitor::StackVisitor(this=0x00007ffeefbba860, startFrame=0x00007ffeefbbdd40, vm=0x0000631000000800) at StackVisitor.cpp:52
    frame #14: JSC::StackVisitor::StackVisitor(this=0x00007ffeefbba860, startFrame=0x00007ffeefbbdd40, vm=0x0000631000000800) at StackVisitor.cpp:41
    frame #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 #16: JSC::Interpreter::getStackTrace(this=0x0000602000005db0, owner=0x000062d00020cbe0, results=0x00006020000249d0, framesToSkip=0, maxStackSize=1) at Interpreter.cpp:437
    frame #17: JSC::getStackTrace(exec=0x000062d00002c048, vm=0x0000631000000800, obj=0x000062d00020cbe0, useCurrentFrame=true) at Error.cpp:170
    frame #18: JSC::ErrorInstance::finishCreation(this=0x000062d00020cbe0, exec=0x000062d00002c048, vm=0x0000631000000800, message=0x00007ffeefbbb800, useCurrentFrame=true) at ErrorInstance.cpp:119
    frame #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 #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 #21: JSC::createRangeError(exec=0x000062d00002c048, globalObject=0x000062d00002c000, message=0x00007ffeefbbb800) at Error.cpp:316
    frame #22: JSC::createStackOverflowError(exec=0x000062d00002c048, globalObject=0x000062d00002c000) at ExceptionHelpers.cpp:77
    frame #23: JSC::createStackOverflowError(exec=0x000062d00002c048) at ExceptionHelpers.cpp:72
    frame #24: JSC::throwStackOverflowError(exec=0x000062d00002c048, scope=0x00007ffeefbbbaa0) at ExceptionHelpers.cpp:335
    frame #25: JSC::ProxyObject::getOwnPropertySlotCommon(this=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbba80, slot=0x00007ffeefbbc720) at ProxyObject.cpp:372
    frame #26: JSC::ProxyObject::getOwnPropertySlot(object=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbbd40, slot=0x00007ffeefbbc720) at ProxyObject.cpp:395
    frame #27: JSC::JSObject::getNonIndexPropertySlot(this=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbbea0, slot=0x00007ffeefbbc720) at JSObjectInlines.h:150
    frame #28: bool JSC::JSObject::getPropertySlot<false>(this=0x000062d000200e40, exec=0x000062d00002c048, propertyName=PropertyName @ 0x00007ffeefbbc320, slot=0x00007ffeefbbc720) at JSObject.h:1424
    frame #29: JSC::JSObject::calculatedClassName(object=0x000062d000200e40) at JSObject.cpp:535
    frame #30: JSC::Structure::toStructureShape(this=0x000062d000007410, value=JSValue @ 0x00007ffeefbbcae0, sawPolyProtoStructure=0x00007ffeefbbcf60) at Structure.cpp:1142
    frame #31: JSC::TypeProfilerLog::processLogEntries(this=0x000060400000a950, reason=0x00007ffeefbbd5c0) at TypeProfilerLog.cpp:89
    frame #32: JSC::JIT::doMainThreadPreparationBeforeCompile(this=0x0000619000034da0) at JIT.cpp:951
    frame #33: JSC::JITWorklist::Plan::Plan(this=0x0000619000034d80, codeBlock=0x000062d0001d88c0, loopOSREntryBytecodeOffset=0) at JITWorklist.cpp:43
    frame #34: JSC::JITWorklist::Plan::Plan(this=0x0000619000034d80, codeBlock=0x000062d0001d88c0, loopOSREntryBytecodeOffset=0) at JITWorklist.cpp:42
    frame #35: JSC::JITWorklist::compileLater(this=0x0000616000001b80, codeBlock=0x000062d0001d88c0, loopOSREntryBytecodeOffset=0) at JITWorklist.cpp:256
    frame #36: JSC::LLInt::jitCompileAndSetHeuristics(codeBlock=0x000062d0001d88c0, exec=0x00007ffeefbbde30, loopOSREntryBytecodeOffset=0) at LLIntSlowPaths.cpp:391
    frame #37: llint_replace(exec=0x00007ffeefbbde30, pc=0x00006040000161ba) at LLIntSlowPaths.cpp:516
    frame #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
pulkomandy pushed a commit that referenced this pull request Dec 6, 2018
https://bugs.webkit.org/show_bug.cgi?id=192236
<rdar://problem/45792118>

Reviewed by Geoffrey Garen.

Source/WebCore:

This patch introduces asynchronous content change observation.
1. Start observing synchronous content change and timer install as the result of dispatching mouseMoved event.
2. Start observing synchronous content change and style recalc schedule as the result of a timer callback (installed at #1).
3. Start observing synchronous content change as the result of a style recalc (scheduled at #2).

This patch also extends the timeout value from 100ms to 250ms. Certain content prefer longer timeouts (see http://briancherne.github.io/jquery-hoverIntent/ for details).

Test: fast/events/touch/ios/hover-when-style-change-is-async.html

* dom/Document.cpp:
(WebCore::Document::scheduleStyleRecalc):
(WebCore::Document::updateStyleIfNeeded):
* page/DOMTimer.cpp:
(WebCore::DOMTimer::install):
(WebCore::DOMTimer::fired):
* platform/ios/wak/WKContentObservation.cpp:
(WKStartObservingStyleRecalcScheduling):
(WKStopObservingStyleRecalcScheduling):
(WKIsObservingStyleRecalcScheduling):
(WKSetShouldObserveNextStyleRecalc):
(WKShouldObserveNextStyleRecalc):
(WKSetObservedContentChange):
* platform/ios/wak/WKContentObservation.h:

LayoutTests:

* fast/events/touch/ios/hover-when-style-change-is-async-expected.txt: Added.
* fast/events/touch/ios/hover-when-style-change-is-async.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@238759 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request May 4, 2019
https://bugs.webkit.org/show_bug.cgi?id=194648

Reviewed by Keith Miller.

JSTests:

* microbenchmarks/generate-multiple-llint-entrypoints.js: Added.

Source/JavaScriptCore:

1. Making LLIntThunks singleton.

Motivation: Former implementation has one LLIntThunk per type per VM.
However, the generated code for every kind of thunk is essentially the
same and we end up wasting memory (right now jitAllocationGranule = 32 bytes)
when we have 2 or more VM instantiated. Turn these thunks into
singleton will avoid such wasting.

Tradeoff: This change comes with a price, because we will keep thunks
allocated even when there is no VM instantiated. Considering WebCore use case,
the situation of having no VM instantiated is uncommon, since once a
VM is created through `commomVM()`, it will never be destroyed. Given
that, this change does not impact the overall memory comsumption of
WebCore/JSC. It also doesn't impact memory footprint, since thunks are
generated lazily (see results below).

Since we are keeping a static `MacroAssemblerCodeRef<JITThunkPtrTag>`,
we have the assurance that JITed code will never be deallocated,
given it is being pointed by `RefPtr<ExecutableMemoryHandle> m_executableMemory`.
To understand why we decided to make LLIntThunks singleton instead of
removing them, please see the comment on `llint/LLIntThunks.cpp`.

2. Making all LLIntEntrypoints singleton

Motivation: With singleton LLIntThunks, we also can have singleton
DirectJITCodes and NativeJITCodes for each LLIntEntrypoint type and
avoid multiple allocations of objects with the same content.

Tradeoff: As explained before, once we allocate an entrypoint, it
will be alive until the program exits. However, the gains we can
achieve in some use cases justifies such allocations.

As DirectJITCode and NativeJITCode are ThreadSafeRefCounted and we are using
`codeBlock->setJITCode(makeRef(*jitCode))`, their reference counter
will never be less than 1.

3. Memory usage analysis

This change reduces memory usage on stress/generate-multiple-llint-entrypoints.js
by 2% and is neutral on JetStream 2. Following results were generated
running each benchmark 6 times and using 95% Student's t distribution
confidence interval.

microbenchmarks/generate-multiple-llint-entrypoints.js (Changes uses less memory):
    Mean of memory peak on ToT: 122576896 bytes (confidence interval: 67747.2316)
    Mean of memory peak on Changes: 119248213.33 bytes (confidence interval: 50251.2718)

JetStream2 (Neutral):
    Mean of memory peak on ToT: 5442742272 bytes (confidence interval: 134381565.9117)
    Mean of memory peak on Changes: 5384949760 bytes (confidence interval: 158413904.8352)

4. Performance Analysis

This change is performance neutral on JetStream 2 and Speedometer 2.
See results below.:

JetStream 2 (Neutral):
    Mean of score on ToT: 139.58 (confidence interval: 2.44)
    Mean of score on Changes: 141.46 (confidence interval: 4.24)

Speedometer run #1
   ToT: 110 +- 2.9
   Changes: 110 +- 1.8

Speedometer run #2
   ToT: 110 +- 1.6
   Changes: 108 +- 2.3

Speedometer run #3
   ToT: 110 +- 3.0
   Changes: 110 +- 1.4

* jit/JSInterfaceJIT.h:
(JSC::JSInterfaceJIT::JSInterfaceJIT):
* llint/LLIntEntrypoint.cpp:

Here we are changing the usage or DirectJITCode by NativeJITCode on cases
where there is no difference from address of calls with and without
ArithCheck.

(JSC::LLInt::setFunctionEntrypoint):
(JSC::LLInt::setEvalEntrypoint):
(JSC::LLInt::setProgramEntrypoint):
(JSC::LLInt::setModuleProgramEntrypoint):
(JSC::LLInt::setEntrypoint):
* llint/LLIntEntrypoint.h:
* llint/LLIntThunks.cpp:
(JSC::LLInt::generateThunkWithJumpTo):
(JSC::LLInt::functionForCallEntryThunk):
(JSC::LLInt::functionForConstructEntryThunk):
(JSC::LLInt::functionForCallArityCheckThunk):
(JSC::LLInt::functionForConstructArityCheckThunk):
(JSC::LLInt::evalEntryThunk):
(JSC::LLInt::programEntryThunk):
(JSC::LLInt::moduleProgramEntryThunk):
(JSC::LLInt::functionForCallEntryThunkGenerator): Deleted.
(JSC::LLInt::functionForConstructEntryThunkGenerator): Deleted.
(JSC::LLInt::functionForCallArityCheckThunkGenerator): Deleted.
(JSC::LLInt::functionForConstructArityCheckThunkGenerator): Deleted.
(JSC::LLInt::evalEntryThunkGenerator): Deleted.
(JSC::LLInt::programEntryThunkGenerator): Deleted.
(JSC::LLInt::moduleProgramEntryThunkGenerator): Deleted.
* llint/LLIntThunks.h:
* runtime/ScriptExecutable.cpp:
(JSC::setupLLInt):
(JSC::ScriptExecutable::prepareForExecutionImpl):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@243136 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request May 18, 2019
…flaky failure on Mac Release builds

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

Reviewed by Tim Horton.

This flaky test exercises a race condition between when attachment insertion updates are dispatched from the web
process to the UI process, and when script is executed via -[WKWebView evaluateJavaScript:completionHandler:].
Since attachment insertion and removal updates from the web process to the UI process are scheduled on a zero-
delay timer, we end up with this sequence of events in the problematic (failure) case:

(a) [UI]    Run script #1 (which calls `HTMLAttachmentElement.getAttachmentIdentifier`)
    ...IPC from UI to web process...
(b) [Web]   Evaluate script #1 in the web process, which schedules attachment updates on a zero-delay timer
    ...IPC from web to UI process...
(c) [UI]    Invoke completion handler for script #1
(d) [UI]    Run script #2 (which calls `document.querySelector('img').attachmentIdentifier`)
    ...IPC from UI to web process...
(e) [Web]   Evaluate script #2 in the web process
(f) [Web]   Zero-delay timer fires and dispatches attachment updates to the UI process

...which means that script #2 will complete before the UI process has received the attachment updates sent in
step (f). However, in the case where the flaky test succeeds, the zero-delay timer in (f) fires *before* script
#2 is run in step (e).

This patch fixes the flaky test by waiting until attachment insertion updates are guaranteed to be received in
the UI process by waiting on a script message posted by the web process, after attachment updates are
dispatched.

* TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
(TestWebKitAPI::TEST):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@244251 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request May 18, 2019
https://bugs.webkit.org/show_bug.cgi?id=197118
<rdar://problem/49969960>

Reviewed by Michael Saboff.

JSTests:

* stress/abstract-value-can-include-int52.js: Added.
(foo):
(index.index.8.index.60.index.65.index.1234.index.1234.parseInt.string_appeared_here.String.fromCharCode):

Source/JavaScriptCore:

Let's analyze this control flow diamond:

#0
branch #1, #2

#1:
PutStack(JSValue, loc42)
Jump #3

#2:
PutStack(Int52, loc42)
Jump #3

#3:
...

Our abstract value for loc42 at the head of #3 will contain an abstract
value that us the union of Int52 with other things. Obviously in the
above program, a GetStack for loc42 would be inavlid, since it might
be loading either JSValue or Int52. However, the abstract interpreter
just tracks what the value could be, and it could be Int52 or JSValue.

When I did the Int52 refactoring, I expected such things to never happen,
but it turns out it does. We should just allow for this instead of asserting
against it since it's valid IR to do the above.

* bytecode/SpeculatedType.cpp:
(JSC::dumpSpeculation):
* dfg/DFGAbstractValue.cpp:
(JSC::DFG::AbstractValue::checkConsistency const):
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::validateTypeAcceptingBoxedInt52 const):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@244480 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request May 19, 2019
https://bugs.webkit.org/show_bug.cgi?id=197496

Reviewed by Lucas Forschler.

* BuildSlaveSupport/ews-app/ews/views/statusbubble.py:
(StatusBubble._build_bubble):
(StatusBubble._queue_position):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@244930 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Dec 8, 2019
…anches during interpretation

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

Reviewed by Saam Barati.

JSTests:

* stress/object-allocation-sinking-interpretation-can-interpret-edges-that-can-be-proven-unreachable-in-ai.js:
(main.v0):
(main):

Source/JavaScriptCore:

Object Allocation Sinking phase has a lightweight abstract interpreter which interprets DFG nodes related to allocations and properties.
This interpreter is lightweight since it does not track abstract values and conditions as deeply as AI does. It can happen that this
interpreter interpret the control-flow edge that AI proved that is never taken.
AI already knows some control-flow edges are never taken, and based on this information, AI can remove CheckStructure nodes. But
ObjectAllocationSinking phase can trace this never-taken edges and propagate structure information that contradicts to the analysis
done in ObjectAllocationSinking.

Let's see the example.

    BB#0
        35: NewObject([%AM:Object])
        ...
        47: Branch(ConstantTrue, T:#1, F:#2)

    BB#1 // This basic block is never taken due to @47's jump.
        ...
        71: PutByOffset(@35, @66, id2{a}, 0, W:NamedProperties(2))
        72: PutStructure(@35, %AM:Object -> %Dx:Object, ID:60066)
        ...
        XX: Jump(#2)

    BB#2
        ...
        92: CheckStructure(@35, [%Dx:Object])
        93: PutByOffset(@35, @35, id2{a}, 0, W:NamedProperties(2))
        ...

AI removes @92 because AI knows BB#0 only takes BB#1 branch. @35's Structure is always %Dx so @92 is redundant.
AI proved that @71 and @72 are always executed while BB#0 -> BB#2 edge is never taken so that @35 object's structure is proven at @92.
After AI removes @92, ObjectAllocationSinking starts looking into this graph.

    BB#0
        35: NewObject([%AM:Object])
        ...
        47: Branch(ConstantTrue, T:#1, F:#2)

    BB#1 // This basic block is never taken due to @47's jump.
        ...
        71: PutByOffset(@35, @66, id2{a}, 0, W:NamedProperties(2))
        72: PutStructure(@35, %AM:Object -> %Dx:Object, ID:60066)
        ...
        XX: Jump(#2)

    BB#2
        ...
        93: PutByOffset(@35, @35, id2{a}, 0, W:NamedProperties(2))
        ...
        YY: Jump(#3)

    BB#3
        ...
        ZZ: <HERE> want to materialize @35's sunk object.

Since AI does not change the @47 Branch to Jump (it is OK anyway), BB#0 -> BB#2 edge remains and ObjectAllocationSinking phase propagates information in
BB#0's %AM structure information to BB#2. ObjectAllocationSinking phase converts @35 to PhantomNewObject, removes PutByOffset and PutStructure, and
insert MaterializeNewObject in @zz. At this point, ObjectAllocationSinking lightweight interpreter gets two structures while AI gets one: @35's original
one (%AM) and @72's replaced one (%Dx). Since AI already proved @zz only gets %Dx, AI removed @92 CheckStructure. But this is not known to ObjectAllocationSinking
phase's interpretation. So when creating recovery data, MultiPutByOffset includes two structures, %AM and %Dx. This is OK since MultiPutByOffset takes
conservative set of structures and performs switching. But the problem here is that %AM's id2{a} offset is -1 since %AM does not have such a property.
So when creating MultiPutByOffset in ObjectAllocationSinking, we accidentally create MultiPutByOffset with -1 offset data, and lowering phase hits the debug
assertion.

    187: MultiPutByOffset(@138, @138, id2{a}, <Replace: [%AM:Object], offset = -1, >, <Replace: [%Dx:Object], offset = 0, >)

This bug is harmless since %AM structure comparison never meets at runtime. But we are not considering the case including `-1` offset property in MultiPutByOffset data.
In this patch, we just filter out apparently wrong structures when creating MultiPutByOffset in ObjectAllocationSinking. This is OK since it never comes at runtime.

* dfg/DFGObjectAllocationSinkingPhase.cpp:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@249306 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Jan 12, 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 #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 #7: 0x00000001008289a2 JavaScriptCore`ctiMasmProbeTrampoline + 338
        frame #8: 0x0000466db28025be
        frame #9: 0x0000000100754ffc JavaScriptCore`llint_entry at LowLevelInterpreter.asm:994
        frame #10: 0x0000000100738173 JavaScriptCore`vmEntryToJavaScript at LowLevelInterpreter64.asm:307
        frame #11: 0x0000000101489307 JavaScriptCore`JSC::JITCode::execute(this=0x0000000106ba1520, vm=0x0000000106d00000, protoCallFrame=0x00007ffeefbfd9b8) at JITCodeInlines.h:38:38
        frame #12: 0x0000000101488982 JavaScriptCore`JSC::Interpreter::executeProgram(this=0x0000000106bfd1f8, source=0x00007ffeefbff090, (null)=0x000000010d0e0000, thisObj=0x000000010d0e8020) at Interpreter.cpp:847:51
        frame #13: 0x00000001017d1f9c JavaScriptCore`JSC::evaluate(globalObject=0x000000010d0e0000, source=0x00007ffeefbff090, thisValue=JSValue @ 0x00007ffeefbfef60, returnedException=0x00007ffeefbff0b0) at Completion.cpp:146:38
        frame #14: 0x000000010005838f jsc`runWithOptions(globalObject=0x000000010d0e0000, options=0x00007ffeefbff620, success=0x00007ffeefbff48b) at jsc.cpp:2670:35
        frame #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 #16: 0x0000000100006eff jsc`int runJSC<jscmain(int, char**)::$_6>(options=0x00007ffeefbff620, isWorker=false, func=0x00007ffeefbff5a0)::$_6 const&) at jsc.cpp:3003:9
        frame #17: 0x0000000100005988 jsc`jscmain(argc=10, argv=0x00007ffeefbff6c8) at jsc.cpp:3150:18
        frame #18: 0x000000010000575e jsc`main(argc=10, argv=0x00007ffeefbff6c8) at jsc.cpp:2498:15
        frame #19: 0x00007fff6cfc4da9 libdyld.dylib`start + 1
        frame #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
pulkomandy pushed a commit that referenced this pull request Jan 26, 2020
Object allocation sinking is missing PutHint for allocations unreachable in the graph
https://bugs.webkit.org/show_bug.cgi?id=203799
<rdar://problem/56852162>

Reviewed by Saam Barati.

* stress/allocation-sinking-puthint-control-flow-2.js: Added.
(f.handler.construct):
(f):

Source/JavaScriptCore:
Object allocation sinking is missing PutHint for sunken allocations
https://bugs.webkit.org/show_bug.cgi?id=203799
<rdar://problem/56852162>

Reviewed by Saam Barati.

Consider the following graph:

    Block #0:
      1: PhantomCreateActivation()
      2: PhantomNewFunction()
      PutHint(@2, @1, FunctionActivationPLoc)
      Branch(#1, #2)

    Block #1:
      3: MaterializeCreateActivation()
      PutHint(@2, @3, FunctionActivationPLoc)
      Upsilon(@3, ^5)
      Jump(#3)

    Block #2:
      4: MaterializeCreateActivation()
      PutHint(@2, @4, FunctionActivationPLoc)
      Upsilon(@4, ^5)
      Jump(#3)

    Block #3:
      5: Phi()
      ExitOK()

On Block #3, we need to emit a PutHint after the Phi, since we might exit after it. However,
object allocation sinking skipped this Phi because it was checking whether the base of the
location that caused us to create this Phi (@2) was live, but it's dead in the graph (there
are no pointers to it).  The issue is that, even though there are no pointers to the base, the
location `PromotedHeapLocation(@2, FunctionActivationPLoc)` is still live, so we should PutHint
to it. We fix it by checking for liveness of the location rather than its base.

* dfg/DFGObjectAllocationSinkingPhase.cpp:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254725 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Feb 6, 2020
Object allocation sinking is missing PutHint for allocations unreachable in the graph
https://bugs.webkit.org/show_bug.cgi?id=203799
<rdar://problem/56852162>

Reviewed by Saam Barati.

* stress/allocation-sinking-puthint-control-flow-2.js: Added.
(f.handler.construct):
(f):

Source/JavaScriptCore:
Object allocation sinking is missing PutHint for sunken allocations
https://bugs.webkit.org/show_bug.cgi?id=203799
<rdar://problem/56852162>

Reviewed by Saam Barati.

Consider the following graph:

    Block #0:
      1: PhantomCreateActivation()
      2: PhantomNewFunction()
      PutHint(@2, @1, FunctionActivationPLoc)
      Branch(#1, #2)

    Block #1:
      3: MaterializeCreateActivation()
      PutHint(@2, @3, FunctionActivationPLoc)
      Upsilon(@3, ^5)
      Jump(#3)

    Block #2:
      4: MaterializeCreateActivation()
      PutHint(@2, @4, FunctionActivationPLoc)
      Upsilon(@4, ^5)
      Jump(#3)

    Block #3:
      5: Phi()
      ExitOK()

On Block #3, we need to emit a PutHint after the Phi, since we might exit after it. However,
object allocation sinking skipped this Phi because it was checking whether the base of the
location that caused us to create this Phi (@2) was live, but it's dead in the graph (there
are no pointers to it).  The issue is that, even though there are no pointers to the base, the
location `PromotedHeapLocation(@2, FunctionActivationPLoc)` is still live, so we should PutHint
to it. We fix it by checking for liveness of the location rather than its base.

* dfg/DFGObjectAllocationSinkingPhase.cpp:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254866 268f45cc-cd09-0410-ab3c-d52691b4dbfc
pulkomandy pushed a commit that referenced this pull request Feb 6, 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:#7/w:1.000000, W:SideState, bc#74, ExitInvalid)
    ...
</code>

B3 graph dump:
<code>
    ...
    b3  BB#14: ; frequency = 10.000000
    b3    Predecessors: #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:#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:#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
pulkomandy pushed a commit that referenced this pull request Aug 10, 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
pulkomandy pushed a commit that referenced this pull request Oct 17, 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
2 participants