mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team a=merge
This commit is contained in:
commit
57cb26988c
@ -15,9 +15,9 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
|
@ -19,8 +19,8 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a89cebcccc1e067ebdb71a93194f4ee79d71bd69"/>
|
||||
|
@ -17,8 +17,8 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
|
@ -15,9 +15,9 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
|
@ -15,9 +15,9 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
|
@ -19,8 +19,8 @@
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
|
||||
<project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="a89cebcccc1e067ebdb71a93194f4ee79d71bd69"/>
|
||||
|
@ -15,9 +15,9 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
|
@ -17,8 +17,8 @@
|
||||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"git": {
|
||||
"git_revision": "a290b11627ec2b7c25980f5687a98da86641cfe4",
|
||||
"git_revision": "5dfd0460eb6e616205154b0d219aa5123bf1abb3",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "dbc540265f837510772bbcfdc7e9181b280b2551",
|
||||
"revision": "d8cd51229d334a6e9ae46951a7e0555a01d0cb1c",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
@ -17,8 +17,8 @@
|
||||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="1b1d86462d3150dceacff927536ded9fcc168419"/>
|
||||
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
|
||||
|
@ -15,9 +15,9 @@
|
||||
<project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a290b11627ec2b7c25980f5687a98da86641cfe4"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="5dfd0460eb6e616205154b0d219aa5123bf1abb3"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="d36455f7defa176797ef5aaf894fe99307081542"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
|
@ -432,12 +432,40 @@ private:
|
||||
WebSocketImpl* mImpl;
|
||||
};
|
||||
|
||||
class CloseConnectionRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
CloseConnectionRunnable(WebSocketImpl* aImpl,
|
||||
uint16_t aReasonCode,
|
||||
const nsACString& aReasonString)
|
||||
: mImpl(aImpl)
|
||||
, mReasonCode(aReasonCode)
|
||||
, mReasonString(aReasonString)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
return mImpl->CloseConnection(mReasonCode, mReasonString);
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<WebSocketImpl> mImpl;
|
||||
uint16_t mReasonCode;
|
||||
const nsCString mReasonString;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
nsresult
|
||||
WebSocketImpl::CloseConnection(uint16_t aReasonCode,
|
||||
const nsACString& aReasonString)
|
||||
{
|
||||
if (!IsTargetThread()) {
|
||||
nsRefPtr<nsRunnable> runnable =
|
||||
new CloseConnectionRunnable(this, aReasonCode, aReasonString);
|
||||
return Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
AssertIsOnTargetThread();
|
||||
|
||||
if (mDisconnectingOrDisconnected) {
|
||||
@ -471,7 +499,6 @@ WebSocketImpl::CloseConnection(uint16_t aReasonCode,
|
||||
}
|
||||
|
||||
// No channel, but not disconnected: canceled or failed early
|
||||
//
|
||||
MOZ_ASSERT(readyState == WebSocket::CONNECTING,
|
||||
"Should only get here for early websocket cancel/error");
|
||||
|
||||
@ -622,10 +649,12 @@ WebSocketImpl::DisconnectInternal()
|
||||
mWeakLoadGroup = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC);
|
||||
os->RemoveObserver(this, DOM_WINDOW_FROZEN_TOPIC);
|
||||
if (!mWorkerPrivate) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
os->RemoveObserver(this, DOM_WINDOW_DESTROYED_TOPIC);
|
||||
os->RemoveObserver(this, DOM_WINDOW_FROZEN_TOPIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ class nsNPAPIPluginInstance;
|
||||
* interface to mirror this interface when changing it.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(16c14177-52eb-49d3-9842-a1a0b92be11a)]
|
||||
[scriptable, uuid(5efbd411-5bbe-4de1-9f3a-1c3459696eb2)]
|
||||
interface nsIObjectLoadingContent : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -188,4 +188,12 @@ interface nsIObjectLoadingContent : nsISupports
|
||||
* This method will disable the play-preview plugin state.
|
||||
*/
|
||||
void cancelPlayPreview();
|
||||
|
||||
/**
|
||||
* If this plugin runs out-of-process, it has a runID to differentiate
|
||||
* between different times the plugin process has been instantiated.
|
||||
*
|
||||
* This throws NS_ERROR_NOT_IMPLEMENTED for in-process plugins.
|
||||
*/
|
||||
readonly attribute unsigned long runID;
|
||||
};
|
||||
|
@ -701,6 +701,8 @@ nsObjectLoadingContent::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
nsObjectLoadingContent::nsObjectLoadingContent()
|
||||
: mType(eType_Loading)
|
||||
, mFallbackType(eFallbackAlternate)
|
||||
, mRunID(0)
|
||||
, mHasRunID(false)
|
||||
, mChannelLoaded(false)
|
||||
, mInstantiating(false)
|
||||
, mNetworkCreated(true)
|
||||
@ -815,6 +817,17 @@ nsObjectLoadingContent::InstantiatePluginInstance(bool aIsLoading)
|
||||
|
||||
mInstanceOwner = newOwner;
|
||||
|
||||
if (mInstanceOwner) {
|
||||
nsRefPtr<nsNPAPIPluginInstance> inst;
|
||||
rv = mInstanceOwner->GetInstance(getter_AddRefs(inst));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = inst->GetRunID(&mRunID);
|
||||
mHasRunID = NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
// Ensure the frame did not change during instantiation re-entry (common).
|
||||
// HasNewFrame would not have mInstanceOwner yet, so the new frame would be
|
||||
// dangling. (Bug 854082)
|
||||
@ -3145,6 +3158,24 @@ nsObjectLoadingContent::CancelPlayPreview()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::GetRunID(uint32_t* aRunID)
|
||||
{
|
||||
if (NS_WARN_IF(!nsContentUtils::IsCallerChrome())) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
if (NS_WARN_IF(!aRunID)) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
if (!mHasRunID) {
|
||||
// The plugin instance must not have a run ID, so we must
|
||||
// be running the plugin in-process.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
*aRunID = mRunID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool sPrefsInitialized;
|
||||
static uint32_t sSessionTimeoutMinutes;
|
||||
static uint32_t sPersistentTimeoutDays;
|
||||
|
@ -233,6 +233,18 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
uint32_t GetRunID(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
uint32_t runID;
|
||||
nsresult rv = GetRunID(&runID);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return runID;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Begins loading the object when called
|
||||
@ -579,6 +591,9 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
// The type of fallback content we're showing (see ObjectState())
|
||||
FallbackType mFallbackType : 8;
|
||||
|
||||
uint32_t mRunID;
|
||||
bool mHasRunID;
|
||||
|
||||
// If true, we have opened a channel as the listener and it has reached
|
||||
// OnStartRequest. Does not get set for channels that are passed directly to
|
||||
// the plugin listener.
|
||||
|
@ -1022,17 +1022,21 @@ ContentParent::RecvGetGMPPluginVersionForAPI(const nsCString& aAPI,
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv)
|
||||
ContentParent::RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID)
|
||||
{
|
||||
*aRv = NS_OK;
|
||||
return mozilla::plugins::SetupBridge(aPluginId, this, false, aRv);
|
||||
return mozilla::plugins::SetupBridge(aPluginId, this, false, aRv, aRunID);
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv)
|
||||
{
|
||||
*aRv = NS_OK;
|
||||
return mozilla::plugins::SetupBridge(aPluginId, this, true, aRv);
|
||||
// We don't need to get the run ID for the plugin, since we already got it
|
||||
// in the first call to SetupBridge in RecvLoadPlugin, so we pass in a dummy
|
||||
// pointer and just throw it away.
|
||||
uint32_t dummy = 0;
|
||||
return mozilla::plugins::SetupBridge(aPluginId, this, true, aRv, &dummy);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -174,7 +174,7 @@ public:
|
||||
bool* aHasPlugin,
|
||||
nsCString* aVersion) override;
|
||||
|
||||
virtual bool RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv) override;
|
||||
virtual bool RecvLoadPlugin(const uint32_t& aPluginId, nsresult* aRv, uint32_t* aRunID) override;
|
||||
virtual bool RecvConnectPluginBridge(const uint32_t& aPluginId, nsresult* aRv) override;
|
||||
virtual bool RecvFindPlugins(const uint32_t& aPluginEpoch,
|
||||
nsTArray<PluginTag>* aPlugins,
|
||||
|
@ -341,6 +341,14 @@ parent:
|
||||
*/
|
||||
sync SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint);
|
||||
|
||||
/**
|
||||
* Returns the offset of this tab from the top level window
|
||||
* origin in device pixels.
|
||||
*
|
||||
* aPoint offset values in device pixels.
|
||||
*/
|
||||
sync GetTabOffset() returns (LayoutDeviceIntPoint aPoint);
|
||||
|
||||
/**
|
||||
* Gets the DPI of the screen corresponding to this browser.
|
||||
*/
|
||||
|
@ -633,7 +633,7 @@ parent:
|
||||
* via bridging. The corresponding PluginModuleChild will live in the plugin
|
||||
* process.
|
||||
*/
|
||||
sync LoadPlugin(uint32_t pluginId) returns (nsresult rv);
|
||||
sync LoadPlugin(uint32_t aPluginId) returns (nsresult aResult, uint32_t aRunID);
|
||||
|
||||
/**
|
||||
* This call is used by asynchronous plugin instantiation to notify the
|
||||
|
@ -1776,6 +1776,13 @@ TabParent::RecvEnableDisableCommands(const nsString& aAction,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvGetTabOffset(LayoutDeviceIntPoint* aPoint)
|
||||
{
|
||||
*aPoint = GetChildProcessOffset();
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TabParent::GetChildProcessOffset(int32_t* aOutCssX, int32_t* aOutCssY)
|
||||
{
|
||||
|
@ -201,6 +201,7 @@ public:
|
||||
virtual bool RecvSynthesizeNativeMouseMove(const mozilla::LayoutDeviceIntPoint& aPoint) override;
|
||||
virtual bool RecvShowTooltip(const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip) override;
|
||||
virtual bool RecvHideTooltip() override;
|
||||
virtual bool RecvGetTabOffset(LayoutDeviceIntPoint* aPoint) override;
|
||||
virtual bool RecvGetDPI(float* aValue) override;
|
||||
virtual bool RecvGetDefaultScale(double* aValue) override;
|
||||
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
|
||||
|
@ -243,8 +243,8 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
ConversionRequired
|
||||
DecoderNeedsConversion(const mp4_demuxer::TrackConfig& aConfig) const
|
||||
virtual ConversionRequired
|
||||
DecoderNeedsConversion(const mp4_demuxer::TrackConfig& aConfig) const override
|
||||
{
|
||||
return kNeedNone;
|
||||
}
|
||||
|
@ -122,6 +122,7 @@ public:
|
||||
virtual nsresult EndUpdateBackground(NPP instance,
|
||||
gfxContext* aCtx, const nsIntRect&) override;
|
||||
virtual void GetLibraryPath(nsACString& aPath) { aPath.Assign(mFilePath); }
|
||||
virtual nsresult GetRunID(uint32_t* aRunID) override { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
private:
|
||||
NP_InitializeFunc mNP_Initialize;
|
||||
|
@ -1778,3 +1778,22 @@ nsNPAPIPluginInstance::GetContentsScaleFactor()
|
||||
}
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNPAPIPluginInstance::GetRunID(uint32_t* aRunID)
|
||||
{
|
||||
if (NS_WARN_IF(!aRunID)) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!mPlugin)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PluginLibrary* library = mPlugin->GetLibrary();
|
||||
if (!library) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return library->GetRunID(aRunID);
|
||||
}
|
||||
|
@ -286,6 +286,8 @@ public:
|
||||
// Returns the contents scale factor of the screen the plugin is drawn on.
|
||||
double GetContentsScaleFactor();
|
||||
|
||||
nsresult GetRunID(uint32_t *aRunID);
|
||||
|
||||
static bool InPluginCallUnsafeForReentry() { return gInUnsafePluginCalls > 0; }
|
||||
static void BeginPluginCall(NSPluginCallReentry aReentryState)
|
||||
{
|
||||
|
@ -3773,6 +3773,7 @@ nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin,
|
||||
const nsAString& browserDumpID)
|
||||
{
|
||||
nsPluginTag* crashedPluginTag = TagForPlugin(aPlugin);
|
||||
MOZ_ASSERT(crashedPluginTag);
|
||||
|
||||
// Notify the app's observer that a plugin crashed so it can submit
|
||||
// a crashreport.
|
||||
@ -3782,6 +3783,18 @@ nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin,
|
||||
nsCOMPtr<nsIWritablePropertyBag2> propbag =
|
||||
do_CreateInstance("@mozilla.org/hash-property-bag;1");
|
||||
if (obsService && propbag) {
|
||||
uint32_t runID = 0;
|
||||
PluginLibrary* library = aPlugin->GetLibrary();
|
||||
|
||||
if (!NS_WARN_IF(!library)) {
|
||||
library->GetRunID(&runID);
|
||||
}
|
||||
propbag->SetPropertyAsUint32(NS_LITERAL_STRING("runID"), runID);
|
||||
|
||||
nsCString pluginName;
|
||||
crashedPluginTag->GetName(pluginName);
|
||||
propbag->SetPropertyAsAString(NS_LITERAL_STRING("pluginName"),
|
||||
NS_ConvertUTF8toUTF16(pluginName));
|
||||
propbag->SetPropertyAsAString(NS_LITERAL_STRING("pluginDumpID"),
|
||||
pluginDumpID);
|
||||
propbag->SetPropertyAsAString(NS_LITERAL_STRING("browserDumpID"),
|
||||
|
@ -17,7 +17,7 @@ namespace plugins {
|
||||
|
||||
bool
|
||||
SetupBridge(uint32_t aPluginId, dom::ContentParent* aContentParent,
|
||||
bool aForceBridgeNow, nsresult* rv);
|
||||
bool aForceBridgeNow, nsresult* aResult, uint32_t* aRunID);
|
||||
|
||||
bool
|
||||
FindPluginsForContent(uint32_t aPluginEpoch,
|
||||
|
@ -84,6 +84,7 @@ public:
|
||||
const nsIntRect&, gfxContext**) = 0;
|
||||
virtual nsresult EndUpdateBackground(NPP instance,
|
||||
gfxContext*, const nsIntRect&) = 0;
|
||||
virtual nsresult GetRunID(uint32_t* aRunID) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -96,8 +96,13 @@ bool
|
||||
mozilla::plugins::SetupBridge(uint32_t aPluginId,
|
||||
dom::ContentParent* aContentParent,
|
||||
bool aForceBridgeNow,
|
||||
nsresult* rv)
|
||||
nsresult* rv,
|
||||
uint32_t* runID)
|
||||
{
|
||||
if (NS_WARN_IF(!rv) || NS_WARN_IF(!runID)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PluginModuleChromeParent::ClearInstantiationFlag();
|
||||
nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
|
||||
nsRefPtr<nsNPAPIPlugin> plugin;
|
||||
@ -106,6 +111,10 @@ mozilla::plugins::SetupBridge(uint32_t aPluginId,
|
||||
return true;
|
||||
}
|
||||
PluginModuleChromeParent* chromeParent = static_cast<PluginModuleChromeParent*>(plugin->GetLibrary());
|
||||
*rv = chromeParent->GetRunID(runID);
|
||||
if (NS_FAILED(*rv)) {
|
||||
return true;
|
||||
}
|
||||
chromeParent->SetContentParent(aContentParent);
|
||||
if (!aForceBridgeNow && chromeParent->IsStartingAsync() &&
|
||||
PluginModuleChromeParent::DidInstantiate()) {
|
||||
@ -365,7 +374,8 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId)
|
||||
*/
|
||||
dom::ContentChild* cp = dom::ContentChild::GetSingleton();
|
||||
nsresult rv;
|
||||
if (!cp->SendLoadPlugin(aPluginId, &rv) ||
|
||||
uint32_t runID;
|
||||
if (!cp->SendLoadPlugin(aPluginId, &rv, &runID) ||
|
||||
NS_FAILED(rv)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -381,6 +391,7 @@ PluginModuleContentParent::LoadModule(uint32_t aPluginId)
|
||||
}
|
||||
|
||||
parent->mPluginId = aPluginId;
|
||||
parent->mRunID = runID;
|
||||
|
||||
return parent;
|
||||
}
|
||||
@ -644,6 +655,10 @@ PluginModuleContentParent::~PluginModuleContentParent()
|
||||
Preferences::UnregisterCallback(TimeoutChanged, kContentTimeoutPref, this);
|
||||
}
|
||||
|
||||
// We start the Run IDs at 1 so that we can use 0 as a way of detecting
|
||||
// errors in retrieving the run ID.
|
||||
uint32_t PluginModuleChromeParent::sNextRunID = 1;
|
||||
|
||||
bool PluginModuleChromeParent::sInstantiated = false;
|
||||
|
||||
PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId)
|
||||
@ -675,6 +690,7 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32
|
||||
{
|
||||
NS_ASSERTION(mSubprocess, "Out of memory!");
|
||||
sInstantiated = true;
|
||||
mRunID = sNextRunID++;
|
||||
|
||||
RegisterSettingsCallbacks();
|
||||
|
||||
@ -1499,6 +1515,16 @@ PluginModuleParent::ActorDestroy(ActorDestroyReason why)
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
PluginModuleParent::GetRunID(uint32_t* aRunID)
|
||||
{
|
||||
if (NS_WARN_IF(!aRunID)) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
*aRunID = mRunID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PluginModuleChromeParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
|
@ -128,6 +128,8 @@ public:
|
||||
return mPluginName + mPluginVersion;
|
||||
}
|
||||
|
||||
virtual nsresult GetRunID(uint32_t* aRunID) override;
|
||||
|
||||
protected:
|
||||
virtual mozilla::ipc::RacyInterruptPolicy
|
||||
MediateInterruptRace(const Message& parent, const Message& child) override
|
||||
@ -305,6 +307,7 @@ protected:
|
||||
bool mNPInitialized;
|
||||
nsTArray<nsRefPtr<PluginAsyncSurrogate>> mSurrogateInstances;
|
||||
nsresult mAsyncNewRv;
|
||||
uint32_t mRunID;
|
||||
};
|
||||
|
||||
class PluginModuleContentParent : public PluginModuleParent
|
||||
@ -551,6 +554,7 @@ private:
|
||||
dom::ContentParent* mContentParent;
|
||||
nsCOMPtr<nsIObserver> mOfflineObserver;
|
||||
bool mIsBlocklisted;
|
||||
static uint32_t sNextRunID;
|
||||
static bool sInstantiated;
|
||||
};
|
||||
|
||||
|
@ -211,6 +211,9 @@ interface MozObjectLoadingContent {
|
||||
*/
|
||||
[ChromeOnly, Throws]
|
||||
void cancelPlayPreview();
|
||||
|
||||
[ChromeOnly, Throws]
|
||||
readonly attribute unsigned long runID;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,7 @@
|
||||
onconnect = function(evt) {
|
||||
var blob = new Blob(['123'], { type: 'text/plain' });
|
||||
var url = URL.createObjectURL(blob);
|
||||
evt.ports[0].postMessage('alive \\o/');
|
||||
evt.ports[0].onmessage = function(e) {
|
||||
var blob = new Blob(['123'], { type: 'text/plain' });
|
||||
var url = URL.createObjectURL(blob);
|
||||
evt.ports[0].postMessage('alive \\o/');
|
||||
};
|
||||
}
|
||||
|
@ -16,9 +16,11 @@
|
||||
SpecialPowers.pushPrefEnv({ set: [["dom.workers.sharedWorkers.enabled", true]] }, function() {
|
||||
var sw = new SharedWorker('bug1132395_sharedWorker.js');
|
||||
sw.port.onmessage = function(event) {
|
||||
ok(true, "We didn't crash.");
|
||||
ok(true, "We didn't crash.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
sw.port.postMessage('go');
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "HwcComposer2D.h"
|
||||
#endif
|
||||
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
||||
@ -46,6 +48,10 @@ public:
|
||||
return static_cast<GLContextEGL*>(gl);
|
||||
}
|
||||
|
||||
static EGLSurface CreateSurfaceForWindow(nsIWidget* aWidget);
|
||||
|
||||
static void DestroySurface(EGLSurface aSurface);
|
||||
|
||||
bool Init() override;
|
||||
|
||||
virtual bool IsDoubleBuffered() const override {
|
||||
|
@ -360,7 +360,7 @@ GLContextEGL::SetEGLSurfaceOverride(EGLSurface surf) {
|
||||
Screen()->AssureBlitted();
|
||||
}
|
||||
|
||||
mSurfaceOverride = surf ? (EGLSurface) surf : mSurface;
|
||||
mSurfaceOverride = surf;
|
||||
MakeCurrent(true);
|
||||
}
|
||||
|
||||
@ -444,7 +444,7 @@ GLContextEGL::RenewSurface() {
|
||||
void
|
||||
GLContextEGL::ReleaseSurface() {
|
||||
if (mOwnsContext) {
|
||||
DestroySurface(mSurface);
|
||||
mozilla::gl::DestroySurface(mSurface);
|
||||
}
|
||||
mSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
@ -459,17 +459,20 @@ GLContextEGL::SetupLookupFunction()
|
||||
bool
|
||||
GLContextEGL::SwapBuffers()
|
||||
{
|
||||
if (mSurface) {
|
||||
EGLSurface surface = mSurfaceOverride != EGL_NO_SURFACE
|
||||
? mSurfaceOverride
|
||||
: mSurface;
|
||||
if (surface) {
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (!mIsOffscreen) {
|
||||
if (mHwc) {
|
||||
return mHwc->Render(EGL_DISPLAY(), mSurface);
|
||||
return mHwc->Render(EGL_DISPLAY(), surface);
|
||||
} else {
|
||||
return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), mSurface);
|
||||
return GetGonkDisplay()->SwapBuffers(EGL_DISPLAY(), surface);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
|
||||
return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), surface);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -482,6 +485,32 @@ GLContextEGL::HoldSurface(gfxASurface *aSurf) {
|
||||
mThebesSurface = aSurf;
|
||||
}
|
||||
|
||||
/* static */ EGLSurface
|
||||
GLContextEGL::CreateSurfaceForWindow(nsIWidget* aWidget)
|
||||
{
|
||||
if (!sEGLLibrary.EnsureInitialized()) {
|
||||
MOZ_CRASH("Failed to load EGL library!\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLConfig config;
|
||||
if (!CreateConfig(&config)) {
|
||||
MOZ_CRASH("Failed to create EGLConfig!\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EGLSurface surface = mozilla::gl::CreateSurfaceForWindow(aWidget, config);
|
||||
return surface;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
GLContextEGL::DestroySurface(EGLSurface aSurface)
|
||||
{
|
||||
if (aSurface != EGL_NO_SURFACE) {
|
||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), aSurface);
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<GLContextEGL>
|
||||
GLContextEGL::CreateGLContext(const SurfaceCaps& caps,
|
||||
GLContextEGL *shareContext,
|
||||
@ -774,7 +803,7 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
|
||||
|
||||
if (!glContext) {
|
||||
MOZ_CRASH("Failed to create EGLContext!\n");
|
||||
DestroySurface(surface);
|
||||
mozilla::gl::DestroySurface(surface);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,56 @@ CurrentThreadIsIonCompiling()
|
||||
{
|
||||
return TlsPerThreadData.get()->ionCompiling;
|
||||
}
|
||||
|
||||
static bool
|
||||
GCIsSweepingOnMainThread(JSRuntime* rt, Zone* zone)
|
||||
{
|
||||
return rt->isHeapMajorCollecting() && rt->gc.state() == SWEEP &&
|
||||
(zone->isGCSweeping() || rt->isAtomsZone(zone));
|
||||
}
|
||||
|
||||
static bool
|
||||
GCIsSweepingOnBackgroundThread(JSRuntime* rt, Zone* zone)
|
||||
{
|
||||
return rt->gc.isBackgroundSweeping() &&
|
||||
(zone->isGCBackgroundSweeping() || rt->isAtomsZone(zone));
|
||||
}
|
||||
|
||||
static bool
|
||||
ThingMayHaveDifferentRuntime(TenuredCell* cell)
|
||||
{
|
||||
// Some GC things may be associated with another runtime.
|
||||
AllocKind kind = cell->getAllocKind();
|
||||
if (kind == AllocKind::STRING)
|
||||
return static_cast<const JSString*>(cell)->isPermanentAtom();
|
||||
else if (kind == AllocKind::SYMBOL)
|
||||
return static_cast<const JS::Symbol*>(cell)->isWellKnownSymbol();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CheckGCIsSweepingZone(gc::Cell* cell)
|
||||
{
|
||||
MOZ_ASSERT(!IsInsideNursery(cell));
|
||||
TenuredCell* tenured = &cell->asTenured();
|
||||
if (ThingMayHaveDifferentRuntime(tenured))
|
||||
return;
|
||||
|
||||
Zone* zone = tenured->zoneFromAnyThread();
|
||||
JSRuntime* rt = zone->runtimeFromAnyThread();
|
||||
if (CurrentThreadCanAccessRuntime(rt)) {
|
||||
// We're on the main thread.
|
||||
MOZ_ASSERT(GCIsSweepingOnMainThread(rt, zone));
|
||||
} else {
|
||||
// We're not on the main thread, so we're either on a helper thread run
|
||||
// while the GC is active on the main thread or we are background
|
||||
// sweeping.
|
||||
MOZ_ASSERT(GCIsSweepingOnMainThread(rt, zone) ||
|
||||
GCIsSweepingOnBackgroundThread(rt, zone));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
bool
|
||||
|
@ -287,6 +287,11 @@ ZoneOfIdFromAnyThread(const jsid& id)
|
||||
void
|
||||
ValueReadBarrier(const Value& value);
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
CheckGCIsSweepingZone(gc::Cell* cell);
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct InternalGCMethods {};
|
||||
|
||||
@ -303,6 +308,13 @@ struct InternalGCMethods<T*>
|
||||
static void postBarrierRemove(T** vp) { T::writeBarrierPostRemove(*vp, vp); }
|
||||
|
||||
static void readBarrier(T* v) { T::readBarrier(v); }
|
||||
|
||||
#ifdef DEBUG
|
||||
static void checkGCIsSweeping(T* v) {
|
||||
if (v)
|
||||
CheckGCIsSweepingZone(v);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -380,6 +392,13 @@ struct InternalGCMethods<Value>
|
||||
}
|
||||
|
||||
static void readBarrier(const Value& v) { ValueReadBarrier(v); }
|
||||
|
||||
#ifdef DEBUG
|
||||
static void checkGCIsSweeping(const Value& v) {
|
||||
if (v.isMarkable())
|
||||
CheckGCIsSweepingZone(v.toGCThing());
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -403,6 +422,13 @@ struct InternalGCMethods<jsid>
|
||||
static void postBarrier(jsid* idp) {}
|
||||
static void postBarrierRelocate(jsid* idp) {}
|
||||
static void postBarrierRemove(jsid* idp) {}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void checkGCIsSweeping(jsid id) {
|
||||
if (JSID_IS_GCTHING(id))
|
||||
CheckGCIsSweepingZone(JSID_TO_GCTHING(id).asCell());
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -446,6 +472,10 @@ class BarrieredBase : public BarrieredBaseMixins<T>
|
||||
protected:
|
||||
void pre() { InternalGCMethods<T>::preBarrier(value); }
|
||||
void pre(Zone* zone) { InternalGCMethods<T>::preBarrier(zone, value); }
|
||||
|
||||
#ifdef DEBUG
|
||||
void checkGCIsSweeping() { InternalGCMethods<T>::checkGCIsSweeping(value); }
|
||||
#endif
|
||||
};
|
||||
|
||||
template <>
|
||||
@ -493,14 +523,16 @@ class PreBarriered : public BarrieredBase<T>
|
||||
/*
|
||||
* A pre- and post-barriered heap pointer, for use inside the JS engine.
|
||||
*
|
||||
* It must only be stored in memory that has GC lifetime. HeapPtr must not be
|
||||
* used in contexts where it may be implicitly moved or deleted, e.g. most
|
||||
* containers.
|
||||
*
|
||||
* Not to be confused with JS::Heap<T>. This is a different class from the
|
||||
* external interface and implements substantially different semantics.
|
||||
*
|
||||
* The post-barriers implemented by this class are faster than those
|
||||
* implemented by RelocatablePtr<T> or JS::Heap<T> at the cost of not
|
||||
* automatically handling deletion or movement. It should generally only be
|
||||
* stored in memory that has GC lifetime. HeapPtr must not be used in contexts
|
||||
* where it may be implicitly moved or deleted, e.g. most containers.
|
||||
* automatically handling deletion or movement.
|
||||
*/
|
||||
template <class T>
|
||||
class HeapPtr : public BarrieredBase<T>
|
||||
@ -509,6 +541,9 @@ class HeapPtr : public BarrieredBase<T>
|
||||
HeapPtr() : BarrieredBase<T>(GCMethods<T>::initial()) {}
|
||||
explicit HeapPtr(T v) : BarrieredBase<T>(v) { post(); }
|
||||
explicit HeapPtr(const HeapPtr<T>& v) : BarrieredBase<T>(v) { post(); }
|
||||
#ifdef DEBUG
|
||||
~HeapPtr() { this->checkGCIsSweeping(); }
|
||||
#endif
|
||||
|
||||
void init(T v) {
|
||||
this->value = v;
|
||||
@ -613,9 +648,20 @@ class RelocatablePtr : public BarrieredBase<T>
|
||||
|
||||
DECLARE_POINTER_ASSIGN_OPS(RelocatablePtr, T);
|
||||
|
||||
/* Make this friend so it can access pre() and post(). */
|
||||
template <class T1, class T2>
|
||||
friend inline void
|
||||
BarrieredSetPair(Zone* zone,
|
||||
RelocatablePtr<T1*>& v1, T1* val1,
|
||||
RelocatablePtr<T2*>& v2, T2* val2);
|
||||
|
||||
protected:
|
||||
void set(const T& v) {
|
||||
this->pre();
|
||||
postBarrieredSet(v);
|
||||
}
|
||||
|
||||
void postBarrieredSet(const T& v) {
|
||||
if (GCMethods<T>::needsPostBarrier(v)) {
|
||||
this->value = v;
|
||||
post();
|
||||
@ -658,6 +704,24 @@ BarrieredSetPair(Zone* zone,
|
||||
v2.post();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a hack for RegExpStatics::updateFromMatch. It allows us to do two
|
||||
* barriers with only one branch to check if we're in an incremental GC.
|
||||
*/
|
||||
template <class T1, class T2>
|
||||
static inline void
|
||||
BarrieredSetPair(Zone* zone,
|
||||
RelocatablePtr<T1*>& v1, T1* val1,
|
||||
RelocatablePtr<T2*>& v2, T2* val2)
|
||||
{
|
||||
if (T1::needWriteBarrierPre(zone)) {
|
||||
v1.pre();
|
||||
v2.pre();
|
||||
}
|
||||
v1.postBarrieredSet(val1);
|
||||
v2.postBarrieredSet(val2);
|
||||
}
|
||||
|
||||
/* Useful for hashtables with a HeapPtr as key. */
|
||||
template <class T>
|
||||
struct HeapPtrHasher
|
||||
@ -766,9 +830,17 @@ typedef PreBarriered<JSString*> PreBarrieredString;
|
||||
typedef PreBarriered<JSAtom*> PreBarrieredAtom;
|
||||
|
||||
typedef RelocatablePtr<JSObject*> RelocatablePtrObject;
|
||||
typedef RelocatablePtr<JSFunction*> RelocatablePtrFunction;
|
||||
typedef RelocatablePtr<PlainObject*> RelocatablePtrPlainObject;
|
||||
typedef RelocatablePtr<JSScript*> RelocatablePtrScript;
|
||||
typedef RelocatablePtr<NativeObject*> RelocatablePtrNativeObject;
|
||||
typedef RelocatablePtr<NestedScopeObject*> RelocatablePtrNestedScopeObject;
|
||||
typedef RelocatablePtr<Shape*> RelocatablePtrShape;
|
||||
typedef RelocatablePtr<ObjectGroup*> RelocatablePtrObjectGroup;
|
||||
typedef RelocatablePtr<jit::JitCode*> RelocatablePtrJitCode;
|
||||
typedef RelocatablePtr<JSLinearString*> RelocatablePtrLinearString;
|
||||
typedef RelocatablePtr<JSString*> RelocatablePtrString;
|
||||
typedef RelocatablePtr<JSAtom*> RelocatablePtrAtom;
|
||||
|
||||
typedef HeapPtr<NativeObject*> HeapPtrNativeObject;
|
||||
typedef HeapPtr<ArrayObject*> HeapPtrArrayObject;
|
||||
|
@ -39,6 +39,9 @@ JS::Zone::Zone(JSRuntime* rt)
|
||||
gcState_(NoGC),
|
||||
gcScheduled_(false),
|
||||
gcPreserveCode_(false),
|
||||
#ifdef DEBUG
|
||||
gcBackgroundSweeping_(false),
|
||||
#endif
|
||||
jitUsingBarriers_(false),
|
||||
listNext_(NotOnList)
|
||||
{
|
||||
@ -270,6 +273,15 @@ Zone::notifyObservingDebuggers()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
Zone::setGCBackgroundSweeping(bool newState)
|
||||
{
|
||||
MOZ_ASSERT(gcBackgroundSweeping_ != newState);
|
||||
gcBackgroundSweeping_ = newState;
|
||||
}
|
||||
#endif
|
||||
|
||||
JS::Zone*
|
||||
js::ZoneOfValue(const JS::Value& value)
|
||||
{
|
||||
|
@ -226,6 +226,9 @@ struct Zone : public JS::shadow::Zone,
|
||||
// For testing purposes, return the index of the zone group which this zone
|
||||
// was swept in in the last GC.
|
||||
unsigned lastZoneGroupIndex() { return gcLastZoneGroupIndex; }
|
||||
|
||||
void setGCBackgroundSweeping(bool newState);
|
||||
bool isGCBackgroundSweeping() { return gcBackgroundSweeping_; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
@ -300,6 +303,9 @@ struct Zone : public JS::shadow::Zone,
|
||||
GCState gcState_;
|
||||
bool gcScheduled_;
|
||||
bool gcPreserveCode_;
|
||||
#ifdef DEBUG
|
||||
bool gcBackgroundSweeping_;
|
||||
#endif
|
||||
bool jitUsingBarriers_;
|
||||
|
||||
// Allow zones to be linked into a list
|
||||
|
@ -119,11 +119,11 @@ struct BaselineScript
|
||||
|
||||
private:
|
||||
// Code pointer containing the actual method.
|
||||
HeapPtrJitCode method_;
|
||||
RelocatablePtrJitCode method_;
|
||||
|
||||
// For heavyweight scripts, template objects to use for the call object and
|
||||
// decl env object (linked via the call object's enclosing scope).
|
||||
HeapPtrObject templateScope_;
|
||||
RelocatablePtrObject templateScope_;
|
||||
|
||||
// Allocated space for fallback stubs.
|
||||
FallbackICStubSpace fallbackStubSpace_;
|
||||
|
@ -3208,6 +3208,27 @@ GCRuntime::expireChunksAndArenas(bool shouldShrink, AutoLockGC& lock)
|
||||
decommitArenas(lock);
|
||||
}
|
||||
|
||||
// In debug builds, set/unset the background sweeping flag on the zone.
|
||||
struct AutoSetZoneBackgroundSweeping
|
||||
{
|
||||
#ifdef DEBUG
|
||||
explicit AutoSetZoneBackgroundSweeping(Zone* zone)
|
||||
: zone_(zone)
|
||||
{
|
||||
zone_->setGCBackgroundSweeping(true);
|
||||
}
|
||||
|
||||
~AutoSetZoneBackgroundSweeping() {
|
||||
zone_->setGCBackgroundSweeping(false);
|
||||
}
|
||||
|
||||
private:
|
||||
Zone* zone_;
|
||||
#else
|
||||
AutoSetZoneBackgroundSweeping(Zone* zone) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
GCRuntime::sweepBackgroundThings(ZoneList& zones, LifoAlloc& freeBlocks, ThreadType threadType)
|
||||
{
|
||||
@ -3221,6 +3242,7 @@ GCRuntime::sweepBackgroundThings(ZoneList& zones, LifoAlloc& freeBlocks, ThreadT
|
||||
FreeOp fop(rt, threadType);
|
||||
for (unsigned phase = 0 ; phase < ArrayLength(BackgroundFinalizePhases) ; ++phase) {
|
||||
for (Zone* zone = zones.front(); zone; zone = zone->nextZone()) {
|
||||
AutoSetZoneBackgroundSweeping zbs(zone);
|
||||
for (unsigned index = 0 ; index < BackgroundFinalizePhases[phase].length ; ++index) {
|
||||
AllocKind kind = BackgroundFinalizePhases[phase].kinds[index];
|
||||
ArenaHeader* arenas = zone->arenas.arenaListsToSweep[kind];
|
||||
|
@ -201,7 +201,7 @@ class Bindings
|
||||
friend class BindingIter;
|
||||
friend class AliasedFormalIter;
|
||||
|
||||
HeapPtrShape callObjShape_;
|
||||
RelocatablePtrShape callObjShape_;
|
||||
uintptr_t bindingArrayAndFlag_;
|
||||
uint16_t numArgs_;
|
||||
uint16_t numBlockScoped_;
|
||||
|
@ -21,19 +21,19 @@ class RegExpStatics
|
||||
{
|
||||
/* The latest RegExp output, set after execution. */
|
||||
VectorMatchPairs matches;
|
||||
HeapPtrLinearString matchesInput;
|
||||
RelocatablePtrLinearString matchesInput;
|
||||
|
||||
/*
|
||||
* The previous RegExp input, used to resolve lazy state.
|
||||
* A raw RegExpShared cannot be stored because it may be in
|
||||
* a different compartment via evalcx().
|
||||
*/
|
||||
HeapPtrAtom lazySource;
|
||||
RelocatablePtrAtom lazySource;
|
||||
RegExpFlag lazyFlags;
|
||||
size_t lazyIndex;
|
||||
|
||||
/* The latest RegExp input, set before execution. */
|
||||
HeapPtrString pendingInput;
|
||||
RelocatablePtrString pendingInput;
|
||||
RegExpFlag flags;
|
||||
|
||||
/*
|
||||
|
@ -799,7 +799,7 @@ class PreliminaryObjectArray
|
||||
|
||||
class PreliminaryObjectArrayWithTemplate : public PreliminaryObjectArray
|
||||
{
|
||||
HeapPtrShape shape_;
|
||||
RelocatablePtrShape shape_;
|
||||
|
||||
public:
|
||||
explicit PreliminaryObjectArrayWithTemplate(Shape* shape)
|
||||
@ -872,7 +872,7 @@ class TypeNewScript
|
||||
|
||||
private:
|
||||
// Scripted function which this information was computed for.
|
||||
HeapPtrFunction function_;
|
||||
RelocatablePtrFunction function_;
|
||||
|
||||
// Any preliminary objects with the type. The analyses are not performed
|
||||
// until this array is cleared.
|
||||
@ -884,7 +884,7 @@ class TypeNewScript
|
||||
// allocation kind to use. This is null if the new objects have an unboxed
|
||||
// layout, in which case the UnboxedLayout provides the initial structure
|
||||
// of the object.
|
||||
HeapPtrPlainObject templateObject_;
|
||||
RelocatablePtrPlainObject templateObject_;
|
||||
|
||||
// Order in which definite properties become initialized. We need this in
|
||||
// case the definite properties are invalidated (such as by adding a setter
|
||||
@ -901,11 +901,11 @@ class TypeNewScript
|
||||
// shape contains all such additional properties (plus the definite
|
||||
// properties). When an object of this group acquires this shape, it is
|
||||
// fully initialized and its group can be changed to initializedGroup.
|
||||
HeapPtrShape initializedShape_;
|
||||
RelocatablePtrShape initializedShape_;
|
||||
|
||||
// Group with definite properties set for all properties found by
|
||||
// both the definite and acquired properties analyses.
|
||||
HeapPtrObjectGroup initializedGroup_;
|
||||
RelocatablePtrObjectGroup initializedGroup_;
|
||||
|
||||
public:
|
||||
TypeNewScript() { mozilla::PodZero(this); }
|
||||
|
@ -109,6 +109,10 @@ UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group)
|
||||
for (GeneralRegisterForwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter)
|
||||
masm.Push(*iter);
|
||||
|
||||
// The scratch double register might be used by MacroAssembler methods.
|
||||
if (ScratchDoubleReg.volatile_())
|
||||
masm.push(ScratchDoubleReg);
|
||||
|
||||
Label failure, tenuredObject, allocated;
|
||||
masm.branch32(Assembler::NotEqual, newKindReg, Imm32(GenericObject), &tenuredObject);
|
||||
masm.branchTest32(Assembler::NonZero, AbsoluteAddress(group->addressOfFlags()),
|
||||
@ -206,6 +210,8 @@ UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group)
|
||||
masm.movePtr(object, ReturnReg);
|
||||
|
||||
// Restore non-volatile registers which were saved on entry.
|
||||
if (ScratchDoubleReg.volatile_())
|
||||
masm.pop(ScratchDoubleReg);
|
||||
for (GeneralRegisterBackwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter)
|
||||
masm.Pop(*iter);
|
||||
|
||||
@ -650,7 +656,10 @@ UnboxedPlainObject::createWithProperties(ExclusiveContext* cx, HandleObjectGroup
|
||||
}
|
||||
|
||||
#ifndef JS_CODEGEN_NONE
|
||||
if (cx->isJSContext() && !layout.constructorCode()) {
|
||||
if (cx->isJSContext() &&
|
||||
!layout.constructorCode() &&
|
||||
cx->asJSContext()->runtime()->jitSupportsFloatingPoint)
|
||||
{
|
||||
if (!UnboxedLayout::makeConstructorCode(cx->asJSContext(), group))
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -625,6 +625,12 @@ nsPluginFrame::CallSetWindow(bool aCheckIsHidden)
|
||||
nsRect bounds = GetContentRectRelativeToSelf() + GetOffsetToCrossDoc(rootFrame);
|
||||
nsIntRect intBounds = bounds.ToNearestPixels(appUnitsPerDevPixel);
|
||||
|
||||
// In e10s, this returns the offset to the top level window, in non-e10s
|
||||
// it return 0,0.
|
||||
LayoutDeviceIntPoint intOffset = GetRemoteTabChromeOffset();
|
||||
intBounds.x += intOffset.x;
|
||||
intBounds.y += intOffset.y;
|
||||
|
||||
// window must be in "display pixels"
|
||||
double scaleFactor = 1.0;
|
||||
if (NS_FAILED(mInstanceOwner->GetContentsScaleFactor(&scaleFactor))) {
|
||||
@ -753,7 +759,30 @@ nsPluginFrame::IsHidden(bool aCheckVisibilityStyle) const
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIntPoint nsPluginFrame::GetWindowOriginInPixels(bool aWindowless)
|
||||
mozilla::LayoutDeviceIntPoint
|
||||
nsPluginFrame::GetRemoteTabChromeOffset()
|
||||
{
|
||||
LayoutDeviceIntPoint offset;
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetContent()->OwnerDoc()->GetWindow());
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDOMWindow> topWindow;
|
||||
window->GetTop(getter_AddRefs(topWindow));
|
||||
if (topWindow) {
|
||||
dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
|
||||
if (tc) {
|
||||
LayoutDeviceIntPoint chromeOffset;
|
||||
tc->SendGetTabOffset(&chromeOffset);
|
||||
offset -= chromeOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsPluginFrame::GetWindowOriginInPixels(bool aWindowless)
|
||||
{
|
||||
nsView * parentWithView;
|
||||
nsPoint origin(0,0);
|
||||
@ -769,8 +798,19 @@ nsIntPoint nsPluginFrame::GetWindowOriginInPixels(bool aWindowless)
|
||||
}
|
||||
origin += GetContentRectRelativeToSelf().TopLeft();
|
||||
|
||||
return nsIntPoint(PresContext()->AppUnitsToDevPixels(origin.x),
|
||||
PresContext()->AppUnitsToDevPixels(origin.y));
|
||||
nsIntPoint pt(PresContext()->AppUnitsToDevPixels(origin.x),
|
||||
PresContext()->AppUnitsToDevPixels(origin.y));
|
||||
|
||||
// If we're in the content process offsetToWidget is tied to the top level
|
||||
// widget we can access in the child process, which is the tab. We need the
|
||||
// offset all the way up to the top level native window here. (If this is
|
||||
// non-e10s this routine will return 0,0.)
|
||||
if (aWindowless) {
|
||||
mozilla::LayoutDeviceIntPoint lpt = GetRemoteTabChromeOffset();
|
||||
pt += nsIntPoint(lpt.x, lpt.y);
|
||||
}
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "nsRegion.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsIReflowCallback.h"
|
||||
#include "Units.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h> // For HWND :(
|
||||
@ -220,6 +221,13 @@ protected:
|
||||
bool IsPaintedByGecko() const;
|
||||
|
||||
nsIntPoint GetWindowOriginInPixels(bool aWindowless);
|
||||
|
||||
/*
|
||||
* If this frame is in a remote tab, return the tab offset to
|
||||
* the origin of the chrome window. In non-e10s, this return 0,0.
|
||||
* This api sends a sync ipc request so be careful about use.
|
||||
*/
|
||||
mozilla::LayoutDeviceIntPoint GetRemoteTabChromeOffset();
|
||||
|
||||
static void PaintPrintPlugin(nsIFrame* aFrame,
|
||||
nsRenderingContext* aRenderingContext,
|
||||
|
10
layout/reftests/svg/baseline-middle-01.svg
Normal file
10
layout/reftests/svg/baseline-middle-01.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -10 20 20" preserveAspectRatio="none"
|
||||
font-family="sans-serif">
|
||||
<rect y="-10" width="20" height="20" fill="lime"/>
|
||||
<text dominant-baseline="middle" fill="red">x</text>
|
||||
<text y="0.5ex" fill="lime" stroke-width="1" stroke="lime">x</text>
|
||||
</svg>
|
After Width: | Height: | Size: 423 B |
@ -26,6 +26,7 @@ include moz-only/reftest.list
|
||||
include svg-integration/reftest.list
|
||||
|
||||
== altGlyph-01.svg altGlyph-01-ref.svg
|
||||
== baseline-middle-01.svg pass.svg
|
||||
== border-radius-01.html pass.svg
|
||||
== cssComment-in-attribute-01.svg cssComment-in-attribute-01-ref.svg
|
||||
== clip-01.svg pass.svg
|
||||
|
@ -337,7 +337,8 @@ IsGlyphPositioningAttribute(nsIAtom* aAttribute)
|
||||
static nscoord
|
||||
GetBaselinePosition(nsTextFrame* aFrame,
|
||||
gfxTextRun* aTextRun,
|
||||
uint8_t aDominantBaseline)
|
||||
uint8_t aDominantBaseline,
|
||||
float aFontSizeScaleFactor)
|
||||
{
|
||||
// use a dummy WritingMode, because nsTextFrame::GetLogicalBaseLine
|
||||
// doesn't use it anyway
|
||||
@ -356,6 +357,10 @@ GetBaselinePosition(nsTextFrame* aFrame,
|
||||
case NS_STYLE_DOMINANT_BASELINE_AUTO:
|
||||
case NS_STYLE_DOMINANT_BASELINE_ALPHABETIC:
|
||||
return aFrame->GetLogicalBaseline(writingMode);
|
||||
case NS_STYLE_DOMINANT_BASELINE_MIDDLE:
|
||||
return aFrame->GetLogicalBaseline(writingMode) -
|
||||
SVGContentUtils::GetFontXHeight(aFrame) / 2.0 *
|
||||
aFrame->PresContext()->AppUnitsPerCSSPixel() * aFontSizeScaleFactor;
|
||||
}
|
||||
|
||||
gfxTextRun::Metrics metrics =
|
||||
@ -367,7 +372,6 @@ GetBaselinePosition(nsTextFrame* aFrame,
|
||||
case NS_STYLE_DOMINANT_BASELINE_IDEOGRAPHIC:
|
||||
return metrics.mAscent + metrics.mDescent;
|
||||
case NS_STYLE_DOMINANT_BASELINE_CENTRAL:
|
||||
case NS_STYLE_DOMINANT_BASELINE_MIDDLE:
|
||||
case NS_STYLE_DOMINANT_BASELINE_MATHEMATICAL:
|
||||
return (metrics.mAscent + metrics.mDescent) / 2.0;
|
||||
}
|
||||
@ -1993,7 +1997,8 @@ TextRenderedRunIterator::Next()
|
||||
frame->EnsureTextRun(nsTextFrame::eInflated);
|
||||
baseline = GetBaselinePosition(frame,
|
||||
frame->GetTextRun(nsTextFrame::eInflated),
|
||||
mFrameIterator.DominantBaseline());
|
||||
mFrameIterator.DominantBaseline(),
|
||||
mFontSizeScaleFactor);
|
||||
|
||||
// Trim the offset/length to remove any leading/trailing white space.
|
||||
uint32_t untrimmedOffset = offset;
|
||||
@ -4607,7 +4612,8 @@ SVGTextFrame::DetermineCharPositions(nsTArray<nsPoint>& aPositions)
|
||||
if (textRun->IsRightToLeft()) {
|
||||
position.x += frame->GetRect().width;
|
||||
}
|
||||
position.y += GetBaselinePosition(frame, textRun, frit.DominantBaseline());
|
||||
position.y += GetBaselinePosition(frame, textRun, frit.DominantBaseline(),
|
||||
mFontSizeScaleFactor);
|
||||
|
||||
// Any characters not in a frame, e.g. when display:none.
|
||||
for (uint32_t i = 0; i < frit.UndisplayedCharacters(); i++) {
|
||||
|
@ -184,8 +184,8 @@ public:
|
||||
NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages) override;
|
||||
NS_IMETHOD GetResponseTimeoutEnabled(bool *aEnable) override;
|
||||
NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override;
|
||||
NS_IMETHOD GetNetworkInterfaceId(nsACString& aNetworkInterfaceId);
|
||||
NS_IMETHOD SetNetworkInterfaceId(const nsACString& aNetworkInterfaceId);
|
||||
NS_IMETHOD GetNetworkInterfaceId(nsACString& aNetworkInterfaceId) override;
|
||||
NS_IMETHOD SetNetworkInterfaceId(const nsACString& aNetworkInterfaceId) override;
|
||||
NS_IMETHOD AddRedirect(nsIPrincipal *aRedirect) override;
|
||||
NS_IMETHOD ForcePending(bool aForcePending) override;
|
||||
NS_IMETHOD GetLastModifiedTime(PRTime* lastModifiedTime) override;
|
||||
|
@ -13,8 +13,6 @@ const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
|
||||
const nsDialogParamBlock = "@mozilla.org/embedcomp/dialogparam;1";
|
||||
const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock;
|
||||
const nsPKIParamBlock = "@mozilla.org/security/pkiparamblock;1";
|
||||
const nsINSSCertCache = Components.interfaces.nsINSSCertCache;
|
||||
const nsNSSCertCache = "@mozilla.org/security/nsscertcache;1";
|
||||
|
||||
const gCertFileTypes = "*.p7b; *.crt; *.cert; *.cer; *.pem; *.der";
|
||||
|
||||
@ -52,9 +50,7 @@ function LoadCerts()
|
||||
Services.obs.addObserver(smartCardObserver, "smartcard-remove", false);
|
||||
|
||||
certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB);
|
||||
var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
|
||||
|
||||
certcache.cacheAllCerts();
|
||||
var certcache = certdb.getCerts();
|
||||
|
||||
caTreeView = Components.classes[nsCertTree]
|
||||
.createInstance(nsICertTree);
|
||||
@ -378,8 +374,7 @@ function restoreCerts()
|
||||
certdb.importPKCS12File(null, fp.file);
|
||||
}
|
||||
|
||||
var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
|
||||
certcache.cacheAllCerts();
|
||||
var certcache = certdb.getCerts();
|
||||
userTreeView.loadCertsFromCache(certcache, nsIX509Cert.USER_CERT);
|
||||
userTreeView.selection.clearSelection();
|
||||
caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
|
||||
@ -521,10 +516,9 @@ function addCACerts()
|
||||
|
||||
function onSmartCardChange()
|
||||
{
|
||||
var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
|
||||
var certcache = certdb.getCerts();
|
||||
// We've change the state of the smart cards inserted or removed
|
||||
// that means the available certs may have changed. Update the display
|
||||
certcache.cacheAllCerts();
|
||||
userTreeView.loadCertsFromCache(certcache, nsIX509Cert.USER_CERT);
|
||||
userTreeView.selection.clearSelection();
|
||||
caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
|
||||
@ -549,8 +543,7 @@ function addEmailCert()
|
||||
fp.appendFilters(nsIFilePicker.filterAll);
|
||||
if (fp.show() == nsIFilePicker.returnOK) {
|
||||
certdb.importCertsFromFile(null, fp.file, nsIX509Cert.EMAIL_CERT);
|
||||
var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
|
||||
certcache.cacheAllCerts();
|
||||
var certcache = certdb.getCerts();
|
||||
emailTreeView.loadCertsFromCache(certcache, nsIX509Cert.EMAIL_CERT);
|
||||
emailTreeView.selection.clearSelection();
|
||||
caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
|
||||
@ -571,8 +564,7 @@ function addWebSiteCert()
|
||||
if (fp.show() == nsIFilePicker.returnOK) {
|
||||
certdb.importCertsFromFile(null, fp.file, nsIX509Cert.SERVER_CERT);
|
||||
|
||||
var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
|
||||
certcache.cacheAllCerts();
|
||||
var certcache = certdb.getCerts();
|
||||
serverTreeView.loadCertsFromCache(certcache, nsIX509Cert.SERVER_CERT);
|
||||
serverTreeView.selection.clearSelection();
|
||||
caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
|
||||
@ -584,8 +576,7 @@ function addException()
|
||||
{
|
||||
window.openDialog('chrome://pippki/content/exceptionDialog.xul', "",
|
||||
'chrome,centerscreen,modal');
|
||||
var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
|
||||
certcache.cacheAllCerts();
|
||||
var certcache = certdb.getCerts();
|
||||
serverTreeView.loadCertsFromCache(certcache, nsIX509Cert.SERVER_CERT);
|
||||
serverTreeView.selection.clearSelection();
|
||||
orphanTreeView.loadCertsFromCache(certcache, nsIX509Cert.UNKNOWN_CERT);
|
||||
|
@ -18,7 +18,6 @@ XPIDL_SOURCES += [
|
||||
'nsIGenKeypairInfoDlg.idl',
|
||||
'nsIKeygenThread.idl',
|
||||
'nsIKeyModule.idl',
|
||||
'nsINSSCertCache.idl',
|
||||
'nsINSSVersion.idl',
|
||||
'nsIPK11Token.idl',
|
||||
'nsIPK11TokenDB.idl',
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include "nsISupports.idl"
|
||||
#include "nsITreeView.idl"
|
||||
|
||||
interface nsINSSCertCache;
|
||||
interface nsIX509Cert;
|
||||
interface nsIX509CertList;
|
||||
|
||||
[scriptable, uuid(d0180863-606e-49e6-8324-cf45ed4dd891)]
|
||||
interface nsICertTreeItem : nsISupports {
|
||||
@ -16,16 +16,16 @@ interface nsICertTreeItem : nsISupports {
|
||||
readonly attribute AString hostPort;
|
||||
};
|
||||
|
||||
[scriptable, uuid(a8cd1c89-a901-4735-831b-7198b7b8b6b1)]
|
||||
[scriptable, uuid(55d5ad6b-5572-47fe-941c-f01fe723659e)]
|
||||
interface nsICertTree : nsITreeView {
|
||||
|
||||
void loadCerts(in unsigned long type);
|
||||
void loadCertsFromCache(in nsINSSCertCache cache, in unsigned long type);
|
||||
void loadCertsFromCache(in nsIX509CertList cache, in unsigned long type);
|
||||
|
||||
nsIX509Cert getCert(in unsigned long index);
|
||||
nsICertTreeItem getTreeItem(in unsigned long index);
|
||||
boolean isHostPortOverride(in unsigned long index);
|
||||
|
||||
|
||||
void deleteEntryObject(in unsigned long index);
|
||||
};
|
||||
|
||||
|
@ -1,44 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIX509CertList;
|
||||
|
||||
[scriptable, uuid(1b75bdae-1757-4322-9d1e-cfcaa18cb710)]
|
||||
interface nsINSSCertCache : nsISupports {
|
||||
|
||||
/*
|
||||
* cacheAllCerts
|
||||
*
|
||||
* Creates a cache of all certificates currently known to NSS.
|
||||
*/
|
||||
void cacheAllCerts();
|
||||
void cacheCertList(in nsIX509CertList list);
|
||||
|
||||
/*
|
||||
* get an X509CertList
|
||||
*/
|
||||
nsIX509CertList getX509CachedCerts();
|
||||
|
||||
/*
|
||||
* getCachedCerts
|
||||
*
|
||||
* Returns the cached CERTCertList*
|
||||
*/
|
||||
[notxpcom, noscript] voidPtr getCachedCerts();
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
#define NS_NSSCERTCACHE_CID { /* 3f429a14-dffe-417d-8cb8-fdf09bacd09e */ \
|
||||
0x3f429a14, \
|
||||
0xdffe, \
|
||||
0x417d, \
|
||||
{0x8c, 0xb8, 0xfd, 0xf0, 0x9b, 0xac, 0xd0, 0x9e} \
|
||||
}
|
||||
|
||||
#define NS_NSSCERTCACHE_CONTRACTID "@mozilla.org/security/nsscertcache;1"
|
||||
|
||||
%}
|
@ -38,7 +38,6 @@ UNIFIED_SOURCES += [
|
||||
'nsKeyModule.cpp',
|
||||
'nsNSSASN1Object.cpp',
|
||||
'nsNSSCallbacks.cpp',
|
||||
'nsNSSCertCache.cpp',
|
||||
'nsNSSCertHelper.cpp',
|
||||
'nsNSSCertificate.cpp',
|
||||
'nsNSSCertificateFakeTransport.cpp',
|
||||
|
@ -15,14 +15,13 @@
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
#include "nsINSSCertCache.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
using namespace mozilla;
|
||||
@ -631,14 +630,23 @@ nsCertTree::GetCertsByType(uint32_t aType,
|
||||
aCertCmpFnArg);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCertTree::GetCertsByTypeFromCache(nsINSSCertCache *aCache,
|
||||
nsresult
|
||||
nsCertTree::GetCertsByTypeFromCache(nsIX509CertList *aCache,
|
||||
uint32_t aType,
|
||||
nsCertCompareFunc aCertCmpFn,
|
||||
void *aCertCmpFnArg)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCache);
|
||||
CERTCertList *certList = reinterpret_cast<CERTCertList*>(aCache->GetCachedCerts());
|
||||
// GetRawCertList checks for NSS shutdown since we can't do it ourselves here
|
||||
// easily. We still have to acquire a shutdown prevention lock to prevent NSS
|
||||
// shutting down after GetRawCertList has returned. While cumbersome, this is
|
||||
// at least mostly correct. The rest of this implementation doesn't even go
|
||||
// this far in attempting to check for or prevent NSS shutdown at the
|
||||
// appropriate times. If this were reimplemented at a higher level using
|
||||
// more encapsulated types that handled NSS shutdown themselves, we wouldn't
|
||||
// be having these kinds of problems.
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
CERTCertList *certList = reinterpret_cast<CERTCertList*>(aCache->GetRawCertList());
|
||||
if (!certList)
|
||||
return NS_ERROR_FAILURE;
|
||||
return GetCertsByTypeFromCertList(certList, aType, aCertCmpFn, aCertCmpFnArg);
|
||||
@ -648,8 +656,8 @@ nsCertTree::GetCertsByTypeFromCache(nsINSSCertCache *aCache,
|
||||
//
|
||||
// Load all of the certificates in the DB for this type. Sort them
|
||||
// by token, organization, then common name.
|
||||
NS_IMETHODIMP
|
||||
nsCertTree::LoadCertsFromCache(nsINSSCertCache *aCache, uint32_t aType)
|
||||
NS_IMETHODIMP
|
||||
nsCertTree::LoadCertsFromCache(nsIX509CertList *aCache, uint32_t aType)
|
||||
{
|
||||
if (mTreeArray) {
|
||||
FreeCertArray();
|
||||
|
@ -114,7 +114,7 @@ protected:
|
||||
nsresult GetCertsByType(uint32_t aType, nsCertCompareFunc aCertCmpFn,
|
||||
void *aCertCmpFnArg);
|
||||
|
||||
nsresult GetCertsByTypeFromCache(nsINSSCertCache *aCache, uint32_t aType,
|
||||
nsresult GetCertsByTypeFromCache(nsIX509CertList *aCache, uint32_t aType,
|
||||
nsCertCompareFunc aCertCmpFn, void *aCertCmpFnArg);
|
||||
private:
|
||||
nsTArray< mozilla::RefPtr<nsCertTreeDispInfo> > mDispInfo;
|
||||
|
@ -1,103 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsNSSCertCache.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "cert.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsNSSHelper.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNSSCertCache, nsINSSCertCache)
|
||||
|
||||
nsNSSCertCache::nsNSSCertCache()
|
||||
:mutex("nsNSSCertCache.mutex"), mCertList(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsNSSCertCache::~nsNSSCertCache()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return;
|
||||
}
|
||||
destructorSafeDestroyNSSReference();
|
||||
shutdown(calledFromObject);
|
||||
}
|
||||
|
||||
void nsNSSCertCache::virtualDestroyNSSReference()
|
||||
{
|
||||
destructorSafeDestroyNSSReference();
|
||||
}
|
||||
|
||||
void nsNSSCertCache::destructorSafeDestroyNSSReference()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertCache::CacheAllCerts()
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
|
||||
|
||||
ScopedCERTCertList newList(PK11_ListCerts(PK11CertListUnique, cxt));
|
||||
|
||||
if (newList) {
|
||||
MutexAutoLock lock(mutex);
|
||||
mCertList = new nsNSSCertList(newList, locker);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertCache::CacheCertList(nsIX509CertList *list)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mutex);
|
||||
mCertList = list;
|
||||
//NS_ADDREF(mCertList);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSSCertCache::GetX509CachedCerts(nsIX509CertList **list)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mutex);
|
||||
if (!mCertList) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
*list = mCertList;
|
||||
NS_ADDREF(*list);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void* nsNSSCertCache::GetCachedCerts()
|
||||
{
|
||||
if (isAlreadyShutDown())
|
||||
return nullptr;
|
||||
|
||||
MutexAutoLock lock(mutex);
|
||||
return mCertList->GetRawCertList();
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _NSNSSCERTCACHE_H_
|
||||
#define _NSNSSCERTCACHE_H_
|
||||
|
||||
#include "nsINSSCertCache.h"
|
||||
#include "nsIX509CertList.h"
|
||||
#include "certt.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsNSSCertCache : public nsINSSCertCache,
|
||||
public nsNSSShutDownObject
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSINSSCERTCACHE
|
||||
|
||||
nsNSSCertCache();
|
||||
|
||||
protected:
|
||||
virtual ~nsNSSCertCache();
|
||||
|
||||
private:
|
||||
mozilla::Mutex mutex;
|
||||
nsCOMPtr<nsIX509CertList> mCertList;
|
||||
virtual void virtualDestroyNSSReference() override;
|
||||
void destructorSafeDestroyNSSReference();
|
||||
};
|
||||
|
||||
#endif
|
@ -1626,8 +1626,17 @@ nsNSSCertList::DupCertList(CERTCertList* aCertList,
|
||||
void*
|
||||
nsNSSCertList::GetRawCertList()
|
||||
{
|
||||
// This function should only be called after adquiring a
|
||||
// nsNSSShutDownPreventionLock
|
||||
// This function should only be called after acquiring a
|
||||
// nsNSSShutDownPreventionLock. It's difficult to enforce this in code since
|
||||
// this is an implementation of an XPCOM interface function (albeit a
|
||||
// C++-only one), so we acquire the (reentrant) lock and check for shutdown
|
||||
// ourselves here. At the moment it appears that only nsCertTree uses this
|
||||
// function. When that gets removed and replaced by a more reasonable
|
||||
// implementation of the certificate manager, this function can be removed.
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return nullptr;
|
||||
}
|
||||
return mCertList.get();
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSHelper.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
#include "nsNSSCertCache.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsICertificateDialogs.h"
|
||||
#include "nsNSSCertTrust.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSCertificateFakeTransport.h"
|
||||
#include "nsNSSCertificateDB.h"
|
||||
#include "nsNSSCertCache.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsCertTree.h"
|
||||
#endif
|
||||
@ -188,7 +187,6 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly,
|
||||
nsNSSCertificate,
|
||||
nsNSSCertificateFakeTransport)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsNSSCertificateDB)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsNSSCertCache)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly,
|
||||
nsNSSCertList,
|
||||
nsNSSCertListFakeTransport)
|
||||
@ -222,7 +220,6 @@ NS_DEFINE_NAMED_CID(NS_PSMCONTENTLISTEN_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_X509CERT_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_X509CERTDB_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_X509CERTLIST_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_NSSCERTCACHE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FORMPROCESSOR_CID);
|
||||
#ifdef MOZ_XUL
|
||||
NS_DEFINE_NAMED_CID(NS_CERTTREE_CID);
|
||||
@ -253,7 +250,6 @@ static const mozilla::Module::CIDEntry kNSSCIDs[] = {
|
||||
{ &kNS_X509CERT_CID, false, nullptr, nsNSSCertificateConstructor },
|
||||
{ &kNS_X509CERTDB_CID, false, nullptr, nsNSSCertificateDBConstructor },
|
||||
{ &kNS_X509CERTLIST_CID, false, nullptr, nsNSSCertListConstructor },
|
||||
{ &kNS_NSSCERTCACHE_CID, false, nullptr, nsNSSCertCacheConstructor },
|
||||
{ &kNS_FORMPROCESSOR_CID, false, nullptr, nsKeygenFormProcessor::Create },
|
||||
#ifdef MOZ_XUL
|
||||
{ &kNS_CERTTREE_CID, false, nullptr, nsCertTreeConstructor },
|
||||
@ -287,7 +283,6 @@ static const mozilla::Module::ContractIDEntry kNSSContracts[] = {
|
||||
{ NS_PSMCONTENTLISTEN_CONTRACTID, &kNS_PSMCONTENTLISTEN_CID },
|
||||
{ NS_X509CERTDB_CONTRACTID, &kNS_X509CERTDB_CID },
|
||||
{ NS_X509CERTLIST_CONTRACTID, &kNS_X509CERTLIST_CID },
|
||||
{ NS_NSSCERTCACHE_CONTRACTID, &kNS_NSSCERTCACHE_CID },
|
||||
{ NS_FORMPROCESSOR_CONTRACTID, &kNS_FORMPROCESSOR_CID },
|
||||
#ifdef MOZ_XUL
|
||||
{ NS_CERTTREE_CONTRACTID, &kNS_CERTTREE_CID },
|
||||
|
@ -20,10 +20,9 @@ function onUnload() {
|
||||
// does not cause assertion failures.
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
let certCache = Cc["@mozilla.org/security/nsscertcache;1"]
|
||||
.getService(Ci.nsINSSCertCache);
|
||||
certCache.cacheAllCerts();
|
||||
let certList = certCache.getX509CachedCerts();
|
||||
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
let certList = certdb.getCerts();
|
||||
let enumerator = certList.getEnumerator();
|
||||
ok(enumerator.hasMoreElements(), "we have at least one certificate");
|
||||
let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
|
||||
|
@ -217,10 +217,10 @@ private:
|
||||
void* const mStackTop;
|
||||
ThreadResponsiveness mRespInfo;
|
||||
|
||||
// Only Linux is using a signal sender, instead of stopping the thread, so we
|
||||
// Linux and OSX use a signal sender, instead of stopping the thread, so we
|
||||
// need some space to store the data which cannot be collected in the signal
|
||||
// handler code.
|
||||
#ifdef XP_LINUX
|
||||
#if defined(XP_LINUX) || defined(XP_MACOSX)
|
||||
public:
|
||||
int64_t mRssMemory;
|
||||
int64_t mUssMemory;
|
||||
|
@ -57,11 +57,38 @@ struct SamplerRegistry {
|
||||
|
||||
Sampler *SamplerRegistry::sampler = NULL;
|
||||
|
||||
// The following variables are used to communicate between the signal
|
||||
// sender thread and the signal handler on the sampled thread.
|
||||
//
|
||||
// sCurrentThreadProfile is used to pass the current thread profile INTO
|
||||
// the signal handler. sSignalHandlingDone is used by the handler to
|
||||
// indicate when it's finished. The signal-sender thread spins on
|
||||
// sSignalHandlingDone (using sched_yield). This is to avoid usage of
|
||||
// synchronization primitives like condvars in the signal handler code.
|
||||
static mozilla::Atomic<ThreadProfile*> sCurrentThreadProfile;
|
||||
static mozilla::Atomic<bool> sSignalHandlingDone;
|
||||
|
||||
#ifdef DEBUG
|
||||
// 0 is never a valid thread id on MacOSX since a pthread_t is a pointer.
|
||||
static const pthread_t kNoThread = (pthread_t) 0;
|
||||
#endif
|
||||
|
||||
static void SetSampleContext(TickSample* sample, void* context)
|
||||
{
|
||||
// Extracting the sample from the context is extremely machine dependent.
|
||||
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
|
||||
mcontext_t& mcontext = ucontext->uc_mcontext;
|
||||
#if defined(SPS_PLAT_amd64_darwin)
|
||||
sample->pc = reinterpret_cast<Address>(mcontext->__ss.__rip);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext->__ss.__rsp);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext->__ss.__rbp);
|
||||
#elif defined(SPS_PLAT_x86_darwin)
|
||||
sample->pc = reinterpret_cast<Address>(mcontext->__ss.__eip);
|
||||
sample->sp = reinterpret_cast<Address>(mcontext->__ss.__esp);
|
||||
sample->fp = reinterpret_cast<Address>(mcontext->__ss.__ebp);
|
||||
#endif
|
||||
}
|
||||
|
||||
void OS::Startup() {
|
||||
}
|
||||
|
||||
@ -133,6 +160,48 @@ void Thread::Join() {
|
||||
pthread_join(thread_, NULL);
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
|
||||
if (!Sampler::GetActiveSampler()) {
|
||||
sSignalHandlingDone = true;
|
||||
return;
|
||||
}
|
||||
|
||||
TickSample sample_obj;
|
||||
TickSample* sample = &sample_obj;
|
||||
sample->context = context;
|
||||
|
||||
// If profiling, we extract the current pc and sp.
|
||||
if (Sampler::GetActiveSampler()->IsProfiling()) {
|
||||
SetSampleContext(sample, context);
|
||||
}
|
||||
sample->threadProfile = sCurrentThreadProfile;
|
||||
sample->timestamp = mozilla::TimeStamp::Now();
|
||||
sample->rssMemory = sample->threadProfile->mRssMemory;
|
||||
sample->ussMemory = sample->threadProfile->mUssMemory;
|
||||
|
||||
Sampler::GetActiveSampler()->Tick(sample);
|
||||
|
||||
sCurrentThreadProfile = NULL;
|
||||
sSignalHandlingDone = true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
static void ProfilerSignalThread(ThreadProfile *profile,
|
||||
bool isFirstProfiledThread)
|
||||
{
|
||||
if (isFirstProfiledThread && Sampler::GetActiveSampler()->ProfileMemory()) {
|
||||
profile->mRssMemory = nsMemoryReporterManager::ResidentFast();
|
||||
profile->mUssMemory = nsMemoryReporterManager::ResidentUnique();
|
||||
} else {
|
||||
profile->mRssMemory = 0;
|
||||
profile->mUssMemory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class PlatformData : public Malloced {
|
||||
public:
|
||||
PlatformData() : profiled_thread_(mach_thread_self())
|
||||
@ -226,6 +295,9 @@ class SamplerThread : public Thread {
|
||||
info->Profile()->GetThreadResponsiveness()->Update();
|
||||
|
||||
ThreadProfile* thread_profile = info->Profile();
|
||||
sCurrentThreadProfile = thread_profile;
|
||||
|
||||
ProfilerSignalThread(sCurrentThreadProfile, isFirstProfiledThread);
|
||||
|
||||
SampleContext(SamplerRegistry::sampler, thread_profile,
|
||||
isFirstProfiledThread);
|
||||
@ -246,58 +318,15 @@ class SamplerThread : public Thread {
|
||||
void SampleContext(Sampler* sampler, ThreadProfile* thread_profile,
|
||||
bool isFirstProfiledThread)
|
||||
{
|
||||
thread_act_t profiled_thread =
|
||||
thread_profile->GetPlatformData()->profiled_thread();
|
||||
pthread_t profiled_pthread =
|
||||
thread_profile->GetPlatformData()->profiled_pthread();
|
||||
|
||||
TickSample sample_obj;
|
||||
TickSample* sample = &sample_obj;
|
||||
|
||||
if (isFirstProfiledThread && Sampler::GetActiveSampler()->ProfileMemory()) {
|
||||
sample->rssMemory = nsMemoryReporterManager::ResidentFast();
|
||||
} else {
|
||||
sample->rssMemory = 0;
|
||||
MOZ_ASSERT(sSignalHandlingDone == false);
|
||||
pthread_kill(profiled_pthread, SIGPROF);
|
||||
while (!sSignalHandlingDone) {
|
||||
sched_yield();
|
||||
}
|
||||
|
||||
// Unique Set Size is not supported on Mac.
|
||||
sample->ussMemory = 0;
|
||||
|
||||
if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
|
||||
|
||||
#if V8_HOST_ARCH_X64
|
||||
thread_state_flavor_t flavor = x86_THREAD_STATE64;
|
||||
x86_thread_state64_t state;
|
||||
mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
|
||||
#if __DARWIN_UNIX03
|
||||
#define REGISTER_FIELD(name) __r ## name
|
||||
#else
|
||||
#define REGISTER_FIELD(name) r ## name
|
||||
#endif // __DARWIN_UNIX03
|
||||
#elif V8_HOST_ARCH_IA32
|
||||
thread_state_flavor_t flavor = i386_THREAD_STATE;
|
||||
i386_thread_state_t state;
|
||||
mach_msg_type_number_t count = i386_THREAD_STATE_COUNT;
|
||||
#if __DARWIN_UNIX03
|
||||
#define REGISTER_FIELD(name) __e ## name
|
||||
#else
|
||||
#define REGISTER_FIELD(name) e ## name
|
||||
#endif // __DARWIN_UNIX03
|
||||
#else
|
||||
#error Unsupported Mac OS X host architecture.
|
||||
#endif // V8_HOST_ARCH
|
||||
|
||||
if (thread_get_state(profiled_thread,
|
||||
flavor,
|
||||
reinterpret_cast<natural_t*>(&state),
|
||||
&count) == KERN_SUCCESS) {
|
||||
sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
|
||||
sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
|
||||
sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
|
||||
sample->timestamp = mozilla::TimeStamp::Now();
|
||||
sample->threadProfile = thread_profile;
|
||||
|
||||
sampler->Tick(sample);
|
||||
}
|
||||
thread_resume(profiled_thread);
|
||||
sSignalHandlingDone = false;
|
||||
}
|
||||
|
||||
int intervalMicro_;
|
||||
@ -330,8 +359,29 @@ Sampler::~Sampler() {
|
||||
|
||||
void Sampler::Start() {
|
||||
ASSERT(!IsActive());
|
||||
|
||||
// Initialize signal handler communication
|
||||
sCurrentThreadProfile = NULL;
|
||||
sSignalHandlingDone = false;
|
||||
|
||||
// Request profiling signals.
|
||||
LOG("Request signal");
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = ProfilerSignalHandler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
if (sigaction(SIGPROF, &sa, &old_sigprof_signal_handler_) != 0) {
|
||||
LOG("Error installing signal");
|
||||
return;
|
||||
}
|
||||
signal_handler_installed_ = true;
|
||||
|
||||
// Start a thread that sends SIGPROF signal to VM thread.
|
||||
// Sending the signal ourselves instead of relying on itimer provides
|
||||
// much better accuracy.
|
||||
SetActive(true);
|
||||
SamplerThread::AddActiveSampler(this);
|
||||
LOG("Profiler thread started");
|
||||
}
|
||||
|
||||
|
||||
@ -339,6 +389,12 @@ void Sampler::Stop() {
|
||||
ASSERT(IsActive());
|
||||
SetActive(false);
|
||||
SamplerThread::RemoveActiveSampler(this);
|
||||
|
||||
// Restore old signal handler
|
||||
if (signal_handler_installed_) {
|
||||
sigaction(SIGPROF, &old_sigprof_signal_handler_, 0);
|
||||
signal_handler_installed_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_t
|
||||
|
@ -397,6 +397,10 @@ class Sampler {
|
||||
bool signal_sender_launched_;
|
||||
pthread_t signal_sender_thread_;
|
||||
#endif
|
||||
#if defined(SPS_OS_darwin)
|
||||
bool signal_handler_installed_;
|
||||
struct sigaction old_sigprof_signal_handler_;
|
||||
#endif
|
||||
};
|
||||
|
||||
class ThreadInfo {
|
||||
|
@ -536,7 +536,7 @@ public:
|
||||
int32_t aPanelX, int32_t aPanelY,
|
||||
nsString& aCommitted) override;
|
||||
|
||||
NS_IMETHOD SetPluginFocused(bool& aFocused);
|
||||
NS_IMETHOD SetPluginFocused(bool& aFocused) override;
|
||||
|
||||
bool IsPluginFocused() { return mPluginFocused; }
|
||||
|
||||
@ -560,6 +560,7 @@ protected:
|
||||
}
|
||||
|
||||
void ConfigureAPZCTreeManager() override;
|
||||
void ConfigureAPZControllerThread() override;
|
||||
|
||||
void DoRemoteComposition(const nsIntRect& aRenderRect);
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "HeapCopyOfStackArray.h"
|
||||
#include "mozilla/layers/APZCTreeManager.h"
|
||||
#include "mozilla/layers/APZThreadUtils.h"
|
||||
#include "mozilla/layers/GLManager.h"
|
||||
#include "mozilla/layers/CompositorOGL.h"
|
||||
#include "mozilla/layers/CompositorParent.h"
|
||||
@ -1890,6 +1891,14 @@ nsChildView::ConfigureAPZCTreeManager()
|
||||
gNumberOfWidgetsNeedingEventThread++;
|
||||
}
|
||||
|
||||
void
|
||||
nsChildView::ConfigureAPZControllerThread()
|
||||
{
|
||||
// On OS X the EventThreadRunner is the controller thread, but it doesn't
|
||||
// have a MessageLoop.
|
||||
APZThreadUtils::SetControllerThread(nullptr);
|
||||
}
|
||||
|
||||
nsIntRect
|
||||
nsChildView::RectContainingTitlebarControls()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user