Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu

case ArithAbs:
if (node->child1().useKind() == Int32Use || node->child1().useKind() == DoubleRepUse)
def(PureValue(node));
def(PureValue(node, node->arithMode()));
else {
read(World);
write(Heap);
Expand All @@ -248,7 +248,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu
if (node->child1().useKind() == Int32Use
|| node->child1().useKind() == DoubleRepUse
|| node->child1().useKind() == Int52RepUse)
def(PureValue(node));
def(PureValue(node, node->arithMode()));
else {
read(World);
write(Heap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ ALWAYS_INLINE void gcSafeMemcpy(T* dst, T* src, size_t bytes)
bitwise_cast<volatile uint64_t*>(dst)[i] = bitwise_cast<volatile uint64_t*>(src)[i];
};

#if COMPILER(GCC_COMPATIBLE) && USE(JSVALUE64)
#if COMPILER(GCC_COMPATIBLE) && (CPU(X86_64) || CPU(ARM64))
if (bytes <= smallCutoff)
slowPathForwardMemcpy();
else if (isARM64() || bytes <= mediumCutoff) {
Expand Down Expand Up @@ -121,8 +121,6 @@ ALWAYS_INLINE void gcSafeMemcpy(T* dst, T* src, size_t bytes)
:
: "d0", "d1", "memory"
);
#else
slowPathForwardMemcpy();
#endif // CPU(X86_64)
} else {
RELEASE_ASSERT(isX86_64());
Expand All @@ -139,7 +137,7 @@ ALWAYS_INLINE void gcSafeMemcpy(T* dst, T* src, size_t bytes)
}
#else
slowPathForwardMemcpy();
#endif // COMPILER(GCC_COMPATIBLE)
#endif // COMPILER(GCC_COMPATIBLE) && (CPU(X86_64) || CPU(ARM64))
#else
memcpy(dst, src, bytes);
#endif // USE(JSVALUE64)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@

namespace JSC {

inline Structure* Structure::create(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingType, unsigned inlineCapacity)
inline Structure* Structure::create(VM& vm, JSGlobalObject* globalObject, JSValue prototype, const TypeInfo& typeInfo, const ClassInfo* classInfo, IndexingType indexingModeIncludingHistory, unsigned inlineCapacity)
{
ASSERT(vm.structureStructure);
ASSERT(classInfo);
if (auto* object = prototype.getObject()) {
ASSERT(!object->anyObjectInChainMayInterceptIndexedAccesses(vm) || hasSlowPutArrayStorage(indexingType) || !hasIndexedProperties(indexingType));
ASSERT(!object->anyObjectInChainMayInterceptIndexedAccesses(vm) || hasSlowPutArrayStorage(indexingModeIncludingHistory) || !hasIndexedProperties(indexingModeIncludingHistory));
object->didBecomePrototype();
}

Structure* structure = new (NotNull, allocateCell<Structure>(vm.heap)) Structure(vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity);
Structure* structure = new (NotNull, allocateCell<Structure>(vm.heap)) Structure(vm, globalObject, prototype, typeInfo, classInfo, indexingModeIncludingHistory, inlineCapacity);
structure->finishCreation(vm);
return structure;
}
Expand Down
88 changes: 82 additions & 6 deletions modules/javafx.web/src/main/native/Source/WTF/wtf/DataMutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,74 @@
#pragma once

#include <wtf/Lock.h>
#include <wtf/Threading.h>

namespace WTF {

template<typename T>
// By default invalid access checks are only done in Debug builds.
#if !defined(ENABLE_DATA_MUTEX_CHECKS)
#if defined(NDEBUG)
#define ENABLE_DATA_MUTEX_CHECKS 0
#else
#define ENABLE_DATA_MUTEX_CHECKS 1
#endif
#endif

#if ENABLE_DATA_MUTEX_CHECKS
#define DATA_MUTEX_CHECK(expr) RELEASE_ASSERT(expr)
#else
#define DATA_MUTEX_CHECK(expr)
#endif

template<typename LockType>
class OwnerAwareLockAdapter {
public:
void lock()
{
DATA_MUTEX_CHECK(m_owner != &Thread::current()); // Thread attempted recursive lock (unsupported).
m_lock.lock();
#if ENABLE_DATA_MUTEX_CHECKS
ASSERT(!m_owner);
m_owner = &Thread::current();
#endif
}

void unlock()
{
#if ENABLE_DATA_MUTEX_CHECKS
m_owner = nullptr;
#endif
m_lock.unlock();
}

bool tryLock()
{
DATA_MUTEX_CHECK(m_owner != &Thread::current()); // Thread attempted recursive lock (unsupported).
if (!m_lock.tryLock())
return false;

#if ENABLE_DATA_MUTEX_CHECKS
ASSERT(!m_owner);
m_owner = &Thread::current();
#endif
return true;
}

bool isLocked() const
{
return m_lock.isLocked();
}

private:
#if ENABLE_DATA_MUTEX_CHECKS
Thread* m_owner { nullptr }; // Use Thread* instead of RefPtr<Thread> since m_owner thread is always alive while m_owner is set.
#endif
LockType m_lock;
};

using OwnerAwareLock = OwnerAwareLockAdapter<Lock>;

template<typename T, typename LockType = OwnerAwareLock>
class DataMutex {
WTF_MAKE_FAST_ALLOCATED;
WTF_MAKE_NONCOPYABLE(DataMutex);
Expand All @@ -44,32 +108,44 @@ class DataMutex {

T* operator->()
{
DATA_MUTEX_CHECK(m_mutex.isLocked());
return &m_data;
}

T& operator*()
{
DATA_MUTEX_CHECK(m_mutex.isLocked());
return m_data;
}

Lock& mutex()
LockType& mutex()
{
return m_mutex;
}

LockHolder& lockHolder()
Locker<LockType>& lockHolder()
{
return m_lockHolder;
}

// Used to avoid excessive brace scoping when only small parts of the code need to be run unlocked.
// Please be mindful that accessing the wrapped data from the callback is unsafe and will fail on assertions.
// It's helpful to use a minimal lambda capture to be conscious of what data you're having access to in these sections.
void runUnlocked(WTF::Function<void()> callback)
{
m_mutex.unlock();
callback();
m_mutex.lock();
}

private:
Lock& m_mutex;
LockHolder m_lockHolder;
LockType& m_mutex;
Locker<LockType> m_lockHolder;
T& m_data;
};

private:
Lock m_mutex;
LockType m_mutex;
T m_data;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ page/scrolling/nicosia/ScrollingTreeStickyNode.cpp

page/scrolling/generic/ScrollingThreadGeneric.cpp

platform/ScrollAnimationKinetic.cpp

platform/UserAgentQuirks.cpp

platform/graphics/GLContext.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class JSDOMWindowProperties final : public JSDOMObject {

static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::MayHaveIndexedAccessors);
}

static bool getOwnPropertySlot(JSC::JSObject*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::PropertySlot&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -811,16 +811,27 @@ bool ScriptController::executeIfJavaScriptURL(const URL& url, RefPtr<SecurityOri

const int javascriptSchemeLength = sizeof("javascript:") - 1;

JSDOMGlobalObject* globalObject = jsWindowProxy(mainThreadNormalWorld()).window();
VM& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);

String decodedURL = decodeURLEscapeSequences(url.string());
auto result = executeScriptIgnoringException(decodedURL.substring(javascriptSchemeLength));
RELEASE_ASSERT(&vm == &jsWindowProxy(mainThreadNormalWorld()).window()->vm());

// If executing script caused this frame to be removed from the page, we
// don't want to try to replace its document!
if (!m_frame.page())
return true;

if (!result)
return true;

String scriptResult;
if (!result || !result.getString(jsWindowProxy(mainThreadNormalWorld()).window(), scriptResult))
bool isString = result.getString(globalObject, scriptResult);
RETURN_IF_EXCEPTION(throwScope, true);

if (!isString)
return true;

// FIXME: We should always replace the document, but doing so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2741,15 +2741,16 @@ sub GenerateHeader
# Structure ID
push(@headerContent, " static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)\n");
push(@headerContent, " {\n");
my $indexingModeIncludingHistory = InstanceOverridesGetOwnPropertySlot($interface) ? "JSC::MayHaveIndexedAccessors" : "JSC::NonArray";
if (IsDOMGlobalObject($interface)) {
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags), info());\n");
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags), info(), $indexingModeIncludingHistory);\n");
} elsif ($codeGenerator->InheritsInterface($interface, "Node")) {
my $type = GetJSTypeForNode($interface);
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType($type), StructureFlags), info());\n");
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType($type), StructureFlags), info(), $indexingModeIncludingHistory);\n");
} elsif ($codeGenerator->InheritsInterface($interface, "Event")) {
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info());\n");
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::JSType(JSEventType), StructureFlags), info(), $indexingModeIncludingHistory);\n");
} else {
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());\n");
push(@headerContent, " return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), $indexingModeIncludingHistory);\n");
}
push(@headerContent, " }\n\n");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4169,12 +4169,21 @@ RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequ
windowRect.setX(*features.x);
if (features.y)
windowRect.setY(*features.y);
// Zero width and height mean using default size, not minumum one.
// Zero width and height mean using default size, not minimum one.
if (features.width && *features.width)
windowRect.setWidth(*features.width + (windowRect.width() - viewportSize.width()));
if (features.height && *features.height)
windowRect.setHeight(*features.height + (windowRect.height() - viewportSize.height()));

#if PLATFORM(GTK)
FloatRect oldWindowRect = oldPage->chrome().windowRect();
// Use the size of the previous window if there is no default size.
if (!windowRect.width())
windowRect.setWidth(oldWindowRect.width());
if (!windowRect.height())
windowRect.setHeight(oldWindowRect.height());
#endif

// Ensure non-NaN values, minimum size as well as being within valid screen area.
FloatRect newWindowRect = DOMWindow::adjustWindowRect(*page, windowRect);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ void ScrollingTreeScrollingNode::scrollTo(const FloatPoint& position, ScrollType
if (position == m_currentScrollPosition)
return;

if (scrollType == ScrollType::Programmatic)
stopScrollAnimations();

scrollingTree().setIsHandlingProgrammaticScroll(scrollType == ScrollType::Programmatic);

m_currentScrollPosition = adjustedScrollPosition(position, clamp);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,17 @@ class WEBCORE_EXPORT ScrollingTreeScrollingNode : public ScrollingTreeNode {
void scrollTo(const FloatPoint&, ScrollType = ScrollType::User, ScrollClamping = ScrollClamping::Clamped);
void scrollBy(const FloatSize&, ScrollClamping = ScrollClamping::Clamped);

virtual void stopScrollAnimations() { };

void wasScrolledByDelegatedScrolling(const FloatPoint& position, Optional<FloatRect> overrideLayoutViewport = { }, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync);

const FloatSize& scrollableAreaSize() const { return m_scrollableAreaSize; }
const FloatSize& totalContentsSize() const { return m_totalContentsSize; }

bool horizontalScrollbarHiddenByStyle() const { return m_scrollableAreaParameters.horizontalScrollbarHiddenByStyle; }
bool verticalScrollbarHiddenByStyle() const { return m_scrollableAreaParameters.verticalScrollbarHiddenByStyle; }
bool canHaveHorizontalScrollbar() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff; }
bool canHaveVerticalScrollbar() const { return m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; }
bool canHaveScrollbars() const { return m_scrollableAreaParameters.horizontalScrollbarMode != ScrollbarAlwaysOff || m_scrollableAreaParameters.verticalScrollbarMode != ScrollbarAlwaysOff; }

#if ENABLE(CSS_SCROLL_SNAP)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
#include "ScrollingStateFrameScrollingNode.h"
#include "ScrollingTree.h"

#if ENABLE(KINETIC_SCROLLING)
#include "ScrollAnimationKinetic.h"
#endif

namespace WebCore {

Ref<ScrollingTreeFrameScrollingNode> ScrollingTreeFrameScrollingNodeNicosia::create(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
Expand All @@ -47,6 +51,20 @@ Ref<ScrollingTreeFrameScrollingNode> ScrollingTreeFrameScrollingNodeNicosia::cre
ScrollingTreeFrameScrollingNodeNicosia::ScrollingTreeFrameScrollingNodeNicosia(ScrollingTree& scrollingTree, ScrollingNodeType nodeType, ScrollingNodeID nodeID)
: ScrollingTreeFrameScrollingNode(scrollingTree, nodeType, nodeID)
{
#if ENABLE(KINETIC_SCROLLING)
m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(
[this]() -> ScrollAnimationKinetic::ScrollExtents {
return { IntPoint(minimumScrollPosition()), IntPoint(maximumScrollPosition()) };
},
[this](FloatPoint&& position) {
auto* scrollLayer = static_cast<Nicosia::PlatformLayer*>(scrolledContentsLayer());
ASSERT(scrollLayer);
auto& compositionLayer = downcast<Nicosia::CompositionLayer>(*scrollLayer);

auto updateScope = compositionLayer.createUpdateScope();
scrollTo(position);
});
#endif
}

ScrollingTreeFrameScrollingNodeNicosia::~ScrollingTreeFrameScrollingNodeNicosia() = default;
Expand Down Expand Up @@ -108,14 +126,39 @@ ScrollingEventResult ScrollingTreeFrameScrollingNodeNicosia::handleWheelEvent(co

auto updateScope = compositionLayer.createUpdateScope();
scrollBy({ -wheelEvent.deltaX(), -wheelEvent.deltaY() });

}

#if ENABLE(KINETIC_SCROLLING)
m_kineticAnimation->appendToScrollHistory(wheelEvent);
#endif

#if ENABLE(KINETIC_SCROLLING)
m_kineticAnimation->stop();
if (wheelEvent.isEndOfNonMomentumScroll()) {
m_kineticAnimation->start(currentScrollPosition(), m_kineticAnimation->computeVelocity(), canHaveHorizontalScrollbar(), canHaveVerticalScrollbar());
m_kineticAnimation->clearScrollHistory();
}
if (wheelEvent.isTransitioningToMomentumScroll()) {
m_kineticAnimation->start(currentScrollPosition(), wheelEvent.swipeVelocity(), canHaveHorizontalScrollbar(), canHaveVerticalScrollbar());
m_kineticAnimation->clearScrollHistory();
}
#endif

scrollingTree().setOrClearLatchedNode(wheelEvent, scrollingNodeID());

// FIXME: This needs to return whether the event was handled.
return ScrollingEventResult::DidHandleEvent;
}

void ScrollingTreeFrameScrollingNodeNicosia::stopScrollAnimations()
{
#if ENABLE(KINETIC_SCROLLING)
m_kineticAnimation->stop();
m_kineticAnimation->clearScrollHistory();
#endif
}

FloatPoint ScrollingTreeFrameScrollingNodeNicosia::adjustedScrollPosition(const FloatPoint& position, ScrollClamping clamping) const
{
FloatPoint scrollPosition(roundf(position.x()), roundf(position.y()));
Expand Down
Loading