зеркало из https://github.com/mozilla/gecko-dev.git
Merge b-s to m-c.
This commit is contained in:
Коммит
a94e57306e
|
@ -0,0 +1,22 @@
|
|||
diff --git a/gfx/skia/src/core/SkScan_AntiPath.cpp b/gfx/skia/src/core/SkScan_AntiPath.cpp
|
||||
--- a/gfx/skia/src/core/SkScan_AntiPath.cpp
|
||||
+++ b/gfx/skia/src/core/SkScan_AntiPath.cpp
|
||||
@@ -26,17 +26,17 @@
|
||||
this is often faster for large objects with big spans
|
||||
|
||||
NEW_AA is a set of code-changes to try to make both paths produce identical
|
||||
results. Its not quite there yet, though the remaining differences may be
|
||||
in the subsequent blits, and not in the different masks/runs...
|
||||
*/
|
||||
//#define FORCE_SUPERMASK
|
||||
//#define FORCE_RLE
|
||||
-//#define SK_SUPPORT_NEW_AA
|
||||
+#define SK_SUPPORT_NEW_AA
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class BaseSuperBlitter : public SkBlitter {
|
||||
public:
|
||||
BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
|
||||
const SkRegion& clip);
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
diff --git a/gfx/skia/src/effects/SkGradientShader.cpp b/gfx/skia/src/effects/SkGradientShader.cpp
|
||||
--- a/gfx/skia/src/effects/SkGradientShader.cpp
|
||||
+++ b/gfx/skia/src/effects/SkGradientShader.cpp
|
||||
@@ -1652,17 +1652,20 @@ public:
|
||||
}
|
||||
return kRadial2_GradientType;
|
||||
}
|
||||
|
||||
virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) {
|
||||
SkASSERT(count > 0);
|
||||
|
||||
// Zero difference between radii: fill with transparent black.
|
||||
- if (fDiffRadius == 0) {
|
||||
+ // TODO: Is removing this actually correct? Two circles with the
|
||||
+ // same radius, but different centers doesn't sound like it
|
||||
+ // should be cleared
|
||||
+ if (fDiffRadius == 0 && fCenter1 == fCenter2) {
|
||||
sk_bzero(dstC, count * sizeof(*dstC));
|
||||
return;
|
||||
}
|
||||
SkMatrix::MapXYProc dstProc = fDstToIndexProc;
|
||||
TileProc proc = fTileProc;
|
||||
const SkPMColor* SK_RESTRICT cache = this->getCache32();
|
||||
|
||||
SkScalar foura = fA * 4;
|
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
//#define FORCE_SUPERMASK
|
||||
//#define FORCE_RLE
|
||||
//#define SK_SUPPORT_NEW_AA
|
||||
#define SK_SUPPORT_NEW_AA
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
|
@ -1657,7 +1657,10 @@ public:
|
|||
SkASSERT(count > 0);
|
||||
|
||||
// Zero difference between radii: fill with transparent black.
|
||||
if (fDiffRadius == 0) {
|
||||
// TODO: Is removing this actually correct? Two circles with the
|
||||
// same radius, but different centers doesn't sound like it
|
||||
// should be cleared
|
||||
if (fDiffRadius == 0 && fCenter1 == fCenter2) {
|
||||
sk_bzero(dstC, count * sizeof(*dstC));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -99,3 +99,7 @@ patch -p3 < arm-opts.patch
|
|||
patch -p3 < fix-gradient-clamp.patch
|
||||
# Bug 687189 - Implement SkPaint::getPosTextPath.
|
||||
patch -p3 < getpostextpath.patch
|
||||
# Bug 688365 - Enable Skia 'New AA' mode.
|
||||
patch -p3 < new-aa.patch
|
||||
# Bug 688366 - Fix Skia marking radial gradients with the same radius as invalid.
|
||||
patch -p3 < radial-gradients.patch
|
||||
|
|
|
@ -77,6 +77,21 @@ PreparePatternForUntiledDrawing(gfxPattern* aPattern,
|
|||
// the surface type.
|
||||
switch (currentTarget->GetType()) {
|
||||
|
||||
// The printing surfaces don't natively support or need
|
||||
// EXTEND_PAD for padding the edges. Using EXTEND_PAD this way
|
||||
// is suboptimal as it will result in the printing surface
|
||||
// creating a new image for each fill operation. The pattern
|
||||
// will be painted to the image to pad out the pattern, then
|
||||
// the new image will be used as the source. This increases
|
||||
// printing time and memory use, and prevents the use of mime
|
||||
// data from cairo_surface_set_mime_data(). Bug 691061.
|
||||
case gfxASurface::SurfaceTypePDF:
|
||||
case gfxASurface::SurfaceTypePS:
|
||||
case gfxASurface::SurfaceTypeWin32Printing:
|
||||
aPattern->SetExtend(gfxPattern::EXTEND_NONE);
|
||||
aPattern->SetFilter(aDefaultFilter);
|
||||
break;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
case gfxASurface::SurfaceTypeXlib:
|
||||
{
|
||||
|
|
|
@ -295,8 +295,13 @@ class HashTable : private AllocPolicy
|
|||
uint64 mutationCount;
|
||||
#endif
|
||||
|
||||
static const unsigned sMinSizeLog2 = 4;
|
||||
/* The default initial capacity is 16, but you can ask for as small as 4. */
|
||||
static const unsigned sMinSizeLog2 = 2;
|
||||
static const unsigned sMinSize = 1 << sMinSizeLog2;
|
||||
static const unsigned sDefaultInitSizeLog2 = 4;
|
||||
public:
|
||||
static const unsigned sDefaultInitSize = 1 << sDefaultInitSizeLog2;
|
||||
private:
|
||||
static const unsigned sMaxInit = JS_BIT(23);
|
||||
static const unsigned sMaxCapacity = JS_BIT(24);
|
||||
static const unsigned sHashBits = tl::BitSize<HashNumber>::result;
|
||||
|
@ -986,7 +991,7 @@ class HashMap
|
|||
* init after constructing a HashMap and check the return value.
|
||||
*/
|
||||
HashMap(AllocPolicy a = AllocPolicy()) : impl(a) {}
|
||||
bool init(uint32 len = 0) { return impl.init(len); }
|
||||
bool init(uint32 len = Impl::sDefaultInitSize) { return impl.init(len); }
|
||||
bool initialized() const { return impl.initialized(); }
|
||||
|
||||
/*
|
||||
|
@ -1214,7 +1219,7 @@ class HashSet
|
|||
* init after constructing a HashSet and check the return value.
|
||||
*/
|
||||
HashSet(AllocPolicy a = AllocPolicy()) : impl(a) {}
|
||||
bool init(uint32 len = 0) { return impl.init(len); }
|
||||
bool init(uint32 len = Impl::sDefaultInitSize) { return impl.init(len); }
|
||||
bool initialized() const { return impl.initialized(); }
|
||||
|
||||
/*
|
||||
|
|
|
@ -2705,7 +2705,6 @@ dnl Configure JIT support
|
|||
|
||||
case "$target" in
|
||||
i?86-*)
|
||||
ENABLE_TRACEJIT=1
|
||||
NANOJIT_ARCH=i386
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
|
@ -2715,7 +2714,6 @@ i?86-*)
|
|||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
x86_64*-*)
|
||||
ENABLE_TRACEJIT=1
|
||||
NANOJIT_ARCH=X64
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
|
@ -2725,7 +2723,6 @@ x86_64*-*)
|
|||
AC_DEFINE(JS_PUNBOX64)
|
||||
;;
|
||||
arm*-*)
|
||||
ENABLE_TRACEJIT=1
|
||||
NANOJIT_ARCH=ARM
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
|
@ -2735,7 +2732,6 @@ arm*-*)
|
|||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
sparc*-*)
|
||||
ENABLE_TRACEJIT=1
|
||||
NANOJIT_ARCH=Sparc
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
|
@ -2758,9 +2754,10 @@ MOZ_ARG_DISABLE_BOOL(polyic,
|
|||
[ --disable-polyic Disable use of PICs by JIT compiler],
|
||||
ENABLE_POLYIC= )
|
||||
|
||||
MOZ_ARG_DISABLE_BOOL(tracejit,
|
||||
[ --disable-tracejit Disable tracing JIT support],
|
||||
ENABLE_TRACEJIT=)
|
||||
MOZ_ARG_ENABLE_BOOL(tracejit,
|
||||
[ --enable-tracejit Enable tracing JIT support],
|
||||
ENABLE_TRACEJIT=1,
|
||||
ENABLE_TRACEJIT= )
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(methodjit-spew,
|
||||
[ --enable-methodjit-spew Enable method JIT spew support],
|
||||
|
|
|
@ -2482,13 +2482,6 @@ gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
|||
*coords[index] = NSAppUnitsToFloatPixels(coord.GetCoordValue(), aFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An offset of (0,0) results in the perspective-origin being at the centre of the element,
|
||||
* so include a shift of the centre point to (0,0).
|
||||
*/
|
||||
result.x -= NSAppUnitsToFloatPixels(boundingRect.width, aFactor)/2;
|
||||
result.y -= NSAppUnitsToFloatPixels(boundingRect.height, aFactor)/2;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -2551,7 +2544,10 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
|||
perspective._34 =
|
||||
-1.0 / NSAppUnitsToFloatPixels(parentDisp->mChildPerspective.GetCoordValue(),
|
||||
aFactor);
|
||||
result = result * nsLayoutUtils::ChangeMatrixBasis(toPerspectiveOrigin, perspective);
|
||||
/* At the point when perspective is applied, we have been translated to the transform origin.
|
||||
* The translation to the perspective origin is the difference between these values.
|
||||
*/
|
||||
result = result * nsLayoutUtils::ChangeMatrixBasis(toPerspectiveOrigin - toMozOrigin, perspective);
|
||||
}
|
||||
|
||||
if (aFrame->Preserves3D() && nsLayoutUtils::Are3DTransformsEnabled()) {
|
||||
|
|
|
@ -35,3 +35,5 @@ fails == preserve3d-1a.html preserve3d-1-ref.html
|
|||
== sorting-2a.html sorting-2-ref.html
|
||||
# Parallel planes, same z depth (shouldn't be sorted!)
|
||||
== sorting-2b.html sorting-2-ref.html
|
||||
# Different, but equivalent (for the given transform) transform origins
|
||||
== rotatex-transformorigin-1a.html rotatex-transformorigin-1-ref.html
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="-moz-perspective: 1000px;">
|
||||
<div style="-moz-transform: rotatex(45deg); -moz-transform-origin: top right; width: 100px; height: 100px;">
|
||||
Test Text
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="-moz-perspective: 1000px;">
|
||||
<div style="-moz-transform: rotatex(45deg); -moz-transform-origin: top left; width: 100px; height: 100px;">
|
||||
Test Text
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -81,7 +81,7 @@ _BROWSER_FILES = \
|
|||
browser_preferences_text.js \
|
||||
browser_preferences_fulltoggle.js \
|
||||
browser_rect.js \
|
||||
browser_rememberPassword.js \
|
||||
$(info browser_rememberPassword.js is disabled because it is random orange on XUL fennec (bug 698387)) \
|
||||
browser_scroll.js \
|
||||
browser_scroll.html \
|
||||
browser_scrollbar.js \
|
||||
|
@ -89,8 +89,8 @@ _BROWSER_FILES = \
|
|||
browser_select.js \
|
||||
browser_sessionstore.js \
|
||||
browser_tabs.js \
|
||||
browser_tapping.js \
|
||||
browser_tap_content.html \
|
||||
$(info browser_tapping.js is disabled because it is random orange on XUL fennec (bug 698387)) \
|
||||
$(info browser_tap_content.html is disabled because it is random orange on XUL fennec (bug 698387)) \
|
||||
browser_tapping_edit.js \
|
||||
browser_tap_contentedit.html \
|
||||
browser_test.js \
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
#include <math.h> // for log()
|
||||
#include "mozilla/Util.h" // for DebugOnly
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
||||
|
@ -1764,6 +1765,7 @@ nsCacheService::ActivateEntry(nsCacheRequest * request,
|
|||
nsCacheEntry *
|
||||
nsCacheService::SearchCacheDevices(nsCString * key, nsCacheStoragePolicy policy, bool *collision)
|
||||
{
|
||||
Telemetry::AutoTimer<Telemetry::CACHE_DEVICE_SEARCH> timer;
|
||||
nsCacheEntry * entry = nsnull;
|
||||
|
||||
CACHE_LOG_DEBUG(("mMemoryDevice: 0x%p\n", mMemoryDevice));
|
||||
|
|
|
@ -503,6 +503,7 @@ nsDiskCacheDevice::GetDeviceID()
|
|||
nsCacheEntry *
|
||||
nsDiskCacheDevice::FindEntry(nsCString * key, bool *collision)
|
||||
{
|
||||
Telemetry::AutoTimer<Telemetry::CACHE_DISK_SEARCH> timer;
|
||||
if (!Initialized()) return nsnull; // NS_ERROR_NOT_INITIALIZED
|
||||
nsDiskCacheRecord record;
|
||||
nsDiskCacheBinding * binding = nsnull;
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "nsISeekableStream.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -1340,6 +1341,7 @@ nsOfflineCacheDevice::GetDeviceID()
|
|||
nsCacheEntry *
|
||||
nsOfflineCacheDevice::FindEntry(nsCString *fullKey, bool *collision)
|
||||
{
|
||||
mozilla::Telemetry::AutoTimer<mozilla::Telemetry::CACHE_OFFLINE_SEARCH> timer;
|
||||
LOG(("nsOfflineCacheDevice::FindEntry [key=%s]\n", fullKey->get()));
|
||||
|
||||
// SELECT * FROM moz_cache WHERE key = ?
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsCache.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
// The memory cache implements the "LRU-SP" caching algorithm
|
||||
// described in "LRU-SP: A Size-Adjusted and Popularity-Aware LRU Replacement
|
||||
|
@ -146,6 +147,7 @@ nsMemoryCacheDevice::GetDeviceID()
|
|||
nsCacheEntry *
|
||||
nsMemoryCacheDevice::FindEntry(nsCString * key, bool *collision)
|
||||
{
|
||||
mozilla::Telemetry::AutoTimer<mozilla::Telemetry::CACHE_MEMORY_SEARCH> timer;
|
||||
nsCacheEntry * entry = mMemCacheEntries.GetEntry(key);
|
||||
if (!entry) return nsnull;
|
||||
|
||||
|
|
|
@ -367,7 +367,7 @@ nsFileChannel::OpenContentStream(bool async, nsIInputStream **result,
|
|||
SetContentType(NS_LITERAL_CSTRING(APPLICATION_OCTET_STREAM));
|
||||
} else {
|
||||
nsCAutoString contentType;
|
||||
nsresult rv = MakeFileInputStream(file, stream, contentType);
|
||||
rv = MakeFileInputStream(file, stream, contentType);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
|
|
@ -77,6 +77,13 @@ nsHtml5OwningUTF16Buffer::FalliblyCreate(PRInt32 aLength)
|
|||
return newObj.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5OwningUTF16Buffer::Swap(nsHtml5OwningUTF16Buffer* aOther)
|
||||
{
|
||||
nsHtml5UTF16Buffer::Swap(aOther);
|
||||
}
|
||||
|
||||
|
||||
// Not using macros for AddRef and Release in order to be able to refcount on
|
||||
// and create on different threads.
|
||||
|
||||
|
|
|
@ -75,6 +75,11 @@ class nsHtml5OwningUTF16Buffer : public nsHtml5UTF16Buffer
|
|||
static already_AddRefed<nsHtml5OwningUTF16Buffer>
|
||||
FalliblyCreate(PRInt32 aLength);
|
||||
|
||||
/**
|
||||
* Swap start, end and buffer fields with another object.
|
||||
*/
|
||||
void Swap(nsHtml5OwningUTF16Buffer* aOther);
|
||||
|
||||
nsrefcnt AddRef();
|
||||
nsrefcnt Release();
|
||||
private:
|
||||
|
|
|
@ -287,25 +287,112 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
|||
NS_ASSERTION(!mStreamParser,
|
||||
"Had stream parser but got document.close().");
|
||||
mDocumentClosed = true;
|
||||
if (!mBlocked) {
|
||||
if (!mBlocked && !mInDocumentWrite) {
|
||||
ParseUntilBlocked();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we got this far, we are dealing with a document.write or
|
||||
// document.writeln call--not document.close().
|
||||
|
||||
NS_ASSERTION(IsInsertionPointDefined(),
|
||||
"Doc.write reached parser with undefined insertion point.");
|
||||
|
||||
NS_ASSERTION(!(mStreamParser && !aKey),
|
||||
"Got a null key in a non-script-created parser");
|
||||
|
||||
// XXX is this optimization bogus?
|
||||
if (aSourceBuffer.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// This guard is here to prevent document.close from tokenizing synchronously
|
||||
// while a document.write (that wrote the script that called document.close!)
|
||||
// is still on the call stack.
|
||||
mozilla::AutoRestore<bool> guard(mInDocumentWrite);
|
||||
mInDocumentWrite = true;
|
||||
|
||||
// The script is identified by aKey. If there's nothing in the buffer
|
||||
// chain for that key, we'll insert at the head of the queue.
|
||||
// When the script leaves something in the queue, a zero-length
|
||||
// key-holder "buffer" is inserted in the queue. If the same script
|
||||
// leaves something in the chain again, it will be inserted immediately
|
||||
// before the old key holder belonging to the same script.
|
||||
//
|
||||
// We don't do the actual data insertion yet in the hope that the data gets
|
||||
// tokenized and there no data or less data to copy to the heap after
|
||||
// tokenization. Also, this way, we avoid inserting one empty data buffer
|
||||
// per document.write, which matters for performance when the parser isn't
|
||||
// blocked and a badly-authored script calls document.write() once per
|
||||
// input character. (As seen in a benchmark!)
|
||||
//
|
||||
// The insertion into the input stream happens conceptually before anything
|
||||
// gets tokenized. To make sure multi-level document.write works right,
|
||||
// it's necessary to establish the location of our parser key up front
|
||||
// in case this is the first write with this key.
|
||||
//
|
||||
// In a document.open() case, the first write level has a null key, so that
|
||||
// case is handled separately, because normal buffers containing data
|
||||
// have null keys.
|
||||
|
||||
// These don't need to be owning references, because they always point to
|
||||
// the buffer queue and buffers can't be removed from the buffer queue
|
||||
// before document.write() returns. The buffer queue clean-up happens the
|
||||
// next time ParseUntilBlocked() is called.
|
||||
// However, they are made owning just in case the reasoning above is flawed
|
||||
// and a flaw would lead to worse problems with plain pointers. If this
|
||||
// turns out to be a perf problem, it's worthwhile to consider making
|
||||
// prevSearchbuf a plain pointer again.
|
||||
nsRefPtr<nsHtml5OwningUTF16Buffer> prevSearchBuf;
|
||||
nsRefPtr<nsHtml5OwningUTF16Buffer> firstLevelMarker;
|
||||
|
||||
if (aKey) {
|
||||
if (mFirstBuffer == mLastBuffer) {
|
||||
nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey);
|
||||
keyHolder->next = mLastBuffer;
|
||||
mFirstBuffer = keyHolder;
|
||||
} else if (mFirstBuffer->key != aKey) {
|
||||
prevSearchBuf = mFirstBuffer;
|
||||
for (;;) {
|
||||
if (prevSearchBuf->next == mLastBuffer) {
|
||||
// key was not found
|
||||
nsHtml5OwningUTF16Buffer* keyHolder =
|
||||
new nsHtml5OwningUTF16Buffer(aKey);
|
||||
keyHolder->next = mFirstBuffer;
|
||||
mFirstBuffer = keyHolder;
|
||||
prevSearchBuf = nsnull;
|
||||
break;
|
||||
}
|
||||
if (prevSearchBuf->next->key == aKey) {
|
||||
// found a key holder
|
||||
break;
|
||||
}
|
||||
prevSearchBuf = prevSearchBuf->next;
|
||||
}
|
||||
} // else mFirstBuffer is the keyholder
|
||||
|
||||
// prevSearchBuf is the previous buffer before the keyholder or null if
|
||||
// there isn't one.
|
||||
} else {
|
||||
// We have a first-level write in the document.open() case. We insert
|
||||
// before mLastBuffer. We need to put a marker there, because otherwise
|
||||
// additional document.writes from nested event loops would insert in the
|
||||
// wrong place. Sigh.
|
||||
firstLevelMarker = new nsHtml5OwningUTF16Buffer((void*)nsnull);
|
||||
if (mFirstBuffer == mLastBuffer) {
|
||||
firstLevelMarker->next = mLastBuffer;
|
||||
mFirstBuffer = firstLevelMarker;
|
||||
} else {
|
||||
prevSearchBuf = mFirstBuffer;
|
||||
while (prevSearchBuf->next != mLastBuffer) {
|
||||
prevSearchBuf = prevSearchBuf->next;
|
||||
}
|
||||
firstLevelMarker->next = mLastBuffer;
|
||||
prevSearchBuf->next = firstLevelMarker;
|
||||
}
|
||||
}
|
||||
|
||||
nsHtml5DependentUTF16Buffer stackBuffer(aSourceBuffer);
|
||||
|
||||
while (!mBlocked && stackBuffer.hasMore()) {
|
||||
|
@ -355,60 +442,35 @@ nsHtml5Parser::Parse(const nsAString& aSourceBuffer,
|
|||
}
|
||||
}
|
||||
|
||||
// The buffer is inserted to the stream here in case it won't be parsed
|
||||
// to completion.
|
||||
// The script is identified by aKey. If there's nothing in the buffer
|
||||
// chain for that key, we'll insert at the head of the queue.
|
||||
// When the script leaves something in the queue, a zero-length
|
||||
// key-holder "buffer" is inserted in the queue. If the same script
|
||||
// leaves something in the chain again, it will be inserted immediately
|
||||
// before the old key holder belonging to the same script.
|
||||
nsHtml5OwningUTF16Buffer* prevSearchBuf = nsnull;
|
||||
nsHtml5OwningUTF16Buffer* searchBuf = mFirstBuffer;
|
||||
|
||||
// after document.open, the first level of document.write has null key
|
||||
if (aKey) {
|
||||
while (searchBuf != mLastBuffer) {
|
||||
if (searchBuf->key == aKey) {
|
||||
// found a key holder
|
||||
// now insert the new buffer between the previous buffer
|
||||
// and the key holder if we have a buffer left.
|
||||
if (heapBuffer) {
|
||||
heapBuffer->next = searchBuf;
|
||||
if (prevSearchBuf) {
|
||||
prevSearchBuf->next = heapBuffer;
|
||||
} else {
|
||||
mFirstBuffer = heapBuffer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
prevSearchBuf = searchBuf;
|
||||
searchBuf = searchBuf->next;
|
||||
}
|
||||
if (searchBuf == mLastBuffer) {
|
||||
// key was not found
|
||||
nsHtml5OwningUTF16Buffer* keyHolder = new nsHtml5OwningUTF16Buffer(aKey);
|
||||
keyHolder->next = mFirstBuffer;
|
||||
if (heapBuffer) {
|
||||
heapBuffer->next = keyHolder;
|
||||
if (heapBuffer) {
|
||||
// We have something to insert before the keyholder holding in the non-null
|
||||
// aKey case and we have something to swap into firstLevelMarker in the
|
||||
// null aKey case.
|
||||
if (aKey) {
|
||||
NS_ASSERTION(mFirstBuffer != mLastBuffer,
|
||||
"Where's the keyholder?");
|
||||
// the key holder is still somewhere further down the list from
|
||||
// prevSearchBuf (which may be null)
|
||||
if (mFirstBuffer->key == aKey) {
|
||||
NS_ASSERTION(!prevSearchBuf,
|
||||
"Non-null prevSearchBuf when mFirstBuffer is the key holder?");
|
||||
heapBuffer->next = mFirstBuffer;
|
||||
mFirstBuffer = heapBuffer;
|
||||
} else {
|
||||
mFirstBuffer = keyHolder;
|
||||
if (!prevSearchBuf) {
|
||||
prevSearchBuf = mFirstBuffer;
|
||||
}
|
||||
// We created a key holder earlier, so we will find it without walking
|
||||
// past the end of the list.
|
||||
while (prevSearchBuf->next->key != aKey) {
|
||||
prevSearchBuf = prevSearchBuf->next;
|
||||
}
|
||||
heapBuffer->next = prevSearchBuf->next;
|
||||
prevSearchBuf->next = heapBuffer;
|
||||
}
|
||||
}
|
||||
} else if (heapBuffer) {
|
||||
// we have a first level document.write after document.open()
|
||||
// insert immediately before mLastBuffer
|
||||
while (searchBuf != mLastBuffer) {
|
||||
prevSearchBuf = searchBuf;
|
||||
searchBuf = searchBuf->next;
|
||||
}
|
||||
heapBuffer->next = mLastBuffer;
|
||||
if (prevSearchBuf) {
|
||||
prevSearchBuf->next = heapBuffer;
|
||||
} else {
|
||||
mFirstBuffer = heapBuffer;
|
||||
NS_ASSERTION(firstLevelMarker, "How come we don't have a marker.");
|
||||
firstLevelMarker->Swap(heapBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -657,14 +719,12 @@ nsHtml5Parser::ParseUntilBlocked()
|
|||
NS_PRECONDITION(!mExecutor->IsFragmentMode(),
|
||||
"ParseUntilBlocked called in fragment mode.");
|
||||
|
||||
if (mBlocked ||
|
||||
mExecutor->IsComplete() ||
|
||||
mExecutor->IsBroken() ||
|
||||
mInDocumentWrite) {
|
||||
if (mBlocked || mExecutor->IsComplete() || mExecutor->IsBroken()) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mExecutor->HasStarted(), "Bad life cycle.");
|
||||
NS_ASSERTION(!mInDocumentWrite,
|
||||
"ParseUntilBlocked entered while in doc.write!");
|
||||
|
||||
mDocWriteSpeculatorActive = false;
|
||||
|
||||
|
|
|
@ -53,3 +53,17 @@ nsHtml5UTF16Buffer::DeleteBuffer()
|
|||
{
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5UTF16Buffer::Swap(nsHtml5UTF16Buffer* aOther)
|
||||
{
|
||||
PRUnichar* tempBuffer = buffer;
|
||||
PRInt32 tempStart = start;
|
||||
PRInt32 tempEnd = end;
|
||||
buffer = aOther->buffer;
|
||||
start = aOther->start;
|
||||
end = aOther->end;
|
||||
aOther->buffer = tempBuffer;
|
||||
aOther->start = tempStart;
|
||||
aOther->end = tempEnd;
|
||||
}
|
||||
|
|
|
@ -43,3 +43,8 @@ protected:
|
|||
* For working around the privacy of |buffer| in the generated code.
|
||||
*/
|
||||
void DeleteBuffer();
|
||||
|
||||
/**
|
||||
* For working around the privacy of |buffer| in the generated code.
|
||||
*/
|
||||
void Swap(nsHtml5UTF16Buffer* aOther);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<!DOCTYPE html>CcBbAa
|
|
@ -0,0 +1,2 @@
|
|||
<!DOCTYPE html>
|
||||
<body><script>document.write("\u003cscript>document.write(\"\\u003cscript src='bug696651-external.js'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); document.write("a");</script>
|
|
@ -0,0 +1 @@
|
|||
<!DOCTYPE html><iframe src="data:text/html,<!DOCTYPE html>CcBbAa"></iframe>
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<iframe></iframe>
|
||||
<script>
|
||||
var doc = document.getElementsByTagName("iframe")[0].contentDocument;
|
||||
doc.open(); doc.write("\u003cscript>document.write(\"\\u003cscript src='bug696651-external.js'>\\u003c/script>B\"); document.write(\"b\");\u003c/script>A"); doc.write("a"); doc.close();</script>
|
|
@ -0,0 +1 @@
|
|||
document.write("C"); document.write("c");
|
|
@ -5,3 +5,5 @@
|
|||
== bug592656-1.html bug592656-1-ref.html
|
||||
== bug608373-1.html bug608373-1-ref.html
|
||||
== view-source:bug673094-1.html view-source:bug673094-1-ref.html
|
||||
== bug696651-1.html bug696651-1-ref.html
|
||||
== bug696651-2.html bug696651-2-ref.html
|
||||
|
|
|
@ -162,6 +162,10 @@ HISTOGRAM(HTTP_CACHE_DISPOSITION, 1, 5, 5, LINEAR, "HTTP Cache Hit, Reval, Faile
|
|||
HISTOGRAM(HTTP_DISK_CACHE_DISPOSITION, 1, 5, 5, LINEAR, "HTTP Disk Cache Hit, Reval, Failed-Reval, Miss")
|
||||
HISTOGRAM(HTTP_MEMORY_CACHE_DISPOSITION, 1, 5, 5, LINEAR, "HTTP Memory Cache Hit, Reval, Failed-Reval, Miss")
|
||||
HISTOGRAM(HTTP_OFFLINE_CACHE_DISPOSITION, 1, 5, 5, LINEAR, "HTTP Offline Cache Hit, Reval, Failed-Reval, Miss")
|
||||
HISTOGRAM(CACHE_DEVICE_SEARCH, 1, 100, 100, LINEAR, "Time to search cache (ms)")
|
||||
HISTOGRAM(CACHE_MEMORY_SEARCH, 1, 100, 100, LINEAR, "Time to search memory cache (ms)")
|
||||
HISTOGRAM(CACHE_DISK_SEARCH, 1, 100, 100, LINEAR, "Time to search disk cache (ms)")
|
||||
HISTOGRAM(CACHE_OFFLINE_SEARCH, 1, 100, 100, LINEAR, "Time to search offline cache (ms)")
|
||||
|
||||
HISTOGRAM(FIND_PLUGINS, 1, 3000, 10, EXPONENTIAL, "Time spent scanning filesystem for plugins (ms)")
|
||||
HISTOGRAM(CHECK_JAVA_ENABLED, 1, 3000, 10, EXPONENTIAL, "Time spent checking if Java is enabled (ms)")
|
||||
|
|
Загрузка…
Ссылка в новой задаче