Merge m-c to fx-team a=merge

This commit is contained in:
Wes Kocher 2015-04-08 17:35:18 -07:00
commit 57cb26988c
69 changed files with 683 additions and 348 deletions

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"
}

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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);
}
}
}

View File

@ -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;
};

View File

@ -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;

View File

@ -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.

View File

@ -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

View File

@ -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,

View File

@ -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.
*/

View File

@ -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

View File

@ -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)
{

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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"),

View File

@ -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,

View File

@ -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;
};

View File

@ -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)
{

View File

@ -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;
};

View File

@ -211,6 +211,9 @@ interface MozObjectLoadingContent {
*/
[ChromeOnly, Throws]
void cancelPlayPreview();
[ChromeOnly, Throws]
readonly attribute unsigned long runID;
};
/**

View File

@ -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/');
};
}

View File

@ -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();

View File

@ -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 {

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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)
{

View File

@ -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

View File

@ -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_;

View File

@ -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];

View File

@ -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_;

View File

@ -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;
/*

View File

@ -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); }

View File

@ -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;
}

View File

@ -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

View File

@ -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,

View 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

View File

@ -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

View File

@ -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++) {

View File

@ -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;

View File

@ -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);

View File

@ -18,7 +18,6 @@ XPIDL_SOURCES += [
'nsIGenKeypairInfoDlg.idl',
'nsIKeygenThread.idl',
'nsIKeyModule.idl',
'nsINSSCertCache.idl',
'nsINSSVersion.idl',
'nsIPK11Token.idl',
'nsIPK11TokenDB.idl',

View File

@ -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);
};

View File

@ -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"
%}

View File

@ -38,7 +38,6 @@ UNIFIED_SOURCES += [
'nsKeyModule.cpp',
'nsNSSASN1Object.cpp',
'nsNSSCallbacks.cpp',
'nsNSSCertCache.cpp',
'nsNSSCertHelper.cpp',
'nsNSSCertificate.cpp',
'nsNSSCertificateFakeTransport.cpp',

View File

@ -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();

View File

@ -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;

View File

@ -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();
}

View File

@ -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

View File

@ -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();
}

View File

@ -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"

View File

@ -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 },

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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 {

View File

@ -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);

View File

@ -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()
{