Merge last green changeset of mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2011-11-16 11:02:43 +00:00
Родитель 5b0b485be4 d42790d809
Коммит 0f2639a814
52 изменённых файлов: 816 добавлений и 363 удалений

Просмотреть файл

@ -137,7 +137,6 @@ let RemoteTabViewer = {
, title: title
, hiddenRows: [ "description"
, "location"
, "folderPicker"
, "loadInSidebar"
, "keyword" ]
}, window.top);

Просмотреть файл

@ -386,7 +386,6 @@ var PlacesCommandHook = {
, hiddenRows: [ "description"
, "location"
, "loadInSidebar"
, "folderPicker"
, "keyword" ]
}, window);
}

Просмотреть файл

@ -3163,7 +3163,6 @@ var bookmarksButtonObserver = {
, hiddenRows: [ "description"
, "location"
, "loadInSidebar"
, "folderPicker"
, "keyword" ]
}, window);
} catch(ex) { }
@ -5792,7 +5791,6 @@ function contentAreaClick(event, isPanelClick)
, loadBookmarkInSidebar: true
, hiddenRows: [ "description"
, "location"
, "folderPicker"
, "keyword" ]
}, window);
event.preventDefault();
@ -6839,8 +6837,9 @@ function AddKeywordForSearchField() {
, postData: postData
, charSet: charset
, hiddenRows: [ "location"
, "loadInSidebar"
, "folderPicker" ]
, "description"
, "tags"
, "loadInSidebar" ]
}, window);
}

Просмотреть файл

@ -1406,7 +1406,6 @@ nsContextMenu.prototype = {
, hiddenRows: [ "description"
, "location"
, "loadInSidebar"
, "folderPicker"
, "keyword" ]
}, window.top);
}

Просмотреть файл

@ -264,8 +264,6 @@ var BookmarkPropertiesPanel = {
NS_ASSERT("itemId" in dialogInfo);
this._itemId = dialogInfo.itemId;
this._title = PlacesUtils.bookmarks.getItemTitle(this._itemId);
// Don't show folderPicker when editing
this._hiddenRows.push("folderPicker");
this._readOnly = !!dialogInfo.readOnly;
switch (dialogInfo.type) {

Просмотреть файл

@ -309,7 +309,6 @@ PlacesController.prototype = {
, hiddenRows: [ "description"
, "keyword"
, "location"
, "folderPicker"
, "loadInSidebar" ]
, uri: NetUtil.newURI(node.uri)
, title: node.title
@ -721,6 +720,7 @@ PlacesController.prototype = {
, type: itemType
, itemId: itemId
, readOnly: isRootItem
, hiddenRows: [ "folderPicker" ]
}, window.top);
},

Просмотреть файл

@ -340,29 +340,36 @@ var PlacesUIUtils = {
* See documentation at the top of bookmarkProperties.js
* @param aWindow
* Owner window for the new dialog.
* @param aMinimalUI [optional]
* Whether to open the dialog in "minimal ui" mode. Do not pass this
* for new callers. It'll be removed in a future release.
* @param aResizable [optional]
* Whether the dialog is allowed to resize. Do not pass this for new
* callers since it's deprecated. It'll be removed in future releases.
*
* @see documentation at the top of bookmarkProperties.js
* @return true if any transaction has been performed, false otherwise.
*/
showBookmarkDialog:
function PUIU_showBookmarkDialog(aInfo, aParentWindow, aMinimalUI) {
function PUIU_showBookmarkDialog(aInfo, aParentWindow, aResizable) {
// This is a compatibility shim for add-ons. It will warn in the Error
// Console when used.
if (!aParentWindow) {
aParentWindow = this._getWindow(null);
}
// Preserve size attributes differently based on the fact the dialog has
// a folder picker or not.
let minimalUI = "hiddenRows" in aInfo &&
aInfo.hiddenRows.indexOf("folderPicker") != -1;
let dialogURL = aMinimalUI ?
// a folder picker or not. If the picker is visible, the dialog should
// be resizable since it may not show enough content for the folders
// hierarchy.
let hasFolderPicker = !("hiddenRows" in aInfo) ||
aInfo.hiddenRows.indexOf("folderPicker") == -1;
let resizable = aResizable !== undefined ? aResizable : hasFolderPicker;
// Use a different chrome url, since this allows to persist different sizes,
// based on resizability of the dialog.
let dialogURL = resizable ?
"chrome://browser/content/places/bookmarkProperties2.xul" :
"chrome://browser/content/places/bookmarkProperties.xul";
let features =
"centerscreen,chrome,modal,resizable=" + (aMinimalUI ? "yes" : "no");
"centerscreen,chrome,modal,resizable=" + (resizable ? "yes" : "no");
aParentWindow.openDialog(dialogURL, "", features, aInfo);
return ("performed" in aInfo && aInfo.performed);

Просмотреть файл

@ -110,9 +110,7 @@ function (aTitle, aContentURL, aCustomizeURL, aPersist)
, type: "bookmark"
, hiddenRows: [ "description"
, "keyword"
, "location"
, "folderPicker"
, "loadInSidebar" ]
, "location" ]
, uri: uri
, title: aTitle
, loadBookmarkInSidebar: true

Просмотреть файл

@ -1722,10 +1722,10 @@ public:
static bool IsFullScreenKeyInputRestricted();
/**
* Returns true if the doctree rooted at aDoc contains any plugins which
* we don't control event dispatch for, i.e. do any plugins in this doc tree
* receive key events outside of our control? This always returns false
* on MacOSX.
* Returns true if the doc tree branch which contains aDoc contains any
* plugins which we don't control event dispatch for, i.e. do any plugins
* in the same tab as this document receive key events outside of our
* control? This always returns false on MacOSX.
*/
static bool HasPluginWithUncontrolledEventDispatch(nsIDocument* aDoc);

Просмотреть файл

@ -5876,7 +5876,15 @@ nsContentUtils::HasPluginWithUncontrolledEventDispatch(nsIDocument* aDoc)
return false;
#endif
bool result = false;
DocTreeContainsWindowedPlugins(aDoc, &result);
// Find the top of the document's branch, the child of the chrome document.
nsIDocument* doc = aDoc;
nsIDocument* parent = nsnull;
while (doc && (parent = doc->GetParentDocument()) && !IsChromeDoc(parent)) {
doc = parent;
}
DocTreeContainsWindowedPlugins(doc, &result);
return result;
}

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<rect width="100" height="100" fill="blue">
<animate attributeName="fill"
begin="999999999999999999999999999999999999999999999999999999999999999999999999999999999"
dur="5s" from="blue" to="red" repeatCount="indefinite" additive="sum"/>
</rect>
</svg>

После

Ширина:  |  Высота:  |  Размер: 359 B

Просмотреть файл

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<rect width="100" height="100" fill="blue">
<animate attributeName="fill" id="a"
begin="4999999999999999" dur="5s" from="blue" to="red"
repeatCount="indefinite" additive="sum"/>
<animate attributeName="fill"
begin="a.begin+4999999999999999"
dur="5s" from="blue" to="red" repeatCount="indefinite" additive="sum"/>
</rect>
</svg>

После

Ширина:  |  Высота:  |  Размер: 452 B

Просмотреть файл

@ -43,5 +43,7 @@ load 678822-1.svg
load 678847-1.svg
load 678938-1.svg
load 690994-1.svg
load 691337-1.svg
load 691337-2.svg
load 697640-1.svg
load 699325-1.svg

Просмотреть файл

@ -730,7 +730,6 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
PRUint8 colonCount = 0;
bool started = false;
bool isValid = true;
PRInt32 metricMultiplicand = MSEC_PER_SEC;
@ -759,16 +758,14 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
} else if ((aFlags & kClockValueAllowSign)
&& (*start == '+' || *start == '-')) {
// check sign has not already been set
if (sign != 0) {
// sign has already been set
isValid = false;
break;
return NS_ERROR_FAILURE;
}
// check sign is not in middle of string
if (started) {
// sign appears in the middle of the string
isValid = false;
break;
return NS_ERROR_FAILURE;
}
sign = (*start == '+') ? 1 : -1;
@ -778,10 +775,8 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
prevNumCouldBeMin = numCouldBeMin;
if (!ParseClockComponent(start, end, component, numIsReal, numCouldBeMin,
numCouldBeSec)) {
isValid = false;
break;
}
numCouldBeSec))
return NS_ERROR_FAILURE;
started = true;
} else if (*start == ':') {
@ -789,31 +784,27 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
// Neither minutes nor hours can be reals
if (numIsReal) {
isValid = false;
break;
return NS_ERROR_FAILURE;
}
// Clock value can't start with a ':'
if (!started) {
isValid = false;
break;
return NS_ERROR_FAILURE;
}
// Can't have more than two colons
if (colonCount > 2) {
isValid = false;
break;
return NS_ERROR_FAILURE;
}
// Multiply the offset by 60 and add the last accumulated component
offset = offset * 60 + PRInt64(component);
offset = offset * 60 + nsSMILTime(component);
component = 0.0;
++start;
} else if (NS_IS_ALPHA(*start)) {
if (colonCount > 0) {
isValid = false;
break;
return NS_ERROR_FAILURE;
}
if ((aFlags & kClockValueAllowIndefinite)
@ -828,68 +819,68 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
} else if (aIsMedia && ConsumeSubstring(start, end, "media")) {
*aIsMedia = true;
} else if (!ParseMetricMultiplicand(start, end, metricMultiplicand)) {
isValid = false;
break;
return NS_ERROR_FAILURE;
}
// Nothing must come after the string except whitespace
break;
} else {
isValid = false;
break;
return NS_ERROR_FAILURE;
}
}
if (!started) {
isValid = false;
return NS_ERROR_FAILURE;
}
// Process remainder of string (if any) to ensure it is only trailing
// whitespace (embedded whitespace is not allowed)
SkipBeginWsp(start, end);
if (start != end) {
isValid = false;
return NS_ERROR_FAILURE;
}
// No more processing required if the value was "indefinite" or "media".
if (isIndefinite || (aIsMedia && *aIsMedia))
if (isIndefinite || (aIsMedia && *aIsMedia)) {
return NS_OK;
}
// If there is more than one colon then the previous component must be a
// correctly formatted minute (i.e. two digits between 00 and 59) and the
// latest component must be a correctly formatted second (i.e. two digits
// before the .)
if (colonCount > 0 && (!prevNumCouldBeMin || !numCouldBeSec)) {
isValid = false;
return NS_ERROR_FAILURE;
}
if (isValid) {
// Tack on the last component
if (colonCount > 0) {
offset = offset * 60 * 1000;
component *= 1000;
// rounding
component = (component >= 0) ? component + 0.5 : component - 0.5;
offset += PRInt64(component);
} else {
component *= metricMultiplicand;
// rounding
component = (component >= 0) ? component + 0.5 : component - 0.5;
offset = PRInt64(component);
}
if (aResult) {
nsSMILTime millis = offset;
if (sign == -1) {
millis = -offset;
}
aResult->SetMillis(millis);
}
// Tack on the last component
if (colonCount > 0) {
offset = offset * 60 * 1000;
component *= 1000;
// rounding
component = (component >= 0) ? component + 0.5 : component - 0.5;
offset += nsSMILTime(component);
} else {
component *= metricMultiplicand;
// rounding
component = (component >= 0) ? component + 0.5 : component - 0.5;
offset = nsSMILTime(component);
}
return (isValid) ? NS_OK : NS_ERROR_FAILURE;
// we haven't applied the sign yet so if the result is negative we must have
// overflowed
if (offset < 0) {
return NS_ERROR_FAILURE;
}
if (aResult) {
if (sign == -1) {
offset = -offset;
}
aResult->SetMillis(offset);
}
return NS_OK;
}
PRInt32

Просмотреть файл

@ -48,6 +48,7 @@
#include "nsGUIEvent.h"
#include "nsIDOMTimeEvent.h"
#include "nsString.h"
#include <limits>
using namespace mozilla::dom;
@ -182,8 +183,9 @@ nsSMILTimeValueSpec::HandleNewInterval(nsSMILInterval& aInterval,
ConvertBetweenTimeContainers(baseInstance.Time(), aSrcContainer);
// Apply offset
if (newTime.IsDefinite()) {
newTime.SetMillis(newTime.GetMillis() + mParams.mOffset.GetMillis());
if (!ApplyOffset(newTime)) {
NS_WARNING("New time overflows nsSMILTime, ignoring");
return;
}
// Create the instance time and register it with the interval
@ -218,9 +220,9 @@ nsSMILTimeValueSpec::HandleChangedInstanceTime(
ConvertBetweenTimeContainers(aBaseTime.Time(), aSrcContainer);
// Apply offset
if (updatedTime.IsDefinite()) {
updatedTime.SetMillis(updatedTime.GetMillis() +
mParams.mOffset.GetMillis());
if (!ApplyOffset(updatedTime)) {
NS_WARNING("Updated time overflows nsSMILTime, ignoring");
return;
}
// The timed element that owns the instance time does the updating so it can
@ -339,7 +341,7 @@ nsSMILTimeValueSpec::RegisterEventListener(Element* aTarget)
nsEventListenerManager* elm = GetEventListenerManager(aTarget);
if (!elm)
return;
elm->AddEventListenerByType(mEventListener,
nsDependentAtomString(mParams.mEventSymbol),
NS_EVENT_FLAG_BUBBLE |
@ -407,7 +409,11 @@ nsSMILTimeValueSpec::HandleEvent(nsIDOMEvent* aEvent)
return;
nsSMILTime currentTime = container->GetCurrentTime();
nsSMILTimeValue newTime(currentTime + mParams.mOffset.GetMillis());
nsSMILTimeValue newTime(currentTime);
if (!ApplyOffset(newTime)) {
NS_WARNING("New time generated from event overflows nsSMILTime, ignoring");
return;
}
nsRefPtr<nsSMILInstanceTime> newInstance =
new nsSMILInstanceTime(newTime, nsSMILInstanceTime::SOURCE_EVENT);
@ -535,3 +541,21 @@ nsSMILTimeValueSpec::ConvertBetweenTimeContainers(
return dstContainer->ParentToContainerTime(docTime.GetMillis());
}
bool
nsSMILTimeValueSpec::ApplyOffset(nsSMILTimeValue& aTime) const
{
// indefinite + offset = indefinite. Likewise for unresolved times.
if (!aTime.IsDefinite()) {
return true;
}
double resultAsDouble =
(double)aTime.GetMillis() + mParams.mOffset.GetMillis();
if (resultAsDouble > std::numeric_limits<nsSMILTime>::max() ||
resultAsDouble < std::numeric_limits<nsSMILTime>::min()) {
return false;
}
aTime.SetMillis(aTime.GetMillis() + mParams.mOffset.GetMillis());
return true;
}

Просмотреть файл

@ -102,6 +102,7 @@ protected:
bool CheckAccessKeyEventDetail(nsIDOMEvent* aEvent);
nsSMILTimeValue ConvertBetweenTimeContainers(const nsSMILTimeValue& aSrcTime,
const nsSMILTimeContainer* aSrcContainer);
bool ApplyOffset(nsSMILTimeValue& aTime) const;
nsSMILTimedElement* mOwner;
bool mIsBegin; // Indicates if *we* are a begin spec,

Просмотреть файл

@ -1888,9 +1888,9 @@ nsSMILTimedElement::ActiveTimeToSimpleTime(nsSMILTime aActiveTime,
{
nsSMILTime result;
NS_ASSERTION(mSimpleDur.IsResolved(),
NS_ABORT_IF_FALSE(mSimpleDur.IsResolved(),
"Unresolved simple duration in ActiveTimeToSimpleTime");
NS_ASSERTION(aActiveTime >= 0, "Expecting non-negative active time");
NS_ABORT_IF_FALSE(aActiveTime >= 0, "Expecting non-negative active time");
// Note that a negative aActiveTime will give us a negative value for
// aRepeatIteration, which is bad because aRepeatIteration is unsigned

Просмотреть файл

@ -28,7 +28,15 @@ const INITIAL_VAL = "500px"
const FROM_VAL = "20px";
const TO_VAL = "80px";
// Helper function
// Helper functions
// This function allows 10ms to pass
function allowTimeToPass() {
var initialDate = new Date();
while (new Date() - initialDate < 10) {}
}
// This function returns a newly created <animate> element for use in this test
function createAnim() {
var a = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
a.setAttribute('attributeName', 'width');
@ -50,13 +58,18 @@ function main() {
// In unpatched Firefox builds, we'll only trigger Bug 699143 if we insert
// an animation and call beginElement() **after** the document start-time.
// Hence, we use executeSoon here to allow some time to pass.
// Hence, we use executeSoon here to allow some time to pass. (And then
// we'll use a short busy-loop, for good measure.)
SimpleTest.executeSoon(runTest);
}
function runTest() {
var svg = SMILUtil.getSVGRoot();
// In case our executeSoon fired immediately, we force a very small amount
// of time to pass here, using a 10ms busy-loop.
allowTimeToPass();
is(svg.getCurrentTime(), 0,
"even though we've allowed time to pass, we shouldn't have bothered " +
"updating the current time, since there aren't any animation elements");

Просмотреть файл

@ -43,6 +43,8 @@
#include "mozilla/layers/PLayersParent.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/Types.h"
#include "ipc/ShadowLayerChild.h"
#include "BasicLayers.h"
@ -2209,17 +2211,17 @@ private:
return static_cast<BasicShadowLayerManager*>(mManager);
}
NS_OVERRIDE virtual void
virtual void
PaintBuffer(gfxContext* aContext,
const nsIntRegion& aRegionToDraw,
const nsIntRegion& aExtendedRegionToDraw,
const nsIntRegion& aRegionToInvalidate,
bool aDidSelfCopy,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData);
void* aCallbackData) MOZ_OVERRIDE;
NS_OVERRIDE virtual already_AddRefed<gfxASurface>
CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize);
virtual already_AddRefed<gfxASurface>
CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize) MOZ_OVERRIDE;
void DestroyBackBuffer()
{

Просмотреть файл

@ -147,7 +147,7 @@ bool ParseFeatureTable(const uint8_t *data, const size_t length,
}
const unsigned feature_table_end =
2 * static_cast<unsigned>(num_lookups) + 4;
2 * static_cast<unsigned>(lookup_count) + 4;
if (feature_table_end > std::numeric_limits<uint16_t>::max()) {
return OTS_FAILURE();
}

Просмотреть файл

@ -1078,7 +1078,8 @@ qcms_transform* qcms_transform_precacheLUT_float(qcms_transform *transform, qcms
//XXX: qcms_modular_transform_data may return either the src or dest buffer. If so it must not be free-ed
if (src && lut != src) {
free(src);
} else if (dest && lut != src) {
}
if (dest && lut != dest) {
free(dest);
}

Просмотреть файл

@ -1,5 +1,4 @@
var currentTest;
var gIsImageLoaded = false;
var gIsRefImageLoaded = false;
function pollForSuccess ()
@ -14,11 +13,6 @@ function pollForSuccess ()
}
};
function imageLoadCallback()
{
gIsImageLoaded = true;
}
function referencePoller()
{
currentTest.takeReferenceSnapshot();
@ -30,7 +24,8 @@ function reuseImageCallback()
}
function failTest ()
{
{ imageLoadCallback();
if (currentTest.isTestFinished || currentTest.closeFunc) {
return;
}
@ -110,15 +105,18 @@ function AnimationTest(pollFreq, timeout, referenceElementId, imageElementId,
this.cleanId = cleanId ? cleanId : '';
this.xulTest = xulTest ? xulTest : '';
this.closeFunc = closeFunc ? closeFunc : '';
};
AnimationTest.prototype.preloadImage = function()
{
if (this.srcAttr) {
this.myImage = new Image();
this.myImage.onload = imageLoadCallback;
this.myImage.onload = function() { currentTest.continueTest(); };
this.myImage.src = this.srcAttr;
} else {
gIsImageLoaded = true;
this.continueTest();
}
}
};
AnimationTest.prototype.outputDebugInfo = function(message, id, dataUri)
{
@ -176,16 +174,25 @@ AnimationTest.prototype.takeBlankSnapshot = function()
/**
* Begin the AnimationTest. This will utilize the information provided in the
* constructor to invoke a mochitest on animated images. It will automatically
* fail if allowed to run past the timeout.
* fail if allowed to run past the timeout. This will attempt to preload an
* image, if applicable, and then asynchronously call continueTest(), or if not
* applicable, synchronously trigger a call to continueTest().
*/
AnimationTest.prototype.beginTest = function ()
AnimationTest.prototype.beginTest = function()
{
SimpleTest.waitForExplicitFinish();
currentTest = this;
this.preloadImage();
};
this.takeReferenceSnapshot();
/**
* This is the second part of the test. It is triggered (eventually) from
* beginTest() either synchronously or asynchronously, as an image load
* callback.
*/
AnimationTest.prototype.continueTest = function()
{
// In case something goes wrong, fail earlier than mochitest timeout,
// and with more information.
setTimeout(failTest, this.timeout);
@ -194,6 +201,7 @@ AnimationTest.prototype.beginTest = function ()
this.disableDisplay(document.getElementById(this.imageElementId));
}
this.takeReferenceSnapshot();
this.setupPolledImage();
setTimeout(pollForSuccess, 10);
};
@ -273,6 +281,7 @@ AnimationTest.prototype.takeReferenceSnapshot = function ()
this.enableDisplay(referenceDiv);
this.referenceSnapshot = snapshotWindow(window, false);
var snapResult = compareSnapshots(this.cleanSnapshot, this.referenceSnapshot,
false);
if (!snapResult[0]) {

Просмотреть файл

@ -40,7 +40,7 @@ const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main() {
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceDiv',
'embeddedSVG', 'debug', '', 'src');
'embeddedSVG', 'debug', '');
animTest.beginTest();
}

Просмотреть файл

@ -30,7 +30,7 @@ const FAILURE_TIMEOUT = 120000; // Fail early after 120 seconds (2 minutes)
function main() {
var animTest = new AnimationTest(20, FAILURE_TIMEOUT, 'referenceImage',
'embeddedSVGFilt', 'debug', '', 'src');
'embeddedSVGFilt', 'debug', '');
animTest.beginTest();
}

Просмотреть файл

@ -723,6 +723,8 @@ JSRuntime::JSRuntime()
functionNamespaceObject(NULL),
#ifdef JS_THREADSAFE
interruptCounter(0),
#else
threadData(thisFromCtor()),
#endif
trustedPrincipals_(NULL),
shapeGen(0),

Просмотреть файл

@ -87,6 +87,7 @@
#endif
#include "frontend/TokenStream.h"
#include "frontend/ParseMaps.h"
#include "yarr/BumpPointerAllocator.h"
#include "jsatominlines.h"
#include "jscntxtinlines.h"
@ -98,8 +99,9 @@ using namespace js::gc;
namespace js {
ThreadData::ThreadData()
: interruptFlags(0),
ThreadData::ThreadData(JSRuntime *rt)
: rt(rt),
interruptFlags(0),
#ifdef JS_THREADSAFE
requestDepth(0),
#endif
@ -111,6 +113,8 @@ ThreadData::ThreadData()
#endif
waiveGCQuota(false),
tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
execAlloc(NULL),
bumpAlloc(NULL),
repCache(NULL),
dtoaState(NULL),
nativeStackBase(GetNativeStackBase()),
@ -126,6 +130,9 @@ ThreadData::~ThreadData()
{
JS_ASSERT(!repCache);
rt->delete_<JSC::ExecutableAllocator>(execAlloc);
rt->delete_<WTF::BumpPointerAllocator>(bumpAlloc);
if (dtoaState)
js_DestroyDtoaState(dtoaState);
}
@ -140,6 +147,8 @@ ThreadData::init()
void
ThreadData::triggerOperationCallback(JSRuntime *rt)
{
JS_ASSERT(rt == this->rt);
/*
* Use JS_ATOMIC_SET and JS_ATOMIC_INCREMENT in the hope that it ensures
* the write will become immediately visible to other processors polling
@ -157,13 +166,40 @@ ThreadData::triggerOperationCallback(JSRuntime *rt)
#endif
}
JSC::ExecutableAllocator *
ThreadData::createExecutableAllocator(JSContext *cx)
{
JS_ASSERT(!execAlloc);
JS_ASSERT(cx->runtime == rt);
execAlloc = rt->new_<JSC::ExecutableAllocator>();
if (!execAlloc)
js_ReportOutOfMemory(cx);
return execAlloc;
}
WTF::BumpPointerAllocator *
ThreadData::createBumpPointerAllocator(JSContext *cx)
{
JS_ASSERT(!bumpAlloc);
JS_ASSERT(cx->runtime == rt);
bumpAlloc = rt->new_<WTF::BumpPointerAllocator>();
if (!bumpAlloc)
js_ReportOutOfMemory(cx);
return bumpAlloc;
}
RegExpPrivateCache *
ThreadData::createRegExpPrivateCache(JSRuntime *rt)
ThreadData::createRegExpPrivateCache(JSContext *cx)
{
JS_ASSERT(!repCache);
JS_ASSERT(cx->runtime == rt);
RegExpPrivateCache *newCache = rt->new_<RegExpPrivateCache>(rt);
if (!newCache || !newCache->init()) {
js_ReportOutOfMemory(cx);
rt->delete_<RegExpPrivateCache>(newCache);
return NULL;
}
@ -173,7 +209,7 @@ ThreadData::createRegExpPrivateCache(JSRuntime *rt)
}
void
ThreadData::purgeRegExpPrivateCache(JSRuntime *rt)
ThreadData::purgeRegExpPrivateCache()
{
rt->delete_<RegExpPrivateCache>(repCache);
repCache = NULL;
@ -223,7 +259,7 @@ js_CurrentThreadAndLockGC(JSRuntime *rt)
} else {
JS_UNLOCK_GC(rt);
thread = OffTheBooks::new_<JSThread>(id);
thread = OffTheBooks::new_<JSThread>(rt, id);
if (!thread || !thread->init()) {
Foreground::delete_(thread);
return NULL;
@ -352,10 +388,10 @@ js_PurgeThreads_PostGlobalSweep(JSContext *cx)
JSThread *thread = e.front().value;
JS_ASSERT(!JS_CLIST_IS_EMPTY(&thread->contextList));
thread->data.purgeRegExpPrivateCache(cx->runtime);
thread->data.purgeRegExpPrivateCache();
}
#else
cx->runtime->threadData.purgeRegExpPrivateCache(cx->runtime);
cx->runtime->threadData.purgeRegExpPrivateCache();
#endif
}

Просмотреть файл

@ -153,6 +153,8 @@ struct PendingProxyOperation {
};
struct ThreadData {
JSRuntime *rt;
/*
* If non-zero, we were been asked to call the operation callback as soon
* as possible. If the thread has an active request, this contributes
@ -198,23 +200,45 @@ struct ThreadData {
LifoAlloc tempLifoAlloc;
private:
js::RegExpPrivateCache *repCache;
/*
* Both of these allocators are used for regular expression code which is shared at the
* thread-data level.
*/
JSC::ExecutableAllocator *execAlloc;
WTF::BumpPointerAllocator *bumpAlloc;
js::RegExpPrivateCache *repCache;
js::RegExpPrivateCache *createRegExpPrivateCache(JSRuntime *rt);
JSC::ExecutableAllocator *createExecutableAllocator(JSContext *cx);
WTF::BumpPointerAllocator *createBumpPointerAllocator(JSContext *cx);
js::RegExpPrivateCache *createRegExpPrivateCache(JSContext *cx);
public:
js::RegExpPrivateCache *getRegExpPrivateCache() { return repCache; }
JSC::ExecutableAllocator *getOrCreateExecutableAllocator(JSContext *cx) {
if (execAlloc)
return execAlloc;
/* N.B. caller is responsible for reporting OOM. */
js::RegExpPrivateCache *getOrCreateRegExpPrivateCache(JSRuntime *rt) {
return createExecutableAllocator(cx);
}
WTF::BumpPointerAllocator *getOrCreateBumpPointerAllocator(JSContext *cx) {
if (bumpAlloc)
return bumpAlloc;
return createBumpPointerAllocator(cx);
}
js::RegExpPrivateCache *getRegExpPrivateCache() {
return repCache;
}
js::RegExpPrivateCache *getOrCreateRegExpPrivateCache(JSContext *cx) {
if (repCache)
return repCache;
return createRegExpPrivateCache(rt);
return createRegExpPrivateCache(cx);
}
/* Called at the end of the global GC sweep phase to deallocate repCache memory. */
void purgeRegExpPrivateCache(JSRuntime *rt);
void purgeRegExpPrivateCache();
/*
* The GSN cache is per thread since even multi-cx-per-thread embeddings
@ -240,7 +264,7 @@ struct ThreadData {
size_t noGCOrAllocationCheck;
#endif
ThreadData();
ThreadData(JSRuntime *rt);
~ThreadData();
bool init();
@ -297,12 +321,13 @@ struct JSThread {
/* Factored out of JSThread for !JS_THREADSAFE embedding in JSRuntime. */
js::ThreadData data;
JSThread(void *id)
JSThread(JSRuntime *rt, void *id)
: id(id),
suspendCount(0)
suspendCount(0),
# ifdef DEBUG
, checkRequestDepth(0)
checkRequestDepth(0),
# endif
data(rt)
{
JS_INIT_CLIST(&contextList);
}

Просмотреть файл

@ -87,9 +87,6 @@ JSCompartment::JSCompartment(JSRuntime *rt)
hasDebugModeCodeToDrop(false),
#ifdef JS_METHODJIT
jaegerCompartment_(NULL),
#endif
#if ENABLE_YARR_JIT
regExpAllocator(NULL),
#endif
propertyTree(thisForCtor()),
emptyArgumentsShape(NULL),
@ -110,10 +107,6 @@ JSCompartment::JSCompartment(JSRuntime *rt)
JSCompartment::~JSCompartment()
{
#if ENABLE_YARR_JIT
Foreground::delete_(regExpAllocator);
#endif
#ifdef JS_METHODJIT
Foreground::delete_(jaegerCompartment_);
#endif
@ -143,10 +136,6 @@ JSCompartment::init(JSContext *cx)
if (!scriptFilenameTable.init())
return false;
regExpAllocator = rt->new_<WTF::BumpPointerAllocator>();
if (!regExpAllocator)
return false;
if (!backEdgeTable.init())
return false;

Просмотреть файл

@ -53,9 +53,6 @@
#pragma warning(disable:4251) /* Silence warning about JS_FRIEND_API and data members. */
#endif
namespace JSC { class ExecutableAllocator; }
namespace WTF { class BumpPointerAllocator; }
namespace js {
/* Holds the number of recording attemps for an address. */
@ -473,7 +470,6 @@ struct JS_FRIEND_API(JSCompartment) {
void getMjitCodeStats(size_t& method, size_t& regexp, size_t& unused) const;
#endif
WTF::BumpPointerAllocator *regExpAllocator;
/*
* Shared scope property tree, and arena-pool for allocating its nodes.

Просмотреть файл

@ -2400,36 +2400,32 @@ DecommitFreePages(JSContext *cx)
for (GCChunkSet::Range r(rt->gcChunkSet.all()); !r.empty(); r.popFront()) {
Chunk *chunk = r.front();
while (chunk) {
ArenaHeader *aheader = static_cast<ArenaHeader*>(chunk->info.freeArenasHead);
ArenaHeader *aheader = chunk->info.freeArenasHead;
/*
* In the non-failure case, the list will be gone at the end of
* the loop. In the case where we fail, we relink all failed
* decommits into a new list on freeArenasHead.
*/
chunk->info.freeArenasHead = NULL;
/*
* In the non-failure case, the list will be gone at the end of
* the loop. In the case where we fail, we relink all failed
* decommits into a new list on freeArenasHead.
*/
chunk->info.freeArenasHead = NULL;
while (aheader) {
/* Store aside everything we will need after decommit. */
ArenaHeader *next = aheader->next;
while (aheader) {
/* Store aside everything we will need after decommit. */
ArenaHeader *next = aheader->next;
bool success = DecommitMemory(aheader, ArenaSize);
if (!success) {
aheader->next = chunk->info.freeArenasHead;
chunk->info.freeArenasHead = aheader;
continue;
}
size_t arenaOffset = Chunk::arenaIndex(reinterpret_cast<uintptr_t>(aheader));
chunk->decommittedArenas.set(arenaOffset);
--chunk->info.numArenasFreeCommitted;
--rt->gcNumFreeArenas;
aheader = next;
bool success = DecommitMemory(aheader, ArenaSize);
if (!success) {
aheader->next = chunk->info.freeArenasHead;
chunk->info.freeArenasHead = aheader;
continue;
}
chunk = chunk->info.next;
size_t arenaIndex = Chunk::arenaIndex(aheader->arenaAddress());
chunk->decommittedArenas.set(arenaIndex);
--chunk->info.numArenasFreeCommitted;
--rt->gcNumFreeArenas;
aheader = next;
}
}
}

Просмотреть файл

@ -269,6 +269,18 @@ struct TypeCompartment;
} /* namespace js */
namespace JSC {
class ExecutableAllocator;
} /* namespace JSC */
namespace WTF {
class BumpPointerAllocator;
} /* namespace WTF */
} /* export "C++" */
#else

Просмотреть файл

@ -42,6 +42,8 @@
#ifndef jswrapper_h___
#define jswrapper_h___
#include "mozilla/Types.h"
#include "jsapi.h"
#include "jsproxy.h"
@ -62,37 +64,37 @@ class JS_FRIEND_API(Wrapper) : public ProxyHandler
/* ES5 Harmony fundamental wrapper traps. */
virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
PropertyDescriptor *desc);
PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
PropertyDescriptor *desc);
PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
PropertyDescriptor *desc);
virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
virtual bool fix(JSContext *cx, JSObject *wrapper, Value *vp);
PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
virtual bool fix(JSContext *cx, JSObject *wrapper, Value *vp) MOZ_OVERRIDE;
/* ES5 Harmony derived wrapper traps. */
virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp);
virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) MOZ_OVERRIDE;
virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict,
Value *vp);
virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp);
Value *vp) MOZ_OVERRIDE;
virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp) MOZ_OVERRIDE;
/* Spidermonkey extensions. */
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp);
virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval);
virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args);
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp);
virtual JSType typeOf(JSContext *cx, JSObject *proxy);
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp);
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval) MOZ_OVERRIDE;
virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
virtual JSType typeOf(JSContext *cx, JSObject *proxy) MOZ_OVERRIDE;
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE;
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent) MOZ_OVERRIDE;
virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp) MOZ_OVERRIDE;
virtual void trace(JSTracer *trc, JSObject *wrapper);
virtual void trace(JSTracer *trc, JSObject *wrapper) MOZ_OVERRIDE;
/* Policy enforcement traps. */
enum Action { GET, SET, CALL };
@ -125,34 +127,34 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
/* ES5 Harmony fundamental wrapper traps. */
virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
PropertyDescriptor *desc);
PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id, bool set,
PropertyDescriptor *desc);
PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool defineProperty(JSContext *cx, JSObject *wrapper, jsid id,
PropertyDescriptor *desc);
virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
PropertyDescriptor *desc) MOZ_OVERRIDE;
virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
virtual bool delete_(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
virtual bool enumerate(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
/* ES5 Harmony derived wrapper traps. */
virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp);
virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp);
virtual bool has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
virtual bool hasOwn(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) MOZ_OVERRIDE;
virtual bool get(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, Value *vp) MOZ_OVERRIDE;
virtual bool set(JSContext *cx, JSObject *wrapper, JSObject *receiver, jsid id, bool strict,
Value *vp);
virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props);
virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp);
Value *vp) MOZ_OVERRIDE;
virtual bool keys(JSContext *cx, JSObject *wrapper, AutoIdVector &props) MOZ_OVERRIDE;
virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp) MOZ_OVERRIDE;
/* Spidermonkey extensions. */
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp);
virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval);
virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args);
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp);
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp);
virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval) MOZ_OVERRIDE;
virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp) MOZ_OVERRIDE;
virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent) MOZ_OVERRIDE;
virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp) MOZ_OVERRIDE;
virtual void trace(JSTracer *trc, JSObject *wrapper);
virtual void trace(JSTracer *trc, JSObject *wrapper) MOZ_OVERRIDE;
static CrossCompartmentWrapper singleton;
};
@ -172,8 +174,8 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
public:
SecurityWrapper(uintN flags);
virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args);
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) MOZ_OVERRIDE;
virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx) MOZ_OVERRIDE;
};
typedef SecurityWrapper<Wrapper> SameCompartmentSecurityWrapper;

Просмотреть файл

@ -248,7 +248,7 @@ RegExpObject::setSticky(bool enabled)
inline RegExpPrivateCache *
detail::RegExpPrivate::getOrCreateCache(JSContext *cx)
{
if (RegExpPrivateCache *cache = cx->threadData()->getOrCreateRegExpPrivateCache(cx->runtime))
if (RegExpPrivateCache *cache = cx->threadData()->getOrCreateRegExpPrivateCache(cx))
return cache;
js_ReportOutOfMemory(cx);
@ -379,18 +379,27 @@ detail::RegExpPrivateCode::compile(JSContext *cx, JSLinearString &pattern, Token
#ifdef JS_METHODJIT
if (isJITRuntimeEnabled(cx) && !yarrPattern.m_containsBackreferences) {
if (!cx->compartment->ensureJaegerCompartmentExists(cx))
JSC::ExecutableAllocator *execAlloc = cx->threadData()->getOrCreateExecutableAllocator(cx);
if (!execAlloc) {
js_ReportOutOfMemory(cx);
return false;
}
JSGlobalData globalData(cx->compartment->jaegerCompartment()->execAlloc());
JSGlobalData globalData(execAlloc);
jitCompile(yarrPattern, &globalData, codeBlock);
if (!codeBlock.isFallBack())
return true;
}
#endif
WTF::BumpPointerAllocator *bumpAlloc = cx->threadData()->getOrCreateBumpPointerAllocator(cx);
if (!bumpAlloc) {
js_ReportOutOfMemory(cx);
return false;
}
codeBlock.setFallBack(true);
byteCode = byteCompile(yarrPattern, cx->compartment->regExpAllocator).get();
byteCode = byteCompile(yarrPattern, bumpAlloc).get();
return true;
#else /* !defined(ENABLE_YARR_JIT) */
int error = 0;

Просмотреть файл

@ -2023,8 +2023,8 @@ public:
data.gcHeapUnusedPercentage,
"Fraction of the garbage-collected JavaScript heap that is unused. "
"Computed as ('js-gc-heap-chunk-clean-unused' + "
"'js-gc-heap-chunk-dirty-unused' + 'js-gc-heap-arena-unused') / "
"'js-gc-heap'.",
"'js-gc-heap-chunk-dirty-unused' + 'js-gc-heap-decommitted' + "
"'js-gc-heap-arena-unused') / 'js-gc-heap'.",
callback, closure);
ReportMemoryBytes(NS_LITERAL_CSTRING("js-total-objects"),

Просмотреть файл

@ -99,41 +99,41 @@ random-if(!winWidget) == arial-bold-lam-alef-1.html arial-bold-lam-alef-1-ref.ht
== auto-hyphenation-5.html auto-hyphenation-5-ref.html
== auto-hyphenation-6.html auto-hyphenation-6-ref.html
== auto-hyphenation-7.html auto-hyphenation-7-ref.html
# Android ships only the en-US hyphenation dictionary
skip-if(Android) == auto-hyphenation-af-1.html auto-hyphenation-af-1-ref.html
skip-if(Android) == auto-hyphenation-bg-1.html auto-hyphenation-bg-1-ref.html
skip-if(Android) == auto-hyphenation-ca-1.html auto-hyphenation-ca-1-ref.html
skip-if(Android) == auto-hyphenation-cy-1.html auto-hyphenation-cy-1-ref.html
skip-if(Android) == auto-hyphenation-da-1.html auto-hyphenation-da-1-ref.html
skip-if(Android) == auto-hyphenation-de-1901-1.html auto-hyphenation-de-1901-1-ref.html
skip-if(Android) == auto-hyphenation-de-1996-1.html auto-hyphenation-de-1996-1-ref.html
skip-if(Android) != auto-hyphenation-de-1901-1.html auto-hyphenation-de-1996-1.html
skip-if(Android) == auto-hyphenation-de-ch-1.html auto-hyphenation-de-ch-1-ref.html
skip-if(Android) == auto-hyphenation-eo-1.html auto-hyphenation-eo-1-ref.html
skip-if(Android) == auto-hyphenation-es-1.html auto-hyphenation-es-1-ref.html
skip-if(Android) == auto-hyphenation-et-1.html auto-hyphenation-et-1-ref.html
skip-if(Android) == auto-hyphenation-fi-1.html auto-hyphenation-fi-1-ref.html
skip-if(Android) == auto-hyphenation-fr-1.html auto-hyphenation-fr-1-ref.html
skip-if(Android) == auto-hyphenation-gl-1.html auto-hyphenation-gl-1-ref.html
skip-if(Android) == auto-hyphenation-hr-1.html auto-hyphenation-hr-1-ref.html
skip-if(Android) == auto-hyphenation-hsb-1.html auto-hyphenation-hsb-1-ref.html
skip-if(Android) == auto-hyphenation-hu-1.html auto-hyphenation-hu-1-ref.html
skip-if(Android) == auto-hyphenation-ia-1.html auto-hyphenation-ia-1-ref.html
skip-if(Android) == auto-hyphenation-is-1.html auto-hyphenation-is-1-ref.html
skip-if(Android) == auto-hyphenation-it-1.html auto-hyphenation-it-1-ref.html
skip-if(Android) == auto-hyphenation-kmr-1.html auto-hyphenation-kmr-1-ref.html
skip-if(Android) == auto-hyphenation-la-1.html auto-hyphenation-la-1-ref.html
skip-if(Android) == auto-hyphenation-lt-1.html auto-hyphenation-lt-1-ref.html
skip-if(Android) == auto-hyphenation-mn-1.html auto-hyphenation-mn-1-ref.html
skip-if(Android) == auto-hyphenation-nb-1.html auto-hyphenation-nb-1-ref.html
skip-if(Android) == auto-hyphenation-nl-1.html auto-hyphenation-nl-1-ref.html
skip-if(Android) == auto-hyphenation-nn-1.html auto-hyphenation-nn-1-ref.html
skip-if(Android) == auto-hyphenation-pt-1.html auto-hyphenation-pt-1-ref.html
skip-if(Android) == auto-hyphenation-ru-1.html auto-hyphenation-ru-1-ref.html
skip-if(Android) == auto-hyphenation-sh-1.html auto-hyphenation-sh-1-ref.html
skip-if(Android) == auto-hyphenation-sl-1.html auto-hyphenation-sl-1-ref.html
skip-if(Android) == auto-hyphenation-sr-1.html auto-hyphenation-sr-1-ref.html
skip-if(Android) == auto-hyphenation-sv-1.html auto-hyphenation-sv-1-ref.html # test swedish patterns
skip-if(Android) != auto-hyphenation-sv-1.html auto-hyphenation-sv-1-notref.html # verify swedish != english
skip-if(Android) == auto-hyphenation-tr-1.html auto-hyphenation-tr-1-ref.html
skip-if(Android) == auto-hyphenation-uk-1.html auto-hyphenation-uk-1-ref.html
== auto-hyphenation-af-1.html auto-hyphenation-af-1-ref.html
== auto-hyphenation-bg-1.html auto-hyphenation-bg-1-ref.html
== auto-hyphenation-ca-1.html auto-hyphenation-ca-1-ref.html
== auto-hyphenation-cy-1.html auto-hyphenation-cy-1-ref.html
== auto-hyphenation-da-1.html auto-hyphenation-da-1-ref.html
== auto-hyphenation-de-1901-1.html auto-hyphenation-de-1901-1-ref.html
== auto-hyphenation-de-1996-1.html auto-hyphenation-de-1996-1-ref.html
!= auto-hyphenation-de-1901-1.html auto-hyphenation-de-1996-1.html
== auto-hyphenation-de-ch-1.html auto-hyphenation-de-ch-1-ref.html
== auto-hyphenation-eo-1.html auto-hyphenation-eo-1-ref.html
== auto-hyphenation-es-1.html auto-hyphenation-es-1-ref.html
== auto-hyphenation-et-1.html auto-hyphenation-et-1-ref.html
== auto-hyphenation-fi-1.html auto-hyphenation-fi-1-ref.html
== auto-hyphenation-fr-1.html auto-hyphenation-fr-1-ref.html
== auto-hyphenation-gl-1.html auto-hyphenation-gl-1-ref.html
== auto-hyphenation-hr-1.html auto-hyphenation-hr-1-ref.html
== auto-hyphenation-hsb-1.html auto-hyphenation-hsb-1-ref.html
== auto-hyphenation-hu-1.html auto-hyphenation-hu-1-ref.html
== auto-hyphenation-ia-1.html auto-hyphenation-ia-1-ref.html
== auto-hyphenation-is-1.html auto-hyphenation-is-1-ref.html
== auto-hyphenation-it-1.html auto-hyphenation-it-1-ref.html
== auto-hyphenation-kmr-1.html auto-hyphenation-kmr-1-ref.html
== auto-hyphenation-la-1.html auto-hyphenation-la-1-ref.html
== auto-hyphenation-lt-1.html auto-hyphenation-lt-1-ref.html
== auto-hyphenation-mn-1.html auto-hyphenation-mn-1-ref.html
== auto-hyphenation-nb-1.html auto-hyphenation-nb-1-ref.html
== auto-hyphenation-nl-1.html auto-hyphenation-nl-1-ref.html
== auto-hyphenation-nn-1.html auto-hyphenation-nn-1-ref.html
== auto-hyphenation-pt-1.html auto-hyphenation-pt-1-ref.html
== auto-hyphenation-ru-1.html auto-hyphenation-ru-1-ref.html
== auto-hyphenation-sh-1.html auto-hyphenation-sh-1-ref.html
== auto-hyphenation-sl-1.html auto-hyphenation-sl-1-ref.html
== auto-hyphenation-sr-1.html auto-hyphenation-sr-1-ref.html
== auto-hyphenation-sv-1.html auto-hyphenation-sv-1-ref.html # test swedish patterns
!= auto-hyphenation-sv-1.html auto-hyphenation-sv-1-notref.html # verify swedish != english
== auto-hyphenation-tr-1.html auto-hyphenation-tr-1-ref.html
== auto-hyphenation-uk-1.html auto-hyphenation-uk-1-ref.html

Просмотреть файл

@ -79,9 +79,9 @@
* other code needs to see import declarations when using mfbt.
*/
#if defined(IMPL_MFBT)
# define MFBT_API(type_) MOZ_EXPORT_API(type_)
# define MFBT_API(type_) MOZ_EXPORT_API(type_)
#else
# define MFBT_API(type_) MOZ_IMPORT_API(type_)
# define MFBT_API(type_) MOZ_IMPORT_API(type_)
#endif
@ -90,6 +90,43 @@
#ifdef __cplusplus
/*
* g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
* without warnings (functionality used by the macros below). These modes are
* detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
* standardly, by checking whether __cplusplus has a C++11 or greater value.
* Current versions of g++ do not correctly set __cplusplus, so we check both
* for forward compatibility.
*/
#if defined(__clang__)
# if __clang_major__ >= 3
# define MOZ_HAVE_CXX11_DELETE
# define MOZ_HAVE_CXX11_OVERRIDE
# elif __clang_major__ == 2
# if __clang_minor__ >= 9
# define MOZ_HAVE_CXX11_DELETE
# endif
# endif
#elif defined(__GNUC__)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# if __GNUC__ > 4
# define MOZ_HAVE_CXX11_DELETE
# define MOZ_HAVE_CXX11_OVERRIDE
# elif __GNUC__ == 4
# if __GNUC_MINOR__ >= 7
# define MOZ_HAVE_CXX11_OVERRIDE
# endif
# if __GNUC_MINOR__ >= 4
# define MOZ_HAVE_CXX11_DELETE
# endif
# endif
# endif
#elif defined(_MSC_VER)
# if _MSC_VER >= 1400
# define MOZ_HAVE_CXX11_OVERRIDE
# endif
#endif
/*
* MOZ_DELETE, specified immediately prior to the ';' terminating an undefined-
* method declaration, attempts to delete that method from the corresponding
@ -112,23 +149,51 @@
* MOZ_DELETE relies on C++11 functionality not universally implemented. As a
* backstop, method declarations using MOZ_DELETE should be private.
*/
#if defined(__clang__) && (__clang_major__ >= 3 || (__clang_major__ == 2 && __clang_minor__ >= 9))
# define MOZ_DELETE = delete
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
/*
* g++ >= 4.4 requires -std=c++0x or -std=gnu++0x to support deleted functions
* without warnings. These modes are detectable by the experimental macro used
* below or, more standardly, by checking whether __cplusplus has a C++11 or
* greater value. Current versions of g++ do not correctly set __cplusplus, so
* we check both for forward compatibility.
*/
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
# define MOZ_DELETE = delete
# else
# define MOZ_DELETE /* = delete */
# endif
#if defined(MOZ_HAVE_CXX11_DELETE)
# define MOZ_DELETE = delete
#else
# define MOZ_DELETE /* no = delete support, or unknown support */
# define MOZ_DELETE /* no support */
#endif
/*
* MOZ_OVERRIDE explicitly indicates that a virtual member function in a class
* overrides a member function of a base class, rather than potentially being a
* new member function. MOZ_OVERRIDE should be placed immediately before the
* ';' terminating the member function's declaration, or before '= 0;' if the
* member function is pure. If the member function is defined in the class
* definition, it should appear before the opening brace of the function body.
*
* class Base
* {
* public:
* virtual void f() = 0;
* };
* class Derived1 : public Base
* {
* public:
* virtual void f() MOZ_OVERRIDE;
* };
* class Derived2 : public Base
* {
* public:
* virtual void f() MOZ_OVERRIDE = 0;
* };
* class Derived3 : public Base
* {
* public:
* virtual void f() MOZ_OVERRIDE { }
* };
*
* In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that
* the function marked with it override a member function of a base class: it
* is a compile error if it does not. Otherwise MOZ_OVERRIDE does not affect
* semantics and merely documents the override relationship to the reader (but
* of course must still be used correctly to not break C++11 compilers).
*/
#if defined(MOZ_HAVE_CXX11_OVERRIDE)
# define MOZ_OVERRIDE override
#else
# define MOZ_OVERRIDE /* no support */
#endif
#endif /* __cplusplus */

Просмотреть файл

@ -69,14 +69,10 @@ MOZ_END_EXTERN_C
* which it fails will stop running in a loud and dramatic way.
*/
#ifdef DEBUG
# define MOZ_ASSERT(expr_) \
((expr_) ? (void)0 : JS_Assert(#expr_, __FILE__, __LINE__))
# define MOZ_ASSERT(expr_) \
((expr_) ? (void)0 : JS_Assert(#expr_, __FILE__, __LINE__))
#else
# define MOZ_ASSERT(expr_) ((void)0)
# define MOZ_ASSERT(expr_) ((void)0)
#endif /* DEBUG */
/*
@ -86,15 +82,15 @@ MOZ_END_EXTERN_C
* may ignore this directive if it chooses.
*/
#ifndef MOZ_INLINE
# if defined __cplusplus
# define MOZ_INLINE inline
# elif defined _MSC_VER
# define MOZ_INLINE __inline
# elif defined __GNUC__
# define MOZ_INLINE __inline__
# else
# define MOZ_INLINE inline
# endif
# if defined __cplusplus
# define MOZ_INLINE inline
# elif defined _MSC_VER
# define MOZ_INLINE __inline
# elif defined __GNUC__
# define MOZ_INLINE __inline__
# else
# define MOZ_INLINE inline
# endif
#endif
/*
@ -105,15 +101,15 @@ MOZ_END_EXTERN_C
* to do so).
*/
#ifndef MOZ_ALWAYS_INLINE
# if defined DEBUG
# define MOZ_ALWAYS_INLINE MOZ_INLINE
# elif defined _MSC_VER
# define MOZ_ALWAYS_INLINE __forceinline
# elif defined __GNUC__
# define MOZ_ALWAYS_INLINE __attribute__((always_inline)) MOZ_INLINE
# else
# define MOZ_ALWAYS_INLINE MOZ_INLINE
# endif
# if defined DEBUG
# define MOZ_ALWAYS_INLINE MOZ_INLINE
# elif defined _MSC_VER
# define MOZ_ALWAYS_INLINE __forceinline
# elif defined __GNUC__
# define MOZ_ALWAYS_INLINE __attribute__((always_inline)) MOZ_INLINE
# else
# define MOZ_ALWAYS_INLINE MOZ_INLINE
# endif
#endif
/*
@ -123,13 +119,13 @@ MOZ_END_EXTERN_C
* guaranteed to support this, but most do.
*/
#ifndef MOZ_NEVER_INLINE
# if defined _MSC_VER
# define MOZ_NEVER_INLINE __declspec(noinline)
# elif defined __GNUC__
# define MOZ_NEVER_INLINE __attribute__((noinline))
# else
# define MOZ_NEVER_INLINE
# endif
# if defined _MSC_VER
# define MOZ_NEVER_INLINE __declspec(noinline)
# elif defined __GNUC__
# define MOZ_NEVER_INLINE __attribute__((noinline))
# else
# define MOZ_NEVER_INLINE
# endif
#endif
#ifdef __cplusplus
@ -224,18 +220,14 @@ public:
*/
#if defined(__GNUC__)
#define MOZ_ALIGNED_DECL(_type, _align) \
_type __attribute__((aligned(_align)))
# define MOZ_ALIGNED_DECL(_type, _align) \
_type __attribute__((aligned(_align)))
#elif defined(_MSC_VER)
#define MOZ_ALIGNED_DECL(_type, _align) \
__declspec(align(_align)) _type
# define MOZ_ALIGNED_DECL(_type, _align) \
__declspec(align(_align)) _type
#else
#warning "We don't know how to align variables on this compiler."
#define MOZ_ALIGNED_DECL(_type, _align) _type
# warning "We don't know how to align variables on this compiler."
# define MOZ_ALIGNED_DECL(_type, _align) _type
#endif
/*

Просмотреть файл

@ -160,9 +160,9 @@
#define NS_TYPEAHEADFIND_CID \
{ 0xe7f70966, 0x9a37, 0x48d7, { 0x8a, 0xeb, 0x35, 0x99, 0x8f, 0x31, 0x09, 0x0e} }
// {5edc87c2-6960-44e5-8431-bdfbb56f6aff}
// {51464459-4e46-4f31-8745-4acfa7c1e2f2}
#define NS_URLCLASSIFIERPREFIXSET_CID \
{ 0x5edc87c2, 0x6960, 0x44e5, { 0x84, 0x31, 0xbd, 0xfb, 0xb5, 0x6f, 0x6a, 0xff} }
{ 0x51464459, 0x4e46, 0x4f31, { 0x87, 0x45, 0x4a, 0xcf, 0xa7, 0xc1, 0xe2, 0xf2} }
// {5eb7c3c1-ec1f-4007-87cc-eefb37d68ce6}
#define NS_URLCLASSIFIERDBSERVICE_CID \

Просмотреть файл

@ -41,7 +41,7 @@
interface nsIArray;
[scriptable, uuid(5edc87c2-6960-44e5-8431-bdfbb56f6aff)]
[scriptable, uuid(51464459-4e46-4f31-8745-4acfa7c1e2f2)]
interface nsIUrlClassifierPrefixSet : nsISupports
{
void setPrefixes([const, array, size_is(aLength)] in unsigned long aPrefixes,
@ -51,7 +51,7 @@ interface nsIUrlClassifierPrefixSet : nsISupports
boolean contains(in unsigned long aPrefix);
boolean probe(in unsigned long aPrefix, in unsigned long aKey,
inout boolean aReady);
PRUint32 sizeOfIncludingThis(in boolean aCountMe);
PRUint32 sizeOfIncludingThis();
PRUint32 getKey();
boolean isEmpty();
void loadFromFile(in nsIFile aFile);

Просмотреть файл

@ -3653,7 +3653,7 @@ nsUrlClassifierDBServiceWorker::LoadPrefixSet(nsCOMPtr<nsIFile> & aFile)
#ifdef DEBUG
PRUint32 size = 0;
rv = mPrefixSet->SizeOfIncludingThis(true, &size);
rv = mPrefixSet->SizeOfIncludingThis(&size);
LOG(("SB tree done, size = %d bytes\n", size));
NS_ENSURE_SUCCESS(rv, rv);
#endif

Просмотреть файл

@ -127,7 +127,7 @@ NS_IMETHODIMP
nsPrefixSetReporter::GetAmount(PRInt64 * aAmount)
{
PRUint32 size;
nsresult rv = mParent->SizeOfIncludingThis(true, &size);
nsresult rv = mParent->SizeOfIncludingThis(&size);
*aAmount = size;
return rv;
}
@ -327,15 +327,11 @@ nsUrlClassifierPrefixSet::Contains(PRUint32 aPrefix, bool * aFound)
}
NS_IMETHODIMP
nsUrlClassifierPrefixSet::SizeOfIncludingThis(bool aCountMe, PRUint32 * aSize)
nsUrlClassifierPrefixSet::SizeOfIncludingThis(PRUint32 * aSize)
{
MutexAutoLock lock(mPrefixSetLock);
if (aCountMe) {
size_t usable = moz_malloc_usable_size(this);
*aSize = (PRUint32)(usable ? usable : sizeof(*this));
} else {
*aSize = 0;
}
size_t usable = moz_malloc_usable_size(this);
*aSize = (PRUint32)(usable ? usable : sizeof(*this));
*aSize += mDeltas.SizeOf();
*aSize += mIndexPrefixes.SizeOf();
*aSize += mIndexStarts.SizeOf();

Просмотреть файл

@ -72,7 +72,7 @@ public:
NS_IMETHOD Probe(PRUint32 aPrefix, PRUint32 aKey, bool* aReady, bool* aFound);
// Return the estimated size of the set on disk and in memory,
// in bytes
NS_IMETHOD SizeOfIncludingThis(bool aCountMe, PRUint32* aSize);
NS_IMETHOD SizeOfIncludingThis(PRUint32* aSize);
NS_IMETHOD IsEmpty(bool * aEmpty);
NS_IMETHOD LoadFromFile(nsIFile* aFile);
NS_IMETHOD StoreToFile(nsIFile* aFile);

Просмотреть файл

@ -1772,7 +1772,7 @@ var XPIProvider = {
}
// Ensure any changes to the add-ons list are flushed to disk
XPIDatabase.writeAddonsList([]);
XPIDatabase.writeAddonsList();
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, false);
},
@ -3047,8 +3047,8 @@ var XPIProvider = {
// Check that the add-ons list still exists
let addonsList = FileUtils.getFile(KEY_PROFILEDIR, [FILE_XPI_ADDONS_LIST],
true);
if (!addonsList.exists()) {
LOG("Add-ons list is missing, recreating");
if (addonsList.exists() == (state.length == 0)) {
LOG("Add-ons list is invalid, rebuilding");
XPIDatabase.writeAddonsList();
}
@ -5495,49 +5495,72 @@ var XPIDatabase = {
* Writes out the XPI add-ons list for the platform to read.
*/
writeAddonsList: function XPIDB_writeAddonsList() {
LOG("Writing add-ons list");
Services.appinfo.invalidateCachesOnRestart();
let addonsList = FileUtils.getFile(KEY_PROFILEDIR, [FILE_XPI_ADDONS_LIST],
true);
if (!this.connection) {
try {
addonsList.remove(false);
LOG("Deleted add-ons list");
}
catch (e) {
}
Services.prefs.clearUserPref(PREF_EM_ENABLED_ADDONS);
return;
}
let enabledAddons = [];
let text = "[ExtensionDirs]\r\n";
let count = 0;
let stmt;
let fullCount = 0;
if (this.connection) {
stmt = this.getStatement("getActiveAddons");
let stmt = this.getStatement("getActiveAddons");
for (let row in resultRows(stmt)) {
text += "Extension" + (count++) + "=" + row.descriptor + "\r\n";
enabledAddons.push(row.id + ":" + row.version);
}
for (let row in resultRows(stmt)) {
text += "Extension" + (count++) + "=" + row.descriptor + "\r\n";
enabledAddons.push(row.id + ":" + row.version);
}
fullCount += count;
// The selected skin may come from an inactive theme (the default theme
// when a lightweight theme is applied for example)
text += "\r\n[ThemeDirs]\r\n";
if (this.connection) {
if (Prefs.getBoolPref(PREF_EM_DSS_ENABLED)) {
stmt = this.getStatement("getThemes");
}
else {
stmt = this.getStatement("getActiveTheme");
stmt.params.internalName = XPIProvider.selectedSkin;
}
if (Prefs.getBoolPref(PREF_EM_DSS_ENABLED)) {
stmt = this.getStatement("getThemes");
}
else {
stmt = this.getStatement("getActiveTheme");
stmt.params.internalName = XPIProvider.selectedSkin;
}
if (stmt) {
count = 0;
for (let row in resultRows(stmt)) {
text += "Extension" + (count++) + "=" + row.descriptor + "\r\n";
enabledAddons.push(row.id + ":" + row.version);
}
fullCount += count;
}
var fos = FileUtils.openSafeFileOutputStream(addonsList);
fos.write(text, text.length);
FileUtils.closeSafeFileOutputStream(fos);
if (fullCount > 0) {
LOG("Writing add-ons list");
var fos = FileUtils.openSafeFileOutputStream(addonsList);
fos.write(text, text.length);
FileUtils.closeSafeFileOutputStream(fos);
Services.prefs.setCharPref(PREF_EM_ENABLED_ADDONS, enabledAddons.join(","));
Services.prefs.setCharPref(PREF_EM_ENABLED_ADDONS, enabledAddons.join(","));
}
else {
if (addonsList.exists()) {
LOG("Deleting add-ons list");
addonsList.remove(false);
}
Services.prefs.clearUserPref(PREF_EM_ENABLED_ADDONS);
}
}
};

Просмотреть файл

@ -129,6 +129,9 @@ function run_test() {
file.append("extensions.sqlite");
do_check_false(file.exists());
file.leafName = "extensions.ini";
do_check_false(file.exists());
run_test_1();
}
@ -175,6 +178,9 @@ function check_test_1() {
file.append("extensions.sqlite");
do_check_true(file.exists());
file.leafName = "extensions.ini";
do_check_false(file.exists());
AddonManager.getAllInstalls(function(installs) {
// There should be no active installs now since the install completed and
// doesn't require a restart.
@ -255,6 +261,10 @@ function run_test_3() {
do_check_eq(getShutdownReason(), ADDON_DISABLE);
do_check_not_in_crash_annotation("bootstrap1@tests.mozilla.org", "1.0");
let file = gProfD.clone();
file.append("extensions.ini");
do_check_false(file.exists());
AddonManager.getAddonByID("bootstrap1@tests.mozilla.org", function(b1) {
do_check_neq(b1, null);
do_check_eq(b1.version, "1.0");

Просмотреть файл

@ -136,6 +136,9 @@ function run_test() {
file.append("extensions.sqlite");
do_check_false(file.exists());
file.leafName = "extensions.ini";
do_check_false(file.exists());
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org",
"addon3@tests.mozilla.org",
@ -191,6 +194,9 @@ function run_test_1() {
file.append("extensions.sqlite");
do_check_true(file.exists());
file.leafName = "extensions.ini";
do_check_true(file.exists());
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org",
"addon3@tests.mozilla.org",
@ -292,6 +298,10 @@ function run_test_2() {
check_startup_changes(AddonManager.STARTUP_CHANGE_ENABLED, []);
do_check_true(gCachePurged);
var file = gProfD.clone();
file.append("extensions.ini");
do_check_true(file.exists());
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org",
"addon3@tests.mozilla.org",

Просмотреть файл

@ -270,7 +270,7 @@ DIST_FILES = \
components \
defaults \
modules \
hyphenation/hyph_en_US.dic \
hyphenation \
res \
lib \
lib.id \

Просмотреть файл

@ -148,5 +148,8 @@ interface nsIGfxInfo : nsISupports
// only useful on X11
[noscript, notxpcom] void GetData();
[implicit_jscontext]
jsval getInfo();
};

Просмотреть файл

@ -863,3 +863,63 @@ NS_IMETHODIMP GfxInfoBase::GetFailures(PRUint32 *failureCount NS_OUTPARAM, char
return NS_OK;
}
nsTArray<GfxInfoCollectorBase*> *sCollectors;
static void
InitCollectors()
{
if (!sCollectors)
sCollectors = new nsTArray<GfxInfoCollectorBase*>;
}
nsresult GfxInfoBase::GetInfo(JSContext* aCx, jsval* aResult)
{
InitCollectors();
InfoObject obj(aCx);
for (PRUint32 i = 0; i < sCollectors->Length(); i++) {
(*sCollectors)[i]->GetInfo(obj);
}
// Some example property definitions
// obj.DefineProperty("wordCacheSize", gfxTextRunWordCache::Count());
// obj.DefineProperty("renderer", mRendererIDsString);
// obj.DefineProperty("five", 5);
if (!obj.mOk) {
return NS_ERROR_FAILURE;
}
*aResult = OBJECT_TO_JSVAL(obj.mObj);
return NS_OK;
}
void
GfxInfoBase::AddCollector(GfxInfoCollectorBase* collector)
{
InitCollectors();
sCollectors->AppendElement(collector);
}
void
GfxInfoBase::RemoveCollector(GfxInfoCollectorBase* collector)
{
InitCollectors();
for (PRUint32 i = 0; i < sCollectors->Length(); i++) {
if ((*sCollectors)[i] == collector) {
sCollectors->RemoveElementAt(i);
break;
}
}
}
GfxInfoCollectorBase::GfxInfoCollectorBase()
{
GfxInfoBase::AddCollector(this);
}
GfxInfoCollectorBase::~GfxInfoCollectorBase()
{
GfxInfoBase::RemoveCollector(this);
}

Просмотреть файл

@ -47,6 +47,7 @@
#include "GfxDriverInfo.h"
#include "nsTArray.h"
#include "nsString.h"
#include "GfxInfoCollector.h"
namespace mozilla {
namespace widget {
@ -75,6 +76,7 @@ public:
NS_SCRIPTABLE NS_IMETHOD GetFailures(PRUint32 *failureCount NS_OUTPARAM, char ***failures NS_OUTPARAM);
NS_IMETHOD_(void) LogFailure(const nsACString &failure);
NS_SCRIPTABLE NS_IMETHOD GetInfo(JSContext*, jsval*);
// Initialization function. If you override this, you must call this class's
// version of Init first.
@ -92,6 +94,10 @@ public:
// only useful on X11
NS_IMETHOD_(void) GetData() { }
static void AddCollector(GfxInfoCollectorBase* collector);
static void RemoveCollector(GfxInfoCollectorBase* collector);
protected:
virtual nsresult GetFeatureStatusImpl(PRInt32 aFeature, PRInt32* aStatus,

Просмотреть файл

@ -0,0 +1,149 @@
/* vim: se cin sw=2 ts=2 et : */
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __mozilla_widget_GfxInfoCollector_h__
#define __mozilla_widget_GfxInfoCollector_h__
#include "jsapi.h"
namespace mozilla {
namespace widget {
/* this is handy wrapper around JSAPI to make it more pleasant to use.
* We collect the JSAPI errors and so that callers don't need to */
class InfoObject
{
friend class GfxInfoBase;
public:
void DefineProperty(const char *name, int value)
{
if (!mOk)
return;
mOk = JS_DefineProperty(mCx, mObj, name, INT_TO_JSVAL(value), NULL, NULL, JSPROP_ENUMERATE);
}
void DefineProperty(const char *name, nsAString &value)
{
if (!mOk)
return;
const nsPromiseFlatString &flat = PromiseFlatString(value);
JSString *string = JS_NewUCStringCopyN(mCx, static_cast<const jschar*>(flat.get()), flat.Length());
if (!string)
mOk = JS_FALSE;
if (!mOk)
return;
mOk = JS_DefineProperty(mCx, mObj, name, STRING_TO_JSVAL(string), NULL, NULL, JSPROP_ENUMERATE);
}
private:
// We need to ensure that this object lives on the stack so that GC sees it properly
InfoObject(JSContext *aCx) : mCx(aCx), mOk(JS_TRUE)
{
mObj = JS_NewObject(mCx, NULL, NULL, NULL);
if (!mObj)
mOk = JS_FALSE;
}
InfoObject(InfoObject&);
JSContext *mCx;
JSObject *mObj;
JSBool mOk;
};
/*
Here's an example usage:
class Foo {
Foo::Foo() : mInfoCollector(this, &Foo::GetAweseomeness) {}
void GetAwesomeness(InfoObject &obj) {
obj.DefineProperty("awesome", mAwesome);
}
int mAwesome;
GfxInfoCollector<Foo> mInfoCollector;
}
This will define a property on the object
returned from calling getInfo() on a
GfxInfo object. e.g.
gfxInfo = Cc["@mozilla.org/gfx/info;1"].getService(Ci.nsIGfxInfo);
info = gfxInfo.getInfo();
if (info.awesome)
alert(info.awesome);
*/
class GfxInfoCollectorBase
{
public:
GfxInfoCollectorBase();
virtual void GetInfo(InfoObject &obj) = 0;
virtual ~GfxInfoCollectorBase();
};
template<class T>
class GfxInfoCollector : public GfxInfoCollectorBase
{
public:
GfxInfoCollector(T* aPointer, void (T::*aFunc)(InfoObject &obj)) : mPointer(aPointer), mFunc(aFunc) {
}
virtual void GetInfo(InfoObject &obj) {
(mPointer->*mFunc)(obj);
}
protected:
T* mPointer;
void (T::*mFunc)(InfoObject &obj);
};
}
}
#endif

Просмотреть файл

@ -46,6 +46,9 @@ MODULE = widget
LIBRARY_NAME = xpwidgets_s
LIBXUL_LIBRARY = 1
EXPORTS = \
GfxInfoCollector.h \
$(NULL)
DEFINES += \
-D_IMPL_NS_WIDGET \

Просмотреть файл

@ -313,7 +313,7 @@ static PRInt64 GetHeapCommitted()
return (PRInt64) stats.committed;
}
static PRInt64 GetHeapCommittedUnallocatedFraction()
static PRInt64 GetHeapCommittedFragmentation()
{
jemalloc_stats_t stats;
jemalloc_stats(&stats);
@ -339,11 +339,11 @@ NS_MEMORY_REPORTER_IMPLEMENT(HeapCommitted,
"memory and is unable to decommit it because a small part of that block is "
"currently in use.")
NS_MEMORY_REPORTER_IMPLEMENT(HeapCommittedUnallocatedFraction,
"heap-committed-unallocated-fraction",
NS_MEMORY_REPORTER_IMPLEMENT(HeapCommittedFragmentation,
"heap-committed-fragmentation",
KIND_OTHER,
UNITS_PERCENTAGE,
GetHeapCommittedUnallocatedFraction,
GetHeapCommittedFragmentation,
"Fraction of committed bytes which do not correspond to an active "
"allocation; i.e., 1 - (heap-allocated / heap-committed). Although the "
"allocator will waste some space under any circumstances, a large value here "
@ -472,7 +472,7 @@ nsMemoryReporterManager::Init()
#if defined(HAVE_JEMALLOC_STATS)
REGISTER(HeapCommitted);
REGISTER(HeapCommittedUnallocatedFraction);
REGISTER(HeapCommittedFragmentation);
REGISTER(HeapDirty);
#elif defined(XP_MACOSX) && !defined(MOZ_MEMORY)
REGISTER(HeapZone0Committed);