Commit 09d062a2 authored by Alberto Garcia's avatar Alberto Garcia
Browse files

New upstream version 2.29.92

parent 58bb4cee
......@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">JavaScriptCore GLib Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">for JavaScriptCore 2.29.91</p></div>
<div><p class="releaseinfo">for JavaScriptCore 2.29.92</p></div>
</div>
<hr>
</div>
......
......@@ -175,7 +175,7 @@ have included when compiling your code.</p>
<hr>
<div class="refsect2">
<a name="JSC-MICRO-VERSION:CAPS"></a><h3>JSC_MICRO_VERSION</h3>
<pre class="programlisting">#define JSC_MICRO_VERSION (91)
<pre class="programlisting">#define JSC_MICRO_VERSION (92)
</pre>
</div>
</div>
......
......@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">WebKitGTK Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">for WebKitGTK 2.29.91</p></div>
<div><p class="releaseinfo">for WebKitGTK 2.29.92</p></div>
</div>
<hr>
</div>
......
......@@ -213,7 +213,7 @@ against at application run time.</p>
<hr>
<div class="refsect2">
<a name="WEBKIT-MICRO-VERSION:CAPS"></a><h3>WEBKIT_MICRO_VERSION</h3>
<pre class="programlisting">#define WEBKIT_MICRO_VERSION (91)
<pre class="programlisting">#define WEBKIT_MICRO_VERSION (92)
</pre>
<p>Like <a class="link" href="webkit2gtk-4.0-WebKitVersion.html#webkit-get-micro-version" title="webkit_get_micro_version ()"><code class="function">webkit_get_micro_version()</code></a>, but from the headers used at
application compile time, rather than from the library linked
......
......@@ -14,7 +14,7 @@
<div class="titlepage">
<div>
<div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">WebKitDOMGTK+ Reference Manual</p></th></tr></table></div>
<div><p class="releaseinfo">for WebKitDOMGTK+ 2.29.91</p></div>
<div><p class="releaseinfo">for WebKitDOMGTK+ 2.29.92</p></div>
</div>
<hr>
</div>
......
=================
WebKitGTK 2.29.92
=================
What's new in WebKitGTK 2.29.92?
- Fix user agent header after a redirect when a new quirk is required.
- Stop using firefox user agent quirk for google docs.
- Fix rendering frames timeline panel in web inspector.
- Fix per-thread cpu usage in web inspector.
- Fix several crashes and rendering issues.
- Translation updates: Polish
=================
WebKitGTK 2.29.91
=================
......
......@@ -1010,7 +1010,7 @@ JSCValue* jsc_value_object_invoke_methodv(JSCValue* value, const char* name, uns
auto result = jsObjectCall(jsContext, function, JSC::JSCCallbackFunction::Type::Method, object, arguments, &exception);
if (jscContextHandleExceptionIfNeeded(priv->context.get(), exception))
jsc_value_new_undefined(priv->context.get());
return jsc_value_new_undefined(priv->context.get());
return jscContextGetOrCreateValue(priv->context.get(), result).leakRef();
}
......
......@@ -78,6 +78,7 @@ struct RegisterState {
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
......@@ -92,6 +93,7 @@ struct RegisterState {
SAVE_REG(r4, registers.r4); \
SAVE_REG(r5, registers.r5); \
SAVE_REG(r6, registers.r6); \
SAVE_REG(r7, registers.r7); \
SAVE_REG(r8, registers.r8); \
SAVE_REG(r9, registers.r9); \
SAVE_REG(r10, registers.r10); \
......
......@@ -1141,15 +1141,10 @@ void SamplingProfiler::reportTopBytecodes(PrintStream& out)
}
}
#if OS(DARWIN)
mach_port_t SamplingProfiler::machThread()
Thread* SamplingProfiler::thread() const
{
if (!m_thread)
return MACH_PORT_NULL;
return m_thread->machThread();
return m_thread.get();
}
#endif
} // namespace JSC
......
......@@ -193,9 +193,7 @@ public:
JS_EXPORT_PRIVATE void reportTopBytecodes();
JS_EXPORT_PRIVATE void reportTopBytecodes(PrintStream&);
#if OS(DARWIN)
JS_EXPORT_PRIVATE mach_port_t machThread();
#endif
JS_EXPORT_PRIVATE Thread* thread() const;
private:
void createThreadIfNecessary(const AbstractLocker&);
......
......@@ -32,9 +32,11 @@
#include <wtf/Forward.h>
#include <wtf/FunctionDispatcher.h>
#include <wtf/HashMap.h>
#include <wtf/Observer.h>
#include <wtf/RetainPtr.h>
#include <wtf/Seconds.h>
#include <wtf/ThreadingPrimitives.h>
#include <wtf/WeakHashSet.h>
#include <wtf/text/WTFString.h>
#if USE(CF)
......@@ -96,6 +98,9 @@ public:
#if USE(GLIB_EVENT_LOOP)
WTF_EXPORT_PRIVATE GMainContext* mainContext() const { return m_mainContext.get(); }
enum class Event { WillDispatch, DidDispatch };
using Observer = WTF::Observer<void(Event, const String&)>;
WTF_EXPORT_PRIVATE void observe(const Observer&);
#endif
#if USE(GENERIC_EVENT_LOOP) || USE(WINDOWS_EVENT_LOOP)
......@@ -221,9 +226,13 @@ private:
RetainPtr<CFRunLoopRef> m_runLoop;
RetainPtr<CFRunLoopSourceRef> m_runLoopSource;
#elif USE(GLIB_EVENT_LOOP)
void notify(Event, const char*);
static GSourceFuncs s_runLoopSourceFunctions;
GRefPtr<GMainContext> m_mainContext;
Vector<GRefPtr<GMainLoop>> m_mainLoops;
GRefPtr<GSource> m_source;
WeakHashSet<Observer> m_observers;
#elif USE(GENERIC_EVENT_LOOP)
void schedule(Ref<TimerBase::ScheduledTask>&&);
void schedule(const AbstractLocker&, Ref<TimerBase::ScheduledTask>&&);
......
......@@ -138,6 +138,10 @@ void Thread::initializeInThread()
m_currentAtomStringTable = &sharedStringTable.get();
}
#endif
#if OS(LINUX)
m_id = currentID();
#endif
}
void Thread::entryPoint(NewThreadContext* newThreadContext)
......
......@@ -157,6 +157,10 @@ public:
WTF_EXPORT_PRIVATE size_t getRegisters(PlatformRegisters&);
#if USE(PTHREADS)
#if OS(LINUX)
WTF_EXPORT_PRIVATE static ThreadIdentifier currentID();
ThreadIdentifier id() const { return m_id; }
#endif
WTF_EXPORT_PRIVATE bool signal(int signalNumber);
#endif
......@@ -329,6 +333,9 @@ protected:
#elif OS(DARWIN)
mach_port_t m_platformThread { MACH_PORT_NULL };
#elif USE(PTHREADS)
#if OS(LINUX)
ThreadIdentifier m_id { 0 };
#endif
PlatformRegisters* m_platformRegisters { nullptr };
unsigned m_suspendCount { 0 };
#endif
......
......@@ -57,6 +57,9 @@ using PlatformThreadHandle = pthread_t;
using PlatformMutex = pthread_mutex_t;
using PlatformCondition = pthread_cond_t;
using ThreadSpecificKey = pthread_key_t;
#if OS(LINUX)
using ThreadIdentifier = pid_t;
#endif
#elif OS(WINDOWS)
using ThreadIdentifier = uint32_t;
using PlatformThreadHandle = HANDLE;
......
......@@ -33,7 +33,12 @@
namespace WTF {
static GSourceFuncs runLoopSourceFunctions = {
typedef struct {
GSource source;
RunLoop* runLoop;
} RunLoopSource;
GSourceFuncs RunLoop::s_runLoopSourceFunctions = {
nullptr, // prepare
nullptr, // check
// dispatch
......@@ -42,7 +47,12 @@ static GSourceFuncs runLoopSourceFunctions = {
if (g_source_get_ready_time(source) == -1)
return G_SOURCE_CONTINUE;
g_source_set_ready_time(source, -1);
return callback(userData);
const char* name = g_source_get_name(source);
auto& runLoopSource = *reinterpret_cast<RunLoopSource*>(source);
runLoopSource.runLoop->notify(RunLoop::Event::WillDispatch, name);
auto returnValue = callback(userData);
runLoopSource.runLoop->notify(RunLoop::Event::DidDispatch, name);
return returnValue;
},
nullptr, // finalize
nullptr, // closure_callback
......@@ -60,7 +70,9 @@ RunLoop::RunLoop()
ASSERT(innermostLoop);
m_mainLoops.append(innermostLoop);
m_source = adoptGRef(g_source_new(&runLoopSourceFunctions, sizeof(GSource)));
m_source = adoptGRef(g_source_new(&RunLoop::s_runLoopSourceFunctions, sizeof(RunLoopSource)));
auto& runLoopSource = *reinterpret_cast<RunLoopSource*>(m_source.get());
runLoopSource.runLoop = this;
g_source_set_priority(m_source.get(), RunLoopSourcePriority::RunLoopDispatcher);
g_source_set_name(m_source.get(), "[WebKit] RunLoop work");
g_source_set_can_recurse(m_source.get(), TRUE);
......@@ -129,10 +141,29 @@ RunLoop::CycleResult RunLoop::cycle(RunLoopMode)
return CycleResult::Continue;
}
void RunLoop::observe(const RunLoop::Observer& observer)
{
ASSERT(!m_observers.contains(observer));
m_observers.add(observer);
}
void RunLoop::notify(RunLoop::Event event, const char* name)
{
if (m_observers.computesEmpty())
return;
m_observers.forEach([event, name = String::fromUTF8(name)](auto& observer) {
observer(event, name);
});
}
RunLoop::TimerBase::TimerBase(RunLoop& runLoop)
: m_runLoop(runLoop)
, m_source(adoptGRef(g_source_new(&runLoopSourceFunctions, sizeof(GSource))))
, m_source(adoptGRef(g_source_new(&RunLoop::s_runLoopSourceFunctions, sizeof(RunLoopSource))))
{
auto& runLoopSource = *reinterpret_cast<RunLoopSource*>(m_source.get());
runLoopSource.runLoop = m_runLoop.ptr();
g_source_set_priority(m_source.get(), RunLoopSourcePriority::RunLoopTimer);
g_source_set_name(m_source.get(), "[WebKit] RunLoop::Timer work");
g_source_set_callback(m_source.get(), [](gpointer userData) -> gboolean {
......
......@@ -68,6 +68,10 @@
#include <mach/thread_switch.h>
#endif
#if OS(LINUX)
#include <sys/syscall.h>
#endif
namespace WTF {
static Lock globalSuspendLock;
......@@ -187,6 +191,13 @@ void Thread::initializePlatformThreading()
#endif
}
#if OS(LINUX)
ThreadIdentifier Thread::currentID()
{
return static_cast<ThreadIdentifier>(syscall(SYS_gettid));
}
#endif
void Thread::initializeCurrentThreadEvenIfNonWTFCreated()
{
#if !OS(DARWIN)
......
......@@ -2171,6 +2171,7 @@ rendering/RenderTextFragment.cpp
rendering/RenderTextLineBoxes.cpp
rendering/RenderTheme.cpp
rendering/RenderTreeAsText.cpp
rendering/RenderTreeMutationDisallowedScope.cpp
rendering/RenderVTTCue.cpp
rendering/RenderVideo.cpp
rendering/RenderView.cpp
......
......@@ -57,6 +57,13 @@ Ref<JSON::Object> TimelineRecordFactory::createGenericRecord(double startTime, i
return record;
}
Ref<JSON::Object> TimelineRecordFactory::createRenderingFrameData(const String& name)
{
Ref<JSON::Object> data = JSON::Object::create();
data->setString("name"_s, name);
return data;
}
Ref<JSON::Object> TimelineRecordFactory::createFunctionCallData(const String& scriptName, int scriptLine, int scriptColumn)
{
Ref<JSON::Object> data = JSON::Object::create();
......
......@@ -49,6 +49,7 @@ class TimelineRecordFactory {
public:
static Ref<JSON::Object> createGenericRecord(double startTime, int maxCallStackDepth);
static Ref<JSON::Object> createRenderingFrameData(const String& name);
static Ref<JSON::Object> createFunctionCallData(const String& scriptName, int scriptLine, int scriptColumn);
static Ref<JSON::Object> createConsoleProfileData(const String& title);
static Ref<JSON::Object> createProbeSampleData(const Inspector::ScriptBreakpointAction&, unsigned sampleId);
......
......@@ -226,6 +226,21 @@ void InspectorTimelineAgent::internalStart(const int* maxCallStackDepth)
pushCurrentRecord(JSON::Object::create(), TimelineRecordType::RenderingFrame, false, nullptr);
m_runLoopNestingLevel = 1;
#elif USE(GLIB_EVENT_LOOP)
m_runLoopObserver = makeUnique<RunLoop::Observer>([this](RunLoop::Event event, const String& name) {
if (!m_tracking || m_environment.scriptDebugServer().isPaused())
return;
switch (event) {
case RunLoop::Event::WillDispatch:
pushCurrentRecord(TimelineRecordFactory::createRenderingFrameData(name), TimelineRecordType::RenderingFrame, false, nullptr);
break;
case RunLoop::Event::DidDispatch:
didCompleteCurrentRecord(TimelineRecordType::RenderingFrame);
break;
}
});
RunLoop::current().observe(*m_runLoopObserver);
#endif
m_frontendDispatcher->recordingStarted(timestamp());
......@@ -247,11 +262,13 @@ void InspectorTimelineAgent::internalStop()
m_frameStartObserver = nullptr;
m_frameStopObserver = nullptr;
m_runLoopNestingLevel = 0;
#elif USE(GLIB_EVENT_LOOP)
m_runLoopObserver = nullptr;
#endif
// Complete all pending records to prevent discarding events that are currently in progress.
while (!m_recordStack.isEmpty())
didCompleteCurrentRecord(m_recordStack.last().type);
#endif
m_recordStack.clear();
......
......@@ -38,6 +38,7 @@
#include <JavaScriptCore/InspectorFrontendDispatchers.h>
#include <JavaScriptCore/ScriptDebugListener.h>
#include <wtf/JSONValues.h>
#include <wtf/RunLoop.h>
#include <wtf/Vector.h>
namespace WebCore {
......@@ -223,8 +224,10 @@ private:
#if PLATFORM(COCOA)
std::unique_ptr<WebCore::RunLoopObserver> m_frameStartObserver;
std::unique_ptr<WebCore::RunLoopObserver> m_frameStopObserver;
#endif
int m_runLoopNestingLevel { 0 };
#elif USE(GLIB_EVENT_LOOP)
std::unique_ptr<RunLoop::Observer> m_runLoopObserver;
#endif
bool m_startedComposite { false };
};
......
......@@ -88,8 +88,12 @@ private:
// They should ensure their use of the VM is thread safe.
JSC::VM* m_vm { nullptr };
#if ENABLE(SAMPLING_PROFILER) && OS(DARWIN)
#if ENABLE(SAMPLING_PROFILER)
#if OS(DARWIN)
mach_port_t m_samplingProfilerMachThread { MACH_PORT_NULL };
#elif OS(LINUX)
pid_t m_samplingProfilerThreadID { 0 };
#endif
#endif
};
......
/*
* Copyright (C) 2017 Igalia S.L.
* Copyright (C) 2017, 2020 Igalia S.L.
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -29,7 +29,9 @@
#if ENABLE(RESOURCE_USAGE) && OS(LINUX)
#include "WorkerThread.h"
#include <JavaScriptCore/GCActivityCallback.h>
#include <JavaScriptCore/SamplingProfiler.h>
#include <JavaScriptCore/VM.h>
#include <errno.h>
#include <fcntl.h>
......@@ -38,6 +40,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wtf/Threading.h>
#include <wtf/linux/CurrentProcessMemoryStatus.h>
namespace WebCore {
......@@ -90,15 +93,41 @@ static float cpuPeriod()
return static_cast<float>(period) / cpuCount;
}
static float cpuUsage()
void ResourceUsageThread::platformSaveStateBeforeStarting()
{
float period = cpuPeriod();
if (!period)
return -1;
#if ENABLE(SAMPLING_PROFILER)
m_samplingProfilerThreadID = 0;
if (auto* profiler = m_vm->samplingProfiler()) {
if (auto* thread = profiler->thread())
m_samplingProfilerThreadID = thread->id();
}
#endif
}
int fd = open("/proc/self/stat", O_RDONLY);
struct ThreadInfo {
Optional<String> name;
Optional<float> cpuUsage;
unsigned long long previousUtime { 0 };
unsigned long long previousStime { 0 };
};
static HashMap<pid_t, ThreadInfo>& threadInfoMap()
{
static LazyNeverDestroyed<HashMap<pid_t, ThreadInfo>> map;
static std::once_flag flag;
std::call_once(flag, [&] {
map.construct();
});
return map;
}
static bool threadCPUUsage(pid_t id, float period, ThreadInfo& info)
{
String path = makeString("/proc/self/task/", id, "/stat");
int fd = open(path.utf8().data(), O_RDONLY);
if (fd < 0)
return -1;
return false;
static const ssize_t maxBufferLength = BUFSIZ - 1;
char buffer[BUFSIZ];
......@@ -110,7 +139,7 @@ static float cpuUsage()
if (bytesRead < 0) {
if (errno != EINTR) {
close(fd);
return -1;
return false;
}
continue;
}
......@@ -123,10 +152,18 @@ static float cpuUsage()
close(fd);
buffer[totalBytesRead] = '\0';
// Skip pid and process name.
char* position = strrchr(buffer, ')');
// Skip tid and name.
char* position = strchr(buffer, ')');
if (!position)
return -1;
return false;
if (!info.name) {
char* name = strchr(buffer, '(');
if (!name)
return false;
name++;
info.name = String::fromUTF8(name, position - name);
}
// Move after state.
position += 4;
......@@ -139,29 +176,130 @@ static float cpuUsage()
position++;
}
static unsigned long long previousUtime = 0;
static unsigned long long previousStime = 0;
unsigned long long utime = strtoull(position, &position, 10);
unsigned long long stime = strtoull(position, &position, 10);
float usage = (utime + stime - (previousUtime + previousStime)) / period * 100.0;
previousUtime = utime;
previousStime = stime;
float usage = (utime + stime - (info.previousUtime + info.previousStime)) / period * 100.0;
info.previousUtime = utime;
info.previousStime = stime;
return clampTo<float>(usage, 0, 100);
info.cpuUsage = clampTo<float>(usage, 0, 100);
return true;
}
void ResourceUsageThread::platformSaveStateBeforeStarting()
static void collectCPUUsage(float period)
{
DIR* dir = opendir("/proc/self/task");
if (!dir) {
threadInfoMap().clear();
return;
}
HashSet<pid_t> previousTasks;
for (const auto& key : threadInfoMap().keys())
previousTasks.add(key);
struct dirent* dp;
while ((dp = readdir(dir))) {
String name = String::fromUTF8(dp->d_name);
if (name == "." || name == "..")
continue;
bool ok;
pid_t id = name.toIntStrict(&ok);
if (!ok)
continue;
auto& info = threadInfoMap().add(id, ThreadInfo()).iterator->value;
if (!threadCPUUsage(id, period, info))
threadInfoMap().remove(id);
previousTasks.remove(id);
}
closedir(dir);
threadInfoMap().removeIf([&](auto& entry) {
return previousTasks.contains(entry.key);
});
}
void ResourceUsageThread::platformCollectCPUData(JSC::VM*, ResourceUsageData& data)
{
data.cpu = cpuUsage();
float period = cpuPeriod();
if (!period) {
data.cpu = 0;
data.cpuExcludingDebuggerThreads = 0;
return;
}
collectCPUUsage(period);
pid_t resourceUsageThreadID = Thread::currentID();
HashSet<pid_t> knownWebKitThreads;
{
auto locker = holdLock(Thread::allThreadsMutex());
for (auto* thread : Thread::allThreads(locker)) {
if (auto id = thread->id())
knownWebKitThreads.add(id);
}
}