Merge mozilla-inbound to b2g-inbound. a=merge

This commit is contained in:
Ryan VanderMeulen 2015-05-21 16:33:37 -04:00
commit 7093ecaec9
47 changed files with 291 additions and 514 deletions

View File

@ -156,18 +156,16 @@ add_task(function*() {
is(document.activeElement, gURLBar.inputField, "focus after loading two tabs");
yield expectFocusShift(function () gBrowser.selectedTab = tab2,
"window2", null, true,
"after tab change, focus in new tab");
yield* expectFocusShiftAfterTabSwitch(tab2, "window2", null, true,
"after tab change, focus in new tab");
focused = yield getFocusedElementForBrowser(browser2);
is(focused, "Focus is <none>", "focusedElement after tab change, focus in new tab");
// switching tabs when nothing in the new tab is focused
// should focus the browser
yield expectFocusShift(function () gBrowser.selectedTab = tab1,
"window1", null, true,
"after tab change, focus in original tab");
yield* expectFocusShiftAfterTabSwitch(tab1, "window1", null, true,
"after tab change, focus in original tab");
focused = yield getFocusedElementForBrowser(browser1);
is(focused, "Focus is <none>", "focusedElement after tab change, focus in original tab");
@ -193,9 +191,8 @@ add_task(function*() {
is(focused, "Focus is button2", "focusedElement in second browser after button focus in unfocused tab");
// switching tabs should now make the button in the other tab focused
yield expectFocusShift(function () gBrowser.selectedTab = tab2,
"window2", "button2", true,
"after tab change with button focused");
yield* expectFocusShiftAfterTabSwitch(tab2, "window2", "button2", true,
"after tab change with button focused");
// blurring an element in a background tab should not change the active
// focus, but should clear the focus in that tab.
@ -212,9 +209,8 @@ add_task(function*() {
yield expectFocusShift(function () gBrowser.selectedTab.focus(),
"main-window", "tab2", true,
"focusing tab element");
yield expectFocusShift(function () gBrowser.selectedTab = tab1,
"main-window", "tab1", true,
"tab change when selected tab element was focused");
yield* expectFocusShiftAfterTabSwitch(tab1, "main-window", "tab1", true,
"tab change when selected tab element was focused");
let switchWaiter;
if (gMultiProcessBrowser) {
@ -226,9 +222,8 @@ add_task(function*() {
});
}
yield expectFocusShift(function () gBrowser.selectedTab = tab2,
"main-window", "tab2", true,
"another tab change when selected tab element was focused");
yield* expectFocusShiftAfterTabSwitch(tab2, "main-window", "tab2", true,
"another tab change when selected tab element was focused");
// When this a remote browser, wait for the paint on the second browser so that
// any post tab-switching stuff has time to complete before blurring the tab.
@ -260,9 +255,8 @@ add_task(function*() {
// when a chrome element is focused, switching tabs to a tab with a button
// with the current focus should focus the button
yield expectFocusShift(function () gBrowser.selectedTab = tab1,
"window1", "button1", true,
"after tab change, focus in url field, button focused in new tab");
yield* expectFocusShiftAfterTabSwitch(tab1, "window1", "button1", true,
"after tab change, focus in url field, button focused in new tab");
focused = yield getFocusedElementForBrowser(browser1, false);
is(focused, "Focus is button1", "after switch tab, focus in unfocused tab, first browser");
@ -288,9 +282,8 @@ add_task(function*() {
is(fm.getFocusedElementForWindow(window, false, focusedWindow), browser1, "focusedElement after blur in unfocused url field");
// switch focus to a tab with a currently focused element
yield expectFocusShift(function () gBrowser.selectedTab = tab2,
"window2", "button2", true,
"after switch from unfocused to focused tab");
yield* expectFocusShiftAfterTabSwitch(tab2, "window2", "button2", true,
"after switch from unfocused to focused tab");
focused = yield getFocusedElementForBrowser(browser2, true);
is(focused, "Focus is button2", "focusedElement after switch from unfocused to focused tab");
@ -304,9 +297,8 @@ add_task(function*() {
is(fm.getFocusedElementForWindow(window, false, focusedWindow), null, "focusedElement after switch to chrome with no focused element");
// switch focus to another tab when neither have an active focus
yield expectFocusShift(function () gBrowser.selectedTab = tab1,
"window1", null, true,
"focusedWindow after tab switch from no focus to no focus");
yield* expectFocusShiftAfterTabSwitch(tab1, "window1", null, true,
"focusedWindow after tab switch from no focus to no focus");
focused = yield getFocusedElementForBrowser(browser1, false);
is(focused, "Focus is <none>", "after tab switch from no focus to no focus, first browser");
@ -475,6 +467,14 @@ function compareFocusResults()
});
}
function* expectFocusShiftAfterTabSwitch(tab, expectedWindow, expectedElement, focusChanged, testid)
{
let tabSwitchPromise = null;
yield expectFocusShift(() => { tabSwitchPromise = BrowserTestUtils.switchTab(gBrowser, tab) },
expectedWindow, expectedElement, focusChanged, testid)
yield tabSwitchPromise;
}
function* expectFocusShift(callback, expectedWindow, expectedElement, focusChanged, testid)
{
currentPromiseResolver = null;

View File

@ -6,7 +6,6 @@ FIREFOX_PREFERENCES = {
"loop.server": LOOP_SERVER_URL + "/v0",
"browser.dom.window.dump.enabled": True,
# Some more changes might be necesarry to have this working in offline mode
"media.peerconnection.default_iceservers": "[]",
"media.peerconnection.use_document_iceservers": False,
"media.peerconnection.ice.loopback": True,
"devtools.chrome.enabled": True,

View File

@ -490,6 +490,11 @@ IsOnFullDomainWhitelist(nsIURI* aURI)
NS_LITERAL_CSTRING("www.kuronekoyamato.co.jp"),
NS_LITERAL_CSTRING("s.tsite.jp"),
NS_LITERAL_CSTRING("formassist.jp"), // for orico.jp
NS_LITERAL_CSTRING("sp.m.reuters.co.jp"),
NS_LITERAL_CSTRING("www.atre.co.jp"),
NS_LITERAL_CSTRING("www.jtb.co.jp"),
NS_LITERAL_CSTRING("www.sharp.co.jp"),
NS_LITERAL_CSTRING("www.biccamera.com"),
};
static const size_t sNumFullDomainsOnWhitelist =
MOZ_ARRAY_LENGTH(sFullDomainsOnWhitelist);
@ -518,6 +523,7 @@ IsOnBaseDomainWhitelist(nsIURI* aURI)
NS_LITERAL_CSTRING("alicdn.com"), // for m.taobao.com
NS_LITERAL_CSTRING("dpfile.com"), // for m.dianping.com
NS_LITERAL_CSTRING("hao123img.com"), // for hao123.com
NS_LITERAL_CSTRING("tabelog.k-img.com"), // for s.tabelog.com
};
static const size_t sNumBaseDomainsOnWhitelist =
MOZ_ARRAY_LENGTH(sBaseDomainsOnWhitelist);

View File

@ -374,7 +374,7 @@ ifdef MOZ_CRT
# OS_LIBS comes from having mozcrt as a dependency in moz.build.
DLLFLAGS := $(OS_LIBS)
else
DLLFLAGS := -LIBPATH:$(ABS_DIST)/lib -DEFAULTLIB:mozglue
DLLFLAGS := -LIBPATH:$(ABS_DIST)/../mozglue/build -DEFAULTLIB:mozglue
endif
export DLLFLAGS
endif

View File

@ -3534,6 +3534,14 @@ nsHTMLDocument::QueryCommandSupported(const nsAString & commandID,
bool
nsHTMLDocument::QueryCommandSupported(const nsAString& commandID)
{
// Gecko technically supports the paste command, but non-privileged content
// will be unable to call it. For that reason, we report that paste is
// not supported to this non-privileged content (as it effectively is).
bool restricted = commandID.LowerCaseEqualsLiteral("paste");
if (restricted && !nsContentUtils::IsCallerChrome()) {
return false;
}
// commandID is supported if it can be converted to a Midas command
nsAutoCString cmdToDispatch;
return ConvertToMidasInternalCommand(commandID, cmdToDispatch);

View File

@ -254,6 +254,7 @@ GeckoMediaPluginServiceParent::Observe(nsISupports* aSubject,
NS_DISPATCH_NORMAL);
} else {
MOZ_ASSERT(mPlugins.IsEmpty());
mWaitingForPluginsAsyncShutdown = false;
}
// Wait for plugins to do async shutdown...

View File

@ -135,7 +135,6 @@ function setupEnvironment() {
['media.peerconnection.enabled', true],
['media.peerconnection.identity.enabled', true],
['media.peerconnection.identity.timeout', 12000],
['media.peerconnection.default_iceservers', '[]'],
['media.navigator.permission.disabled', true],
['media.getusermedia.screensharing.enabled', true],
['media.getusermedia.screensharing.allowed_domains', "mochi.test"]

View File

@ -100,3 +100,4 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_navigation_timing.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_bug1161721.html]

View File

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1161721
-->
<head>
<title>Test for Bug 1161721</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/WindowSnapshot.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1161721">Mozilla Bug 1161721</a>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script type="application/javascript">
ok(!document.queryCommandSupported("paste"), "Paste isn't supported in non-privilged JavaScript");
ok(document.queryCommandSupported("copy"), "Copy is supported in non-privilged JavaScript");
ok(document.queryCommandSupported("cut"), "Cut is supported in non-privilged JavaScript");
ok(SpecialPowers.wrap(document).queryCommandSupported("paste"), "Paste is supported in privilged JavaScript");
ok(SpecialPowers.wrap(document).queryCommandSupported("copy"), "Copy is supported in privilged JavaScript");
ok(SpecialPowers.wrap(document).queryCommandSupported("cut"), "Cut is supported in privilged JavaScript");
</script>
</pre>
</body>
</html>

View File

@ -289,6 +289,9 @@ const knownFailures = {
"Q-Proposed-UNBOOKMARK_TEXT-1-dM": true,
"Q-Proposed-UNBOOKMARK_TEXT-1-body": true,
"Q-Proposed-UNBOOKMARK_TEXT-1-div": true,
"Q-Proposed-PASTE_TEXT-1-dM": true,
"Q-Proposed-PASTE_TEXT-1-body": true,
"Q-Proposed-PASTE_TEXT-1-div": true,
"QE-Proposed-UNSELECT_TEXT-1-dM": true,
"QE-Proposed-UNSELECT_TEXT-1-body": true,
"QE-Proposed-UNSELECT_TEXT-1-div": true,

View File

@ -24,6 +24,7 @@ EXPORTS.mozilla.gfx += [
'DrawTargetTiled.h',
'Filters.h',
'Helpers.h',
'HelpersCairo.h',
'Logging.h',
'Matrix.h',
'NumericTools.h',
@ -79,7 +80,6 @@ if CONFIG['MOZ_ENABLE_SKIA']:
'image_operations.cpp', # Uses _USE_MATH_DEFINES
]
EXPORTS.mozilla.gfx += [
'HelpersCairo.h',
'HelpersSkia.h',
]

View File

@ -1796,6 +1796,7 @@ ColorLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
{
Layer::PrintInfo(aStream, aPrefix);
AppendToString(aStream, mColor, " [color=", "]");
AppendToString(aStream, mBounds, " [bounds=", "]");
}
void

View File

@ -215,31 +215,40 @@ AppendToString(std::stringstream& aStream, const ScrollableLayerGuid& s,
}
void
AppendToString(std::stringstream& aStream, const Matrix4x4& m,
AppendToString(std::stringstream& aStream, const Matrix& m,
const char* pfx, const char* sfx)
{
aStream << pfx;
if (m.Is2D()) {
Matrix matrix = m.As2D();
if (matrix.IsIdentity()) {
aStream << "[ I ]";
aStream << sfx;
return;
}
aStream << nsPrintfCString(
"[ %g %g; %g %g; %g %g; ]",
matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32).get();
if (m.IsIdentity()) {
aStream << "[ I ]";
} else {
aStream << nsPrintfCString(
"[ %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g; ]",
m._11, m._12, m._13, m._14,
m._21, m._22, m._23, m._24,
m._31, m._32, m._33, m._34,
m._41, m._42, m._43, m._44).get();
"[ %g %g; %g %g; %g %g; ]",
m._11, m._12, m._21, m._22, m._31, m._32).get();
}
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const Matrix4x4& m,
const char* pfx, const char* sfx)
{
if (m.Is2D()) {
Matrix matrix = m.As2D();
AppendToString(aStream, matrix, pfx, sfx);
return;
}
aStream << pfx;
aStream << nsPrintfCString(
"[ %g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g; ]",
m._11, m._12, m._13, m._14,
m._21, m._22, m._23, m._24,
m._31, m._32, m._33, m._34,
m._41, m._42, m._43, m._44).get();
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const Matrix5x4& m,
const char* pfx, const char* sfx)

View File

@ -182,6 +182,10 @@ AppendToString(std::stringstream& aStream, const mozilla::gfx::ScaleFactors2D<sr
aStream << sfx;
}
void
AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix& m,
const char* pfx="", const char* sfx="");
void
AppendToString(std::stringstream& aStream, const mozilla::gfx::Matrix4x4& m,
const char* pfx="", const char* sfx="");

View File

@ -404,6 +404,8 @@ public:
: mPaintedLayer(nullptr)
, mCompositableClient(nullptr)
, mManager(nullptr)
, mCallback(nullptr)
, mCallbackData(nullptr)
, mLastPaintContentType(gfxContentType::COLOR)
, mLastPaintSurfaceMode(SurfaceMode::SURFACE_OPAQUE)
, mSharedFrameMetricsHelper(nullptr)

View File

@ -23,7 +23,7 @@ public:
NS_INLINE_DECL_REFCOUNTING(TextRenderer)
explicit TextRenderer(Compositor *aCompositor)
: mCompositor(aCompositor)
: mCompositor(aCompositor), mMap({nullptr, 0})
{
}

View File

@ -489,7 +489,7 @@ PrepareFontOptions(FcPattern* aPattern,
{
NS_ASSERTION(aFontOptions, "null font options passed to PrepareFontOptions");
// xxx - taken from the gfxPangoFonts code, needs to be reviewed
// xxx - taken from the gfxFontconfigFonts code, needs to be reviewed
FcBool printing;
if (FcPatternGetBool(aPattern, PRINTING_FC_PROPERTY, 0, &printing) !=

View File

@ -1844,7 +1844,7 @@ protected:
// (and with variantCaps set to normal).
// Default implementation relies on gfxFontEntry::CreateFontInstance;
// backends that don't implement that will need to override this and use
// an alternative technique. (gfxPangoFonts, I'm looking at you...)
// an alternative technique. (gfxFontconfigFonts, I'm looking at you...)
virtual already_AddRefed<gfxFont> GetSmallCapsFont();
// subclasses may provide (possibly hinted) glyph widths (in font units);

View File

@ -15,7 +15,7 @@
#ifdef MOZ_WIDGET_QT
#include "gfxQtPlatform.h"
#endif
#include "gfxPangoFonts.h"
#include "gfxFontconfigFonts.h"
#include "gfxFT2FontBase.h"
#include "gfxFT2Utils.h"
#include "harfbuzz/hb.h"

View File

@ -3,8 +3,8 @@
* 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 GFX_PANGOFONTS_H
#define GFX_PANGOFONTS_H
#ifndef GFX_FONTCONFIG_FONTS_H
#define GFX_FONTCONFIG_FONTS_H
#include "cairo.h"
#include "gfxTypes.h"
@ -102,4 +102,4 @@ private:
static FT_Library GetFTLibrary();
};
#endif /* GFX_PANGOFONTS_H */
#endif /* GFX_FONTCONFIG_FONTS_H */

View File

@ -14,7 +14,7 @@
#include "gfx2DGlue.h"
#include "gfxFcPlatformFontList.h"
#include "gfxFontconfigUtils.h"
#include "gfxPangoFonts.h"
#include "gfxFontconfigFonts.h"
#include "gfxContext.h"
#include "gfxUserFontSet.h"
#include "gfxUtils.h"

View File

@ -23,7 +23,7 @@
#include "gfxQPainterSurface.h"
#include "nsUnicodeProperties.h"
#include "gfxPangoFonts.h"
#include "gfxFontconfigFonts.h"
#include "gfxContext.h"
#include "gfxUserFontSet.h"

View File

@ -102,9 +102,9 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
]
elif CONFIG['MOZ_WIDGET_GTK']:
EXPORTS += [
'gfxFontconfigFonts.h',
'gfxFT2FontBase.h',
'gfxGdkNativeRenderer.h',
'gfxPangoFonts.h',
'gfxPDFSurface.h',
'gfxPlatformGtk.h',
'gfxPSSurface.h',
@ -112,11 +112,11 @@ elif CONFIG['MOZ_WIDGET_GTK']:
SOURCES += [
'gfxFcPlatformFontList.cpp',
'gfxFontconfigFonts.cpp',
'gfxFontconfigUtils.cpp',
'gfxFT2FontBase.cpp',
'gfxFT2Utils.cpp',
'gfxGdkNativeRenderer.cpp',
'gfxPangoFonts.cpp',
'gfxPDFSurface.cpp',
'gfxPlatformGtk.cpp',
'gfxPSSurface.cpp',
@ -134,18 +134,18 @@ elif CONFIG['MOZ_WIDGET_GTK']:
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
EXPORTS += [
'gfxFontconfigFonts.h',
'gfxFT2FontBase.h',
'gfxPangoFonts.h',
'gfxPDFSurface.h',
'gfxQPainterSurface.h',
'gfxQtNativeRenderer.h',
'gfxQtPlatform.h',
]
SOURCES += [
'gfxFontconfigFonts.cpp',
'gfxFontconfigUtils.cpp',
'gfxFT2FontBase.cpp',
'gfxFT2Utils.cpp',
'gfxPangoFonts.cpp',
'gfxPDFSurface.cpp',
'gfxQPainterSurface.cpp',
'gfxQtPlatform.cpp',

View File

@ -50,7 +50,7 @@ NS_GetComplexLineBreaks(const char16_t* aText, uint32_t aLength,
// pango_break (pango 1.16.2) only analyses text before the
// first NUL (but sets one extra attr). Workaround loop to call
// pango_break again to analyse after the NUL is done somewhere else
// (gfx/thebes/gfxPangoFonts.cpp: SetupClusterBoundaries()).
// (gfx/thebes/gfxFontconfigFonts.cpp: SetupClusterBoundaries()).
// So, we do the same here for pango_get_log_attrs.
break;
}

View File

@ -64,7 +64,7 @@ class OutOfLineUpdateCache :
private:
LInstruction* lir_;
size_t cacheIndex_;
AddCacheState state_;
RepatchLabel entry_;
public:
OutOfLineUpdateCache(LInstruction* lir, size_t cacheIndex)
@ -83,8 +83,8 @@ class OutOfLineUpdateCache :
LInstruction* lir() const {
return lir_;
}
AddCacheState& state() {
return state_;
RepatchLabel& entry() {
return entry_;
}
void accept(CodeGenerator* codegen) {
@ -125,10 +125,7 @@ CodeGeneratorShared::addCache(LInstruction* lir, size_t cacheIndex)
OutOfLineUpdateCache* ool = new(alloc()) OutOfLineUpdateCache(lir, cacheIndex);
addOutOfLineCode(ool, mir);
// OOL-specific state depends on the type of cache.
cache->initializeAddCacheState(lir, &ool->state());
cache->emitInitialJump(masm, ool->state());
cache->emitInitialJump(masm, ool->entry());
masm.bind(ool->rejoin());
}
@ -139,7 +136,7 @@ CodeGenerator::visitOutOfLineCache(OutOfLineUpdateCache* ool)
// Register the location of the OOL path in the IC.
cache->setFallbackLabel(masm.labelForPatch());
cache->bindInitialJump(masm, ool->state());
masm.bind(&ool->entry());
// Dispatch to ICs' accept functions.
cache->accept(this, ool);
@ -6737,7 +6734,7 @@ CodeGenerator::visitOutOfLineStoreElementHole(OutOfLineStoreElementHole* ool)
Address initLength(elements, ObjectElements::offsetOfInitializedLength());
masm.branchKey(Assembler::NotEqual, initLength, ToInt32Key(index), &callStub);
} else {
Address initLength(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength());
Address initLength(object, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength());
masm.load32(initLength, ToRegister(temp));
masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), ToRegister(temp));
masm.branchKey(Assembler::NotEqual, ToRegister(temp), ToInt32Key(index), &callStub);

View File

@ -1099,7 +1099,6 @@ IonScript::Destroy(FreeOp* fop, IonScript* script)
if (script->pendingBuilder())
jit::FinishOffThreadBuilder(nullptr, script->pendingBuilder());
script->destroyCaches();
script->unlinkFromRuntime(fop);
fop->free_(script);
}
@ -1125,13 +1124,6 @@ IonScript::purgeCaches()
getCacheFromIndex(i).reset();
}
void
IonScript::destroyCaches()
{
for (size_t i = 0; i < numCaches(); i++)
getCacheFromIndex(i).destroy();
}
void
IonScript::unlinkFromRuntime(FreeOp* fop)
{

View File

@ -168,16 +168,19 @@ class IonCache::StubAttacher
bool hasNextStubOffset_ : 1;
bool hasStubCodePatchOffset_ : 1;
IonCache& cache_;
CodeLocationLabel rejoinLabel_;
CodeOffsetJump nextStubOffset_;
CodeOffsetJump rejoinOffset_;
CodeOffsetLabel stubCodePatchOffset_;
public:
explicit StubAttacher(CodeLocationLabel rejoinLabel)
explicit StubAttacher(IonCache& cache)
: hasNextStubOffset_(false),
hasStubCodePatchOffset_(false),
rejoinLabel_(rejoinLabel),
cache_(cache),
rejoinLabel_(cache.rejoinLabel_),
nextStubOffset_(),
rejoinOffset_(),
stubCodePatchOffset_()
@ -253,22 +256,6 @@ class IonCache::StubAttacher
}
}
virtual void patchNextStubJump(MacroAssembler& masm, JitCode* code) = 0;
};
const ImmPtr IonCache::StubAttacher::STUB_ADDR = ImmPtr((void*)0xdeadc0de);
class RepatchIonCache::RepatchStubAppender : public IonCache::StubAttacher
{
RepatchIonCache& cache_;
public:
explicit RepatchStubAppender(RepatchIonCache& cache)
: StubAttacher(cache.rejoinLabel_),
cache_(cache)
{
}
void patchNextStubJump(MacroAssembler& masm, JitCode* code) {
// Patch the previous nextStubJump of the last stub, or the jump from the
// codeGen, to jump into the newly allocated code.
@ -289,103 +276,18 @@ class RepatchIonCache::RepatchStubAppender : public IonCache::StubAttacher
}
};
void
RepatchIonCache::reset()
{
IonCache::reset();
PatchJump(initialJump_, fallbackLabel_);
lastJump_ = initialJump_;
}
const ImmPtr IonCache::StubAttacher::STUB_ADDR = ImmPtr((void*)0xdeadc0de);
void
RepatchIonCache::emitInitialJump(MacroAssembler& masm, AddCacheState& addState)
IonCache::emitInitialJump(MacroAssembler& masm, RepatchLabel& entry)
{
initialJump_ = masm.jumpWithPatch(&addState.repatchEntry);
initialJump_ = masm.jumpWithPatch(&entry);
lastJump_ = initialJump_;
Label label;
masm.bind(&label);
rejoinLabel_ = CodeOffsetLabel(label.offset());
}
void
RepatchIonCache::bindInitialJump(MacroAssembler& masm, AddCacheState& addState)
{
masm.bind(&addState.repatchEntry);
}
void
RepatchIonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm)
{
IonCache::updateBaseAddress(code, masm);
initialJump_.repoint(code, &masm);
lastJump_.repoint(code, &masm);
rejoinLabel_.repoint(code, &masm);
}
class DispatchIonCache::DispatchStubPrepender : public IonCache::StubAttacher
{
DispatchIonCache& cache_;
public:
explicit DispatchStubPrepender(DispatchIonCache& cache)
: StubAttacher(cache.rejoinLabel_),
cache_(cache)
{
}
void patchNextStubJump(MacroAssembler& masm, JitCode* code) {
MOZ_ASSERT(hasNextStubOffset_);
// Jump to the previous entry in the stub dispatch table. We
// have not yet executed the code we're patching the jump in.
nextStubOffset_.fixup(&masm);
CodeLocationJump nextStubJump(code, nextStubOffset_);
PatchJump(nextStubJump, CodeLocationLabel(cache_.firstStub_));
// Update the dispatch table. Modification to jumps after the dispatch
// table is updated is disallowed, lest we race on entry into an
// unfinalized stub.
cache_.firstStub_ = code->raw();
}
};
void
DispatchIonCache::reset()
{
IonCache::reset();
firstStub_ = fallbackLabel_.raw();
}
void
DispatchIonCache::emitInitialJump(MacroAssembler& masm, AddCacheState& addState)
{
Register scratch = addState.dispatchScratch;
dispatchLabel_ = masm.movWithPatch(ImmPtr((void*)-1), scratch);
masm.loadPtr(Address(scratch, 0), scratch);
masm.jump(scratch);
rejoinLabel_ = masm.labelForPatch();
}
void
DispatchIonCache::bindInitialJump(MacroAssembler& masm, AddCacheState& addState)
{
// Do nothing.
}
void
DispatchIonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm)
{
// The address of firstStub_ should be pointer aligned.
MOZ_ASSERT(uintptr_t(&firstStub_) % sizeof(uintptr_t) == 0);
IonCache::updateBaseAddress(code, masm);
dispatchLabel_.fixup(&masm);
Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, dispatchLabel_),
ImmPtr(&firstStub_),
ImmPtr((void*)-1));
firstStub_ = fallbackLabel_.raw();
rejoinLabel_.repoint(code, &masm);
}
void
IonCache::attachStub(MacroAssembler& masm, StubAttacher& attacher, Handle<JitCode*> code)
{
@ -469,11 +371,9 @@ void
IonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm)
{
fallbackLabel_.repoint(code, &masm);
}
void
IonCache::initializeAddCacheState(LInstruction* ins, AddCacheState* addState)
{
initialJump_.repoint(code, &masm);
lastJump_.repoint(code, &masm);
rejoinLabel_.repoint(code, &masm);
}
static void*
@ -1419,7 +1319,7 @@ GetPropertyIC::tryAttachNative(JSContext* cx, HandleScript outerScript, IonScrip
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
const char* attachKind;
switch (type) {
@ -1468,7 +1368,7 @@ GetPropertyIC::tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScri
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateReadUnboxed(cx, ion, masm, attacher, obj, property, object(), output());
return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed");
}
@ -1496,7 +1396,7 @@ GetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript,
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateReadSlot(cx, ion, masm, attacher, obj, obj,
shape, object(), output());
return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed expando");
@ -1530,7 +1430,7 @@ GetPropertyIC::tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript
*emitted = true;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateTypedArrayLength(cx, masm, attacher, AnyTypedArrayLayout(obj), object(), output());
setHasTypedArrayLengthStub(obj);
@ -1635,7 +1535,7 @@ GetPropertyIC::tryAttachDOMProxyShadowed(JSContext* cx, HandleScript outerScript
Label failures;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
// Guard on the shape of the object.
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
@ -1704,7 +1604,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScri
Label failures;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
// Guard on the shape of the object.
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
@ -1817,7 +1717,7 @@ GetPropertyIC::tryAttachGenericProxy(JSContext* cx, HandleScript outerScript, Io
Label failures;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
Register scratchReg = output().valueReg().scratchReg();
@ -1870,7 +1770,7 @@ GetPropertyIC::tryAttachArgumentsLength(JSContext* cx, HandleScript outerScript,
Label failures;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
Register tmpReg;
if (output().hasValue()) {
@ -2023,7 +1923,7 @@ GetPropertyIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex
void
GetPropertyIC::reset()
{
RepatchIonCache::reset();
IonCache::reset();
hasTypedArrayLengthStub_ = false;
hasSharedTypedArrayLengthStub_ = false;
hasStrictArgumentsLengthStub_ = false;
@ -2042,11 +1942,8 @@ void
IonCache::reset()
{
this->stubCount_ = 0;
}
void
IonCache::destroy()
{
PatchJump(initialJump_, fallbackLabel_);
lastJump_ = initialJump_;
}
// Jump to failure if a value being written is not a property for obj/id.
@ -2132,7 +2029,7 @@ SetPropertyIC::attachSetSlot(JSContext* cx, HandleScript outerScript, IonScript*
HandleObject obj, HandleShape shape, bool checkTypeset)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateSetSlot(cx, masm, attacher, obj, shape, object(), value(), needsTypeBarrier(),
checkTypeset);
return linkAndAttachStub(cx, masm, attacher, ion, "setting");
@ -2325,7 +2222,7 @@ SetPropertyIC::attachGenericProxy(JSContext* cx, HandleScript outerScript, IonSc
MOZ_ASSERT(!hasGenericProxyStub());
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
Label failures;
{
@ -2382,7 +2279,7 @@ SetPropertyIC::attachDOMProxyShadowed(JSContext* cx, HandleScript outerScript, I
Label failures;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
// Guard on the shape of the object.
masm.branchPtr(Assembler::NotEqual,
@ -2673,7 +2570,7 @@ SetPropertyIC::attachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScript,
Label failures;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
// Guard on the shape of the object.
masm.branchPtr(Assembler::NotEqual,
@ -2719,7 +2616,7 @@ SetPropertyIC::attachCallSetter(JSContext* cx, HandleScript outerScript, IonScri
void* returnAddr)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
Label failure;
TestMatchingReceiver(masm, attacher, object(), obj, &failure);
@ -2865,7 +2762,7 @@ SetPropertyIC::attachAddSlot(JSContext* cx, HandleScript outerScript, IonScript*
MOZ_ASSERT_IF(!needsTypeBarrier(), !checkTypeset);
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateAddSlot(cx, masm, attacher, obj, oldShape, oldGroup, object(), value(), checkTypeset);
return linkAndAttachStub(cx, masm, attacher, ion, "adding");
}
@ -3101,7 +2998,7 @@ SetPropertyIC::attachSetUnboxed(JSContext* cx, HandleScript outerScript, IonScri
bool checkTypeset)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateSetUnboxed(cx, masm, attacher, obj, id, unboxedOffset, unboxedType,
object(), value(), checkTypeset);
return linkAndAttachStub(cx, masm, attacher, ion, "set_unboxed");
@ -3316,7 +3213,7 @@ SetPropertyIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex
void
SetPropertyIC::reset()
{
RepatchIonCache::reset();
IonCache::reset();
hasGenericProxyStub_ = false;
}
@ -3422,7 +3319,7 @@ GetElementIC::attachGetProp(JSContext* cx, HandleScript outerScript, IonScript*
masm.branchIfFalseBool(scratch, &failures);
masm.bind(&equal);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
if (canCache == GetPropertyIC::CanAttachReadSlot) {
GenerateReadSlot(cx, ion, masm, attacher, obj, holder, shape, object(), output(),
&failures);
@ -3511,7 +3408,7 @@ GetElementIC::attachDenseElement(JSContext* cx, HandleScript outerScript, IonScr
HandleObject obj, const Value& idval)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
if (!GenerateDenseElement(cx, masm, attacher, obj, idval, object(), index(), output()))
return false;
@ -3666,7 +3563,7 @@ GetElementIC::attachDenseElementHole(JSContext* cx, HandleScript outerScript, Io
HandleObject obj, const Value& idval)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateDenseElementHole(cx, masm, attacher, ion, obj, idval, object(), index(), output());
return linkAndAttachStub(cx, masm, attacher, ion, "dense hole");
@ -3817,7 +3714,7 @@ GetElementIC::attachTypedArrayElement(JSContext* cx, HandleScript outerScript, I
HandleObject tarr, const Value& idval)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
GenerateGetTypedArrayElement(cx, masm, attacher, tarr, idval, object(), index(), output(),
allowDoubleResult());
return linkAndAttachStub(cx, masm, attacher, ion, "typed array");
@ -3831,7 +3728,7 @@ GetElementIC::attachArgumentsElement(JSContext* cx, HandleScript outerScript, Io
Label failures;
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
Register tmpReg = output().scratchReg().gpr();
MOZ_ASSERT(tmpReg != InvalidReg);
@ -4019,7 +3916,7 @@ GetElementIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex,
void
GetElementIC::reset()
{
RepatchIonCache::reset();
IonCache::reset();
hasDenseStub_ = false;
hasStrictArgumentsStub_ = false;
hasNormalArgumentsStub_ = false;
@ -4217,7 +4114,7 @@ SetElementIC::attachDenseElement(JSContext* cx, HandleScript outerScript, IonScr
HandleObject obj, const Value& idval)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
if (!GenerateSetDenseElement(cx, masm, attacher, obj, idval,
guardHoles(), object(), index(),
value(), tempToUnboxIndex(),
@ -4319,7 +4216,7 @@ SetElementIC::attachTypedArrayElement(JSContext* cx, HandleScript outerScript, I
HandleObject tarr)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
if (!GenerateSetTypedArrayElement(cx, masm, attacher, tarr,
object(), index(), value(),
tempToUnboxIndex(), temp(), tempDouble(), tempFloat32()))
@ -4358,7 +4255,7 @@ SetElementIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex,
void
SetElementIC::reset()
{
RepatchIonCache::reset();
IonCache::reset();
hasDenseStub_ = false;
}
@ -4369,7 +4266,7 @@ BindNameIC::attachGlobal(JSContext* cx, HandleScript outerScript, IonScript* ion
MOZ_ASSERT(scopeChain->is<GlobalObject>());
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
// Guard on the scope chain.
attacher.branchNextStub(masm, Assembler::NotEqual, scopeChainReg(),
@ -4446,7 +4343,7 @@ BindNameIC::attachNonGlobal(JSContext* cx, HandleScript outerScript, IonScript*
MOZ_ASSERT(IsCacheableNonGlobalScope(scopeChain));
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
// Guard on the shape of the scope chain.
Label failures;
@ -4539,7 +4436,7 @@ NameIC::attachReadSlot(JSContext* cx, HandleScript outerScript, IonScript* ion,
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
Label failures;
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
Register scratchReg = outputReg().valueReg().scratchReg();
@ -4608,7 +4505,7 @@ NameIC::attachCallGetter(JSContext* cx, HandleScript outerScript, IonScript* ion
HandleShape shape, void* returnAddr)
{
MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
RepatchStubAppender attacher(*this);
StubAttacher attacher(*this);
Label failures;
Register scratchReg = outputReg().valueReg().scratchReg();

View File

@ -46,15 +46,6 @@ class IonCacheVisitor
#undef VISIT_INS
};
// Common shared temporary state needed during codegen between the different
// kinds of caches. Used by OutOfLineUpdateCache.
struct AddCacheState
{
RepatchLabel repatchEntry;
Register dispatchScratch;
};
// Common structure encoding the state of a polymorphic inline cache contained
// in the code for an IonScript. IonCaches are used for polymorphic operations
// where multiple implementations may be required.
@ -64,14 +55,71 @@ struct AddCacheState
// may generate a stub to perform the operation in certain cases (e.g. a
// particular shape for an input object) and attach the stub to existing
// stubs, forming a daisy chain of tests for how to perform the operation in
// different circumstances. The details of how stubs are linked up as
// described in comments below for the classes RepatchIonCache and
// DispatchIonCache.
// different circumstances.
//
// Eventually, if too many stubs are generated the cache function may disable
// the cache, by generating a stub to make a call and perform the operation
// within the VM.
//
// The caches initially generate a patchable jump to an out of line call
// to the cache function. Stubs are attached by appending: when attaching a
// new stub, we patch the any failure conditions in last generated stub to
// jump to the new stub. Failure conditions in the new stub jump to the cache
// function which may generate new stubs.
//
// Control flow Pointers
// =======# ----. .---->
// # | |
// #======> \-----/
//
// Initial state:
//
// JIT Code
// +--------+ .---------------.
// | | | |
// |========| v +----------+ |
// |== IC ==|====>| Cache Fn | |
// |========| +----------+ |
// | |<=# # |
// | | #=======# |
// +--------+ Rejoin path |
// |________ |
// | |
// IC | |
// Entry | |
// +------------+ |
// | lastJump_ |---------------/
// +------------+
// | ... |
// +------------+
//
// Attaching stubs:
//
// Patch the jump pointed to by lastJump_ to jump to the new stub. Update
// lastJump_ to be the new stub's failure jump. The failure jump of the new
// stub goes to the fallback label, which is the cache function. In this
// fashion, new stubs are _appended_ to the chain of stubs, as lastJump_
// points to the _tail_ of the stub chain.
//
// JIT Code
// +--------+ #=======================#
// | | # v
// |========| # +----------+ +------+
// |== IC ==|=# | Cache Fn |<====| Stub |
// |========| +----------+ ^ +------+
// | |<=# # | #
// | | #======#=========|=====#
// +--------+ Rejoin path |
// |________ |
// | |
// IC | |
// Entry | |
// +------------+ |
// | lastJump_ |---------------/
// +------------+
// | ... |
// +------------+
//
// While calls may be made to the cache function and other VM functions, the
// cache may still be treated as pure during optimization passes, such that
// LICM and GVN may be performed on operations around the cache as if the
@ -166,6 +214,10 @@ class IonCache
// IC code to enter a callee.
jsbytecode* profilerLeavePc_;
CodeLocationJump initialJump_;
CodeLocationJump lastJump_;
CodeLocationLabel rejoinLabel_;
private:
static const size_t MAX_STUBS;
void incrementStubCount() {
@ -184,7 +236,10 @@ class IonCache
fallbackLabel_(),
script_(nullptr),
pc_(nullptr),
profilerLeavePc_(nullptr)
profilerLeavePc_(nullptr),
initialJump_(),
lastJump_(),
rejoinLabel_()
{
}
@ -206,22 +261,16 @@ class IonCache
}
// Get the address at which IC rejoins the mainline jitcode.
virtual void* rejoinAddress() = 0;
void* rejoinAddress() const {
return rejoinLabel_.raw();
}
virtual void emitInitialJump(MacroAssembler& masm, AddCacheState& addState) = 0;
virtual void bindInitialJump(MacroAssembler& masm, AddCacheState& addState) = 0;
virtual void updateBaseAddress(JitCode* code, MacroAssembler& masm);
// Initialize the AddCacheState depending on the kind of cache, like
// setting a scratch register. Defaults to doing nothing.
virtual void initializeAddCacheState(LInstruction* ins, AddCacheState* addState);
void emitInitialJump(MacroAssembler& masm, RepatchLabel& entry);
void updateBaseAddress(JitCode* code, MacroAssembler& masm);
// Reset the cache around garbage collection.
virtual void reset();
// Destroy any extra resources the cache uses upon IonScript finalization.
virtual void destroy();
bool canAttachStub() const {
return stubCount_ < MAX_STUBS;
}
@ -285,204 +334,6 @@ class IonCache
}
};
//
// Repatch caches initially generate a patchable jump to an out of line call
// to the cache function. Stubs are attached by appending: when attaching a
// new stub, we patch the any failure conditions in last generated stub to
// jump to the new stub. Failure conditions in the new stub jump to the cache
// function which may generate new stubs.
//
// Control flow Pointers
// =======# ----. .---->
// # | |
// #======> \-----/
//
// Initial state:
//
// JIT Code
// +--------+ .---------------.
// | | | |
// |========| v +----------+ |
// |== IC ==|====>| Cache Fn | |
// |========| +----------+ |
// | |<=# # |
// | | #=======# |
// +--------+ Rejoin path |
// |________ |
// | |
// Repatch | |
// IC | |
// Entry | |
// +------------+ |
// | lastJump_ |---------------/
// +------------+
// | ... |
// +------------+
//
// Attaching stubs:
//
// Patch the jump pointed to by lastJump_ to jump to the new stub. Update
// lastJump_ to be the new stub's failure jump. The failure jump of the new
// stub goes to the fallback label, which is the cache function. In this
// fashion, new stubs are _appended_ to the chain of stubs, as lastJump_
// points to the _tail_ of the stub chain.
//
// JIT Code
// +--------+ #=======================#
// | | # v
// |========| # +----------+ +------+
// |== IC ==|=# | Cache Fn |<====| Stub |
// |========| +----------+ ^ +------+
// | |<=# # | #
// | | #======#=========|=====#
// +--------+ Rejoin path |
// |________ |
// | |
// Repatch | |
// IC | |
// Entry | |
// +------------+ |
// | lastJump_ |---------------/
// +------------+
// | ... |
// +------------+
//
class RepatchIonCache : public IonCache
{
protected:
class RepatchStubAppender;
CodeLocationJump initialJump_;
CodeLocationJump lastJump_;
CodeLocationLabel rejoinLabel_;
public:
RepatchIonCache()
: initialJump_(),
lastJump_()
{
}
virtual void reset() override;
// Set the initial jump state of the cache. The initialJump is the inline
// jump that will point to out-of-line code (such as the slow path, or
// stubs), and the rejoinLabel is the position that all out-of-line paths
// will rejoin to.
void emitInitialJump(MacroAssembler& masm, AddCacheState& addState) override;
void bindInitialJump(MacroAssembler& masm, AddCacheState& addState) override;
// Update the labels once the code is finalized.
void updateBaseAddress(JitCode* code, MacroAssembler& masm) override;
virtual void* rejoinAddress() override {
return rejoinLabel_.raw();
}
};
//
// Dispatch caches avoid patching already-running code. Instead, the jump to
// the stub chain is indirect by way of the firstStub_ pointer
// below. Initially the pointer points to the cache function which may attach
// new stubs. Stubs are attached by prepending: when attaching a new stub, we
// jump to the previous stub on failure conditions, then overwrite the
// firstStub_ pointer with the newly generated stub.
//
// This style does not patch the already executing instruction stream, does
// not need to worry about cache coherence of cached jump addresses, and does
// not have to worry about aligning the exit jumps to ensure atomic patching,
// at the expense of an extra memory read to load the very first stub.
//
// ICs that need to work in parallel execution need to be dispatch
// style. Since PJS's removal, nothing else yet uses this style of ICs.
//
// Control flow Pointers Memory load
// =======# ----. .----> ******
// # | | *
// #======> \-----/ *******
//
// Initial state:
//
// The first stub points to the cache function.
//
// JIT Code
// +--------+ .-------.
// | | v |
// |========| +---------------+ +----------+ |
// |== IC ==|====>| Load and jump |====>| Cache Fn | |
// |========| +---------------+ +----------+ |
// | |<=# * # |
// | | #===========*================# |
// +--------+ Rejoin * path |
// |________ * |
// | * |
// Dispatch | * |
// IC **|************ |
// Entry * | |
// +------------+ |
// | firstStub_ |-------------------------------------/
// +------------+
// | ... |
// +------------+
//
// Attaching stubs:
//
// Assign the address of the new stub to firstStub_. The new stub jumps to
// the old address held in firstStub_ on failure. Note that there is no
// concept of a fallback label here, new stubs are _prepended_, as
// firstStub_ always points to the _head_ of the stub chain.
//
// JIT Code
// +--------+ #=====================# .-----.
// | | # v v |
// |========| +---------------+ # +----------+ +------+ |
// |== IC ==|====>| Load and jump |==# | Cache Fn |<====| Stub | |
// |========| +---------------+ +----------+ +------+ |
// | |<=# * # # |
// | | #===========*================#================# |
// +--------+ Rejoin * path |
// |________ * |
// | * |
// Dispatch | * |
// IC **|************ |
// Entry * | |
// +------------+ |
// | firstStub_ |----------------------------------------------------/
// +------------+
// | ... |
// +------------+
//
class DispatchIonCache : public IonCache
{
protected:
class DispatchStubPrepender;
uint8_t* firstStub_;
CodeLocationLabel rejoinLabel_;
CodeOffsetLabel dispatchLabel_;
public:
DispatchIonCache()
: firstStub_(nullptr),
rejoinLabel_(),
dispatchLabel_()
{
}
virtual void reset() override;
virtual void initializeAddCacheState(LInstruction* ins, AddCacheState* addState) override;
void emitInitialJump(MacroAssembler& masm, AddCacheState& addState) override;
void bindInitialJump(MacroAssembler& masm, AddCacheState& addState) override;
// Fix up the first stub pointer once the code is finalized.
void updateBaseAddress(JitCode* code, MacroAssembler& masm) override;
virtual void* rejoinAddress() override {
return rejoinLabel_.raw();
}
};
// Define the cache kind and pre-declare data structures used for calling inline
// caches.
#define CACHE_HEADER(ickind) \
@ -517,7 +368,7 @@ struct CacheLocation {
{ }
};
class GetPropertyIC : public RepatchIonCache
class GetPropertyIC : public IonCache
{
protected:
// Registers live after the cache, excluding output registers. The initial
@ -662,7 +513,7 @@ class GetPropertyIC : public RepatchIonCache
HandleObject obj, MutableHandleValue vp);
};
class SetPropertyIC : public RepatchIonCache
class SetPropertyIC : public IonCache
{
protected:
// Registers live after the cache, excluding output registers. The initial
@ -749,7 +600,7 @@ class SetPropertyIC : public RepatchIonCache
HandleObject obj, HandleValue value);
};
class GetElementIC : public RepatchIonCache
class GetElementIC : public IonCache
{
protected:
LiveRegisterSet liveRegs_;
@ -860,7 +711,7 @@ class GetElementIC : public RepatchIonCache
}
};
class SetElementIC : public RepatchIonCache
class SetElementIC : public IonCache
{
protected:
Register object_;
@ -944,7 +795,7 @@ class SetElementIC : public RepatchIonCache
HandleValue idval, HandleValue value);
};
class BindNameIC : public RepatchIonCache
class BindNameIC : public IonCache
{
protected:
Register scopeChain_;
@ -981,7 +832,7 @@ class BindNameIC : public RepatchIonCache
update(JSContext* cx, HandleScript outerScript, size_t cacheIndex, HandleObject scopeChain);
};
class NameIC : public RepatchIonCache
class NameIC : public IonCache
{
protected:
// Registers live after the cache, excluding output registers. The initial

View File

@ -503,7 +503,6 @@ struct IonScript
}
void toggleBarriers(bool enabled);
void purgeCaches();
void destroyCaches();
void unlinkFromRuntime(FreeOp* fop);
void copySnapshots(const SnapshotWriter* writer);
void copyRecovers(const RecoverWriter* writer);

View File

@ -1707,13 +1707,6 @@ CodeGeneratorARM::generateInvalidateEpilogue()
masm.assumeUnreachable("Should have returned directly to its caller instead of here.");
}
void
DispatchIonCache::initializeAddCacheState(LInstruction* ins, AddCacheState* addState)
{
// Can always use the scratch register on ARM.
addState->dispatchScratch = ScratchRegister;
}
void
CodeGeneratorARM::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic* ins)
{

View File

@ -1797,13 +1797,6 @@ CodeGeneratorMIPS::generateInvalidateEpilogue()
masm.assumeUnreachable("Should have returned directly to its caller instead of here.");
}
void
DispatchIonCache::initializeAddCacheState(LInstruction* ins, AddCacheState* addState)
{
// Can always use the scratch register on MIPS.
addState->dispatchScratch = ScratchRegister;
}
void
CodeGeneratorMIPS::visitLoadTypedArrayElementStatic(LLoadTypedArrayElementStatic* ins)
{

View File

@ -32,8 +32,6 @@ FrameSizeClass FrameSizeClass::FromDepth(uint32_t) { MOZ_CRASH(); }
FrameSizeClass FrameSizeClass::ClassLimit() { MOZ_CRASH(); }
uint32_t FrameSizeClass::frameSize() const { MOZ_CRASH(); }
void DispatchIonCache::initializeAddCacheState(LInstruction*, AddCacheState*) { MOZ_CRASH(); }
const Register ABIArgGenerator::NonArgReturnReg0 = { Registers::invalid_reg };
const Register ABIArgGenerator::NonArgReturnReg1 = { Registers::invalid_reg };
const Register ABIArgGenerator::NonArg_VolatileReg = { Registers::invalid_reg };

View File

@ -796,13 +796,6 @@ CodeGeneratorX64::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc* ins)
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
}
void
DispatchIonCache::initializeAddCacheState(LInstruction* ins, AddCacheState* addState)
{
// Can always use the scratch register on x64.
addState->dispatchScratch = ScratchReg;
}
void
CodeGeneratorX64::visitTruncateDToInt32(LTruncateDToInt32* ins)
{

View File

@ -865,14 +865,6 @@ CodeGeneratorX86::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc* ins)
masm.append(AsmJSGlobalAccess(label, mir->globalDataOffset()));
}
void
DispatchIonCache::initializeAddCacheState(LInstruction* ins, AddCacheState* addState)
{
// On x86, where there is no general purpose scratch register available,
// child cache classes must manually specify a dispatch scratch register.
MOZ_CRASH("x86 needs manual assignment of dispatchScratch");
}
namespace js {
namespace jit {

View File

@ -370,7 +370,7 @@ pref("media.peerconnection.video.start_bitrate", 300);
pref("media.peerconnection.video.max_bitrate", 2000);
#endif
pref("media.navigator.permission.disabled", false);
pref("media.peerconnection.default_iceservers", "[{\"urls\": [\"stun:stun.services.mozilla.com\"]}]");
pref("media.peerconnection.default_iceservers", "[]");
pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments.
pref("media.peerconnection.use_document_iceservers", true);
pref("media.peerconnection.identity.enabled", true);

View File

@ -1922,7 +1922,8 @@ nsSocketTransport::OnSocketDetached(PRFileDesc *fd)
}
}
if (RecoverFromError())
// If we are not offline try again.
if (!gIOService->IsOffline() && RecoverFromError())
mCondition = NS_OK;
else {
mState = STATE_CLOSED;

View File

@ -1252,6 +1252,7 @@ int processConfigLine(char* configLine)
else
{
LOG_ERROR(("Incorrect client auth option modifier for host '%s'", hostname));
delete authoption;
return 1;
}
@ -1260,6 +1261,7 @@ int processConfigLine(char* configLine)
char *hostname_copy = new char[strlen(hostname)+strlen(hostportstring)+2];
if (!hostname_copy) {
LOG_ERROR(("Out of memory"));
delete authoption;
return 1;
}
@ -1270,6 +1272,7 @@ int processConfigLine(char* configLine)
PLHashEntry* entry = PL_HashTableAdd(existingServer->host_clientauth_table, hostname_copy, authoption);
if (!entry) {
LOG_ERROR(("Out of memory"));
delete authoption;
return 1;
}
}
@ -1315,6 +1318,8 @@ int processConfigLine(char* configLine)
PLHashEntry* entry = PL_HashTableAdd(existingServer->host_redir_table, hostname_copy, redir_copy);
if (!entry) {
LOG_ERROR(("Out of memory"));
delete hostname_copy;
delete redir_copy;
return 1;
}
}
@ -1366,7 +1371,10 @@ int parseConfigFile(const char* filePath)
case '\n':
*b++ = 0;
if (processConfigLine(buffer))
{
fclose(f);
return 1;
}
b = buffer;
case '\r':
continue;

View File

@ -18,6 +18,8 @@ support-files =
[test_0015_check_incompat_basic_addons.xul]
[test_0016_check_incompat_basic_license_addons.xul]
[test_0017_check_staging_basic.xul]
skip-if = os != 'win'
reason = Bug 918029 and bug 1164560 - timeout caused by copying too many files.
[test_0021_check_billboard.xul]
[test_0022_check_billboard_license.xul]
[test_0023_check_incompat_billboard.xul]
@ -59,10 +61,10 @@ support-files =
[test_0095_restartNotification_remoteInvalidNumber.xul]
[test_0096_restartNotification_stagedBackground.xul]
[test_0097_restartNotification_stagedServiceBackground.xul]
skip-if = os != 'win'
reason = only Windows has the maintenance service.
[test_0101_background_restartNotification.xul]
[test_0102_background_restartNotification_staging.xul]
skip-if = os == 'linux'
reason = Bug 918029 - timeout caused by copying too many files.
[test_0103_background_restartNotification_stagingService.xul]
skip-if = os != 'win'
reason = only Windows has the maintenance service.

View File

@ -330,7 +330,6 @@ function runTestDefaultWaitForWindowClosed() {
setupFiles();
setupPrefs();
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "1");
removeUpdateDirsAndFiles();
reloadUpdateManagerData();
setupAddons(runTest);
@ -359,7 +358,6 @@ function finishTestDefault() {
verifyTestsRan();
resetPrefs();
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "");
resetFiles();
removeUpdateDirsAndFiles();
reloadUpdateManagerData();

View File

@ -130,10 +130,6 @@ XPCOMUtils.defineLazyGetter(this, "gPrefRoot", function test_gPR() {
return Services.prefs.getBranch(null);
});
XPCOMUtils.defineLazyServiceGetter(this, "gEnv",
"@mozilla.org/process/environment;1",
"nsIEnvironment");
XPCOMUtils.defineLazyGetter(this, "gZipW", function test_gZipW() {
return Cc["@mozilla.org/zipwriter;1"].
createInstance(Ci.nsIZipWriter);

View File

@ -18,7 +18,7 @@
// These are generated at compile time based on the DER file for the channel
// being used
#ifdef MOZ_VERIFY_MAR_SIGNATURE
#ifdef TEST_UPDATER
#ifdef UPDATER_XPCSHELL_CERT
#include "../xpcshellCert.h"
#else
#include "primaryCert.h"
@ -85,7 +85,7 @@ ArchiveReader::VerifySignature()
#ifndef MOZ_VERIFY_MAR_SIGNATURE
return OK;
#else
#ifdef TEST_UPDATER
#ifdef UPDATER_XPCSHELL_CERT
int rv = VerifyLoadedCert(mArchive, xpcshellCertData);
#else
int rv = VerifyLoadedCert(mArchive, primaryCertData);

View File

@ -8,6 +8,6 @@ Program('updater-xpcshell')
updater_rel_path = '../'
DIST_INSTALL = False
DEFINES['TEST_UPDATER'] = True
DEFINES['UPDATER_XPCSHELL_CERT'] = True
include('../updater-common.build')
FAIL_ON_WARNINGS = True

View File

@ -2260,18 +2260,7 @@ UpdateThreadFunc(void *param)
#endif
if (rv == OK && sStagedUpdate && !sIsOSUpdate) {
#ifdef TEST_UPDATER
// The MOZ_TEST_SKIP_UPDATE_STAGE environment variable prevents copying
// the files in dist/bin in the test updater when staging an update since
// this can cause tests to timeout.
if (getenv("MOZ_TEST_SKIP_UPDATE_STAGE")) {
rv = OK;
} else {
rv = CopyInstallDirToDestDir();
}
#else
rv = CopyInstallDirToDestDir();
#endif
}
if (rv == OK) {

View File

@ -4,7 +4,7 @@
// Microsoft Visual C++ generated resource script.
//
#ifdef TEST_UPDATER
#ifdef UPDATER_XPCSHELL_CERT
#include "../resource.h"
#define MANIFEST_PATH "../updater.exe.manifest"
#define COMCTL32_MANIFEST_PATH "../updater.exe.comctl32.manifest"

View File

@ -311,6 +311,7 @@ BlacklistDevicesToDeviceFamily(nsIDOMHTMLCollection* aDevices)
static int32_t
BlacklistFeatureToGfxFeature(const nsAString& aFeature)
{
MOZ_ASSERT(!aFeature.IsEmpty());
if (aFeature.EqualsLiteral("DIRECT2D"))
return nsIGfxInfo::FEATURE_DIRECT2D;
else if (aFeature.EqualsLiteral("DIRECT3D_9_LAYERS"))
@ -337,7 +338,13 @@ BlacklistFeatureToGfxFeature(const nsAString& aFeature)
return nsIGfxInfo::FEATURE_STAGEFRIGHT;
else if (aFeature.EqualsLiteral("WEBRTC_HW_ACCELERATION"))
return nsIGfxInfo::FEATURE_WEBRTC_HW_ACCELERATION;
return 0;
// If we don't recognize the feature, it may be new, and something
// this version doesn't understand. So, nothing to do. This is
// different from feature not being specified at all, in which case
// this method should not get called and we should continue with the
// "all features" blocklisting.
return -1;
}
static int32_t
@ -525,6 +532,11 @@ BlacklistEntryToDriverInfo(nsIDOMNode* aBlacklistEntry,
getter_AddRefs(dataNode))) {
BlacklistNodeToTextValue(dataNode, dataValue);
aDriverInfo.mFeature = BlacklistFeatureToGfxFeature(dataValue);
if (aDriverInfo.mFeature < 0) {
// If we don't recognize the feature, we do not want to proceed.
gfxWarning() << "Unrecognized feature " << NS_ConvertUTF16toUTF8(dataValue).get();
return false;
}
}
// <featureStatus> BLOCKED_DRIVER_VERSION </featureStatus>

View File

@ -848,7 +848,8 @@ DrawThemeWithCairo(gfxContext* aContext, DrawTarget* aDrawTarget,
if (needClip || aTransparency != nsITheme::eOpaque) {
// The widget either needs to be masked or has transparency, so use the slower drawing path.
aDrawTarget->DrawSurface(dataSurface,
Rect(aDrawOrigin, Size(aDrawSize)),
Rect(aSnapped ? aDrawOrigin - aDrawTarget->GetTransform().GetTranslation() : aDrawOrigin,
Size(aDrawSize)),
Rect(0, 0, aDrawSize.width, aDrawSize.height));
} else {
// The widget is a simple opaque rectangle, so just copy it out.

View File

@ -64,7 +64,7 @@ interface nsIGfxInfo : nsISupports
* A set of constants for features that we can ask this GfxInfo object
* about via GetFeatureStatus
*/
/* Don't assign 0 or -1 */
/* Don't assign any value <= 0 */
/* Whether Direct2D is supported for content rendering. */
const long FEATURE_DIRECT2D = 1;
/* Whether Direct3D 9 is supported for layers. */
@ -81,15 +81,15 @@ interface nsIGfxInfo : nsISupports
const long FEATURE_WEBGL_ANGLE = 7;
/* Whether WebGL antialiasing is supported. */
const long FEATURE_WEBGL_MSAA = 8;
/* Whether Stagefright is supported */
/* Whether Stagefright is supported, starting in 17. */
const long FEATURE_STAGEFRIGHT = 9;
/* Whether Webrtc Hardware acceleration is supported */
/* Whether Webrtc Hardware acceleration is supported, starting in 31. */
const long FEATURE_WEBRTC_HW_ACCELERATION = 10;
/* Whether Direct3D 11 is supported for layers. */
/* Whether Direct3D 11 is supported for layers, starting in 32. */
const long FEATURE_DIRECT3D_11_LAYERS = 11;
/* Whether hardware accelerated video decoding is supported. */
/* Whether hardware accelerated video decoding is supported, starting in 36. */
const long FEATURE_HARDWARE_VIDEO_DECODING = 12;
/* Whether Direct3D 11 is supported for ANGLE. */
/* Whether Direct3D 11 is supported for ANGLE, starting in 38. */
const long FEATURE_DIRECT3D_11_ANGLE = 13;
/*