summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2013-03-27 14:30:38 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2013-03-27 14:30:38 +0100
commit37f074e127ba1df465b79664fd4d487fad91a2ce (patch)
tree5819feae97bbc1684fc70d867b843bd04ac8f411
parent99783e2c7e917224da401ddbd33354c131b3a377 (diff)
parent909c9942ce927c3dac5f850d9bc110a66a72d397 (diff)
downloadqtwebkit-37f074e127ba1df465b79664fd4d487fad91a2ce.tar.gz
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I7f624a8e4ba9491c3ec635ffcb66a16c69bf8188
-rw-r--r--.qmake.conf2
-rw-r--r--Source/JavaScriptCore/JSCTypedArrayStubs.h5
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.cpp24
-rw-r--r--Source/JavaScriptCore/assembler/ARMAssembler.h20
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h45
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h11
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h7
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp4
-rw-r--r--Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp32
-rw-r--r--Source/JavaScriptCore/bytecompiler/Label.h6
-rw-r--r--Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp11
-rw-r--r--Source/JavaScriptCore/dfg/DFGGraph.h27
-rw-r--r--Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp25
-rw-r--r--Source/JavaScriptCore/dfg/DFGRepatch.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp2
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp9
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp20
-rw-r--r--Source/JavaScriptCore/llint/LLIntExceptions.cpp6
-rw-r--r--Source/JavaScriptCore/llint/LLIntSlowPaths.cpp7
-rw-r--r--Source/JavaScriptCore/llint/LowLevelInterpreter.cpp11
-rw-r--r--Source/JavaScriptCore/offlineasm/ast.rb2
-rw-r--r--Source/JavaScriptCore/offlineasm/cloop.rb2
-rw-r--r--Source/JavaScriptCore/runtime/JSTypeInfo.h3
-rw-r--r--Source/JavaScriptCore/runtime/Operations.h9
-rw-r--r--Source/WebCore/bindings/scripts/CodeGeneratorJS.pm13
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp2
-rw-r--r--Source/WebCore/rendering/RenderBox.cpp1
-rw-r--r--Source/WebCore/rendering/RenderFrameSet.cpp8
-rw-r--r--Source/WebKit2/UIProcess/PageViewportController.cpp25
-rw-r--r--Source/WebKit2/UIProcess/PageViewportController.h9
-rw-r--r--Source/WebKit2/UIProcess/WebPageProxy.h1
-rw-r--r--Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp79
-rw-r--r--Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h26
-rw-r--r--Tools/MiniBrowser/qt/raw/View.cpp2
34 files changed, 329 insertions, 131 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 7f9e1dacb..357f8176d 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -3,4 +3,4 @@ MODULE_QMAKE_OUTDIR = $$shadowed($$PWD/Tools/qmake)
QMAKEPATH += $$PWD/Tools/qmake $$MODULE_QMAKE_OUTDIR
load(qt_build_config)
-MODULE_VERSION = 5.0.2
+MODULE_VERSION = 5.1.0
diff --git a/Source/JavaScriptCore/JSCTypedArrayStubs.h b/Source/JavaScriptCore/JSCTypedArrayStubs.h
index 2e273f66f..91481fab0 100644
--- a/Source/JavaScriptCore/JSCTypedArrayStubs.h
+++ b/Source/JavaScriptCore/JSCTypedArrayStubs.h
@@ -184,7 +184,10 @@ static EncodedJSValue JSC_HOST_CALL constructJS##name##Array(ExecState* callFram
if (length < 0) \
return JSValue::encode(jsUndefined()); \
Structure* structure = JS##name##Array::createStructure(callFrame->globalData(), callFrame->lexicalGlobalObject(), callFrame->lexicalGlobalObject()->objectPrototype()); \
- return JSValue::encode(JS##name##Array::create(structure, callFrame->lexicalGlobalObject(), name##Array::create(length)));\
+ RefPtr<name##Array> buffer = name##Array::create(length); \
+ if (!buffer) \
+ return throwVMError(callFrame, createRangeError(callFrame, "ArrayBuffer size is not a small enough positive integer.")); \
+ return JSValue::encode(JS##name##Array::create(structure, callFrame->lexicalGlobalObject(), buffer.release())); \
}
TYPED_ARRAY(Uint8, uint8_t);
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.cpp b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
index 9655557a5..6912d1ea3 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.cpp
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.cpp
@@ -297,8 +297,15 @@ void ARMAssembler::baseIndexTransfer32(DataTransferTypeA transferType, RegisterI
return;
}
- add(ARMRegisters::S1, base, op2);
- dataTransfer32(transferType, srcDst, ARMRegisters::S1, offset);
+ if (offset <= 0xfffff && offset >= -0xfffff) {
+ add(ARMRegisters::S0, base, op2);
+ dataTransfer32(transferType, srcDst, ARMRegisters::S0, offset);
+ return;
+ }
+
+ moveImm(offset, ARMRegisters::S0);
+ add(ARMRegisters::S0, ARMRegisters::S0, op2);
+ dtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
}
void ARMAssembler::dataTransfer16(DataTransferTypeB transferType, RegisterID srcDst, RegisterID base, int32_t offset)
@@ -333,8 +340,17 @@ void ARMAssembler::baseIndexTransfer16(DataTransferTypeB transferType, RegisterI
return;
}
- add(ARMRegisters::S1, base, lsl(index, scale));
- dataTransfer16(transferType, srcDst, ARMRegisters::S1, offset);
+ ARMWord op2 = lsl(index, scale);
+
+ if (offset <= 0xffff && offset >= -0xffff) {
+ add(ARMRegisters::S0, base, op2);
+ dataTransfer16(transferType, srcDst, ARMRegisters::S0, offset);
+ return;
+ }
+
+ moveImm(offset, ARMRegisters::S0);
+ add(ARMRegisters::S0, ARMRegisters::S0, op2);
+ halfDtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
}
void ARMAssembler::dataTransferFloat(DataTransferTypeFloat transferType, FPRegisterID srcDst, RegisterID base, int32_t offset)
diff --git a/Source/JavaScriptCore/assembler/ARMAssembler.h b/Source/JavaScriptCore/assembler/ARMAssembler.h
index ebab46d98..18b10179c 100644
--- a/Source/JavaScriptCore/assembler/ARMAssembler.h
+++ b/Source/JavaScriptCore/assembler/ARMAssembler.h
@@ -402,13 +402,6 @@ namespace JSC {
emitInstruction(toARMWord(cc) | MOV | SetConditionalCodes, rd, ARMRegisters::r0, op2);
}
- static void revertJump(void* instructionStart, RegisterID rd, ARMWord imm)
- {
- ARMWord* insn = reinterpret_cast<ARMWord*>(instructionStart);
- ARMWord* address = getLdrImmAddress(insn);
- *address = imm;
- }
-
void bic(int rd, int rn, ARMWord op2, Condition cc = AL)
{
emitInstruction(toARMWord(cc) | BIC, rd, rn, op2);
@@ -904,7 +897,7 @@ namespace JSC {
static void replaceWithJump(void* instructionStart, void* to)
{
- ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart) - 1;
+ ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
intptr_t difference = reinterpret_cast<intptr_t>(to) - (reinterpret_cast<intptr_t>(instruction) + DefaultPrefetchOffset * sizeof(ARMWord));
if (!(difference & 1)) {
@@ -952,6 +945,17 @@ namespace JSC {
}
}
+ static void revertBranchPtrWithPatch(void* instructionStart, RegisterID rn, ARMWord imm)
+ {
+ ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
+
+ ASSERT((instruction[2] & LdrPcImmediateInstructionMask) == LdrPcImmediateInstruction);
+ instruction[0] = toARMWord(AL) | ((instruction[2] & 0x0fff0fff) + sizeof(ARMWord)) | RD(ARMRegisters::S1);
+ *getLdrImmAddress(instruction) = imm;
+ instruction[1] = toARMWord(AL) | CMP | SetConditionalCodes | RN(rn) | RM(ARMRegisters::S1);
+ cacheFlush(instruction, 2 * sizeof(ARMWord));
+ }
+
// Address operations
static void* getRelocatedAddress(void* code, AssemblerLabel label)
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index b93ec6e63..aa402e208 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1262,6 +1262,20 @@ public:
m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T3, imm.m_value.imm4, rd, imm);
}
+#if OS(LINUX) || OS(QNX)
+ static void revertJumpTo_movT3movtcmpT2(void* instructionStart, RegisterID left, RegisterID right, uintptr_t imm)
+ {
+ uint16_t* address = static_cast<uint16_t*>(instructionStart);
+ ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(imm));
+ ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(imm >> 16));
+ address[0] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOV_imm_T3, lo16);
+ address[1] = twoWordOp5i6Imm4Reg4EncodedImmSecond(right, lo16);
+ address[2] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16);
+ address[3] = twoWordOp5i6Imm4Reg4EncodedImmSecond(right, hi16);
+ address[4] = OP_CMP_reg_T2 | left;
+ cacheFlush(address, sizeof(uint16_t) * 5);
+ }
+#else
static void revertJumpTo_movT3(void* instructionStart, RegisterID rd, ARMThumbImmediate imm)
{
ASSERT(imm.isValid());
@@ -1273,6 +1287,7 @@ public:
address[1] = twoWordOp5i6Imm4Reg4EncodedImmSecond(rd, imm);
cacheFlush(address, sizeof(uint16_t) * 2);
}
+#endif
ALWAYS_INLINE void mov(RegisterID rd, ARMThumbImmediate imm)
{
@@ -1858,7 +1873,12 @@ public:
{
m_formatter.oneWordOp8Imm8(OP_NOP_T1, 0);
}
-
+
+ void nopw()
+ {
+ m_formatter.twoWordOp16Op16(OP_NOP_T2a, OP_NOP_T2b);
+ }
+
AssemblerLabel labelIgnoringWatchpoints()
{
return m_formatter.label();
@@ -1878,7 +1898,10 @@ public:
{
AssemblerLabel result = m_formatter.label();
while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
- nop();
+ if (UNLIKELY(static_cast<int>(result.m_offset) + 4 <= m_indexOfTailOfLastWatchpoint))
+ nopw();
+ else
+ nop();
result = m_formatter.label();
}
return result;
@@ -2136,15 +2159,31 @@ public:
{
ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 1));
ASSERT(!(bitwise_cast<uintptr_t>(to) & 1));
+
+#if OS(LINUX) || OS(QNX)
+ if (canBeJumpT4(reinterpret_cast<uint16_t*>(instructionStart), to)) {
+ uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart) + 2;
+ linkJumpT4(ptr, to);
+ cacheFlush(ptr - 2, sizeof(uint16_t) * 2);
+ } else {
+ uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart) + 5;
+ linkBX(ptr, to);
+ cacheFlush(ptr - 5, sizeof(uint16_t) * 5);
+ }
+#else
uint16_t* ptr = reinterpret_cast<uint16_t*>(instructionStart) + 2;
-
linkJumpT4(ptr, to);
cacheFlush(ptr - 2, sizeof(uint16_t) * 2);
+#endif
}
static ptrdiff_t maxJumpReplacementSize()
{
+#if OS(LINUX) || OS(QNX)
+ return 10;
+#else
return 4;
+#endif
}
static void replaceWithLoad(void* instructionStart)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index e6b5ad383..c5ea9c542 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -673,9 +673,8 @@ public:
m_assembler.vmov(dest1, dest2, src);
}
- void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch)
+ void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID)
{
- UNUSED_PARAM(scratch);
m_assembler.vmov(dest, src1, src2);
}
@@ -955,6 +954,7 @@ public:
Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
+ ensureSpace(3 * sizeof(ARMWord), 2 * sizeof(ARMWord));
dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S1);
Jump jump = branch32(cond, left, ARMRegisters::S1, true);
return jump;
@@ -963,6 +963,7 @@ public:
Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
{
load32(left, ARMRegisters::S1);
+ ensureSpace(3 * sizeof(ARMWord), 2 * sizeof(ARMWord));
dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S0);
Jump jump = branch32(cond, ARMRegisters::S0, ARMRegisters::S1, true);
return jump;
@@ -1215,7 +1216,7 @@ public:
// If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits
// (specifically, in this case, 0).
- void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
+ void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
{
m_assembler.vcvt_s32_f64(ARMRegisters::SD0 << 1, src);
m_assembler.vmov_arm32(dest, ARMRegisters::SD0 << 1);
@@ -1285,10 +1286,10 @@ public:
static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID reg, void* initialValue)
{
- ARMAssembler::revertJump(instructionStart.dataLocation(), reg, reinterpret_cast<uintptr_t>(initialValue) & 0xffff);
+ ARMAssembler::revertBranchPtrWithPatch(instructionStart.dataLocation(), reg, reinterpret_cast<uintptr_t>(initialValue) & 0xffff);
}
- static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel instructionStart, Address, void* initialValue)
+ static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel, Address, void*)
{
UNREACHABLE_FOR_PLATFORM();
}
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 8d7a3a69a..06d0e1534 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -1767,9 +1767,14 @@ public:
return label.labelAtOffset(-twoWordOpSize * 2);
}
- static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID, void* initialValue)
+ static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID rd, void* initialValue)
{
+#if OS(LINUX) || OS(QNX)
+ ARMv7Assembler::revertJumpTo_movT3movtcmpT2(instructionStart.dataLocation(), rd, dataTempRegister, reinterpret_cast<uintptr_t>(initialValue));
+#else
+ UNUSED_PARAM(rd);
ARMv7Assembler::revertJumpTo_movT3(instructionStart.dataLocation(), dataTempRegister, ARMThumbImmediate::makeUInt16(reinterpret_cast<uintptr_t>(initialValue) & 0xffff));
+#endif
}
static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr)
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 00209f236..fe9f6ac7c 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -568,7 +568,7 @@ void CodeBlock::dumpBytecode()
dataLogF("\nException Handlers:\n");
unsigned i = 0;
do {
- dataLogF("\t %d: { start: [%4d] end: [%4d] target: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target);
+ dataLogF("\t %d: { start: [%4d] end: [%4d] target: [%4d] depth: [%4d] }\n", i + 1, m_rareData->m_exceptionHandlers[i].start, m_rareData->m_exceptionHandlers[i].end, m_rareData->m_exceptionHandlers[i].target, m_rareData->m_exceptionHandlers[i].scopeDepth);
++i;
} while (i < m_rareData->m_exceptionHandlers.size());
}
@@ -2473,7 +2473,7 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
for (size_t i = 0; i < exceptionHandlers.size(); ++i) {
// Handlers are ordered innermost first, so the first handler we encounter
// that contains the source address is the correct handler to use.
- if (exceptionHandlers[i].start <= bytecodeOffset && exceptionHandlers[i].end >= bytecodeOffset)
+ if (exceptionHandlers[i].start <= bytecodeOffset && exceptionHandlers[i].end > bytecodeOffset)
return &exceptionHandlers[i];
}
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index 35976257b..507241696 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -157,10 +157,38 @@ ParserError BytecodeGenerator::generate()
for (unsigned i = 0; i < m_tryRanges.size(); ++i) {
TryRange& range = m_tryRanges[i];
+ int start = range.start->bind();
+ int end = range.end->bind();
+
+ // This will happen for empty try blocks and for some cases of finally blocks:
+ //
+ // try {
+ // try {
+ // } finally {
+ // return 42;
+ // // *HERE*
+ // }
+ // } finally {
+ // print("things");
+ // }
+ //
+ // The return will pop scopes to execute the outer finally block. But this includes
+ // popping the try context for the inner try. The try context is live in the fall-through
+ // part of the finally block not because we will emit a handler that overlaps the finally,
+ // but because we haven't yet had a chance to plant the catch target. Then when we finish
+ // emitting code for the outer finally block, we repush the try contex, this time with a
+ // new start index. But that means that the start index for the try range corresponding
+ // to the inner-finally-following-the-return (marked as "*HERE*" above) will be greater
+ // than the end index of the try block. This is harmless since end < start handlers will
+ // never get matched in our logic, but we do the runtime a favor and choose to not emit
+ // such handlers at all.
+ if (end <= start)
+ continue;
+
ASSERT(range.tryData->targetScopeDepth != UINT_MAX);
UnlinkedHandlerInfo info = {
- static_cast<uint32_t>(range.start->bind(0, 0)), static_cast<uint32_t>(range.end->bind(0, 0)),
- static_cast<uint32_t>(range.tryData->target->bind(0, 0)),
+ static_cast<uint32_t>(start), static_cast<uint32_t>(end),
+ static_cast<uint32_t>(range.tryData->target->bind()),
range.tryData->targetScopeDepth
};
m_codeBlock->addExceptionHandler(info);
diff --git a/Source/JavaScriptCore/bytecompiler/Label.h b/Source/JavaScriptCore/bytecompiler/Label.h
index 21fa46309..8b444de91 100644
--- a/Source/JavaScriptCore/bytecompiler/Label.h
+++ b/Source/JavaScriptCore/bytecompiler/Label.h
@@ -66,6 +66,12 @@ namespace JSC {
int refCount() const { return m_refCount; }
bool isForward() const { return m_location == invalidLocation; }
+
+ int bind()
+ {
+ ASSERT(!isForward());
+ return bind(0, 0);
+ }
private:
typedef Vector<std::pair<int, int>, 8> JumpVector;
diff --git a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
index d9ae4a274..52cebf80f 100644
--- a/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGCFGSimplificationPhase.cpp
@@ -305,8 +305,6 @@ private:
dataLogF(" Original has local r%d.\n", originalNode->local());
#endif
ASSERT(child.local() == originalNode->local());
- if (changeRef)
- ASSERT(originalNode->shouldGenerate());
// Possibilities:
// SetLocal -> the secondBlock is getting the value of something that is immediately
// available in the first block with a known NodeIndex.
@@ -326,6 +324,8 @@ private:
}
switch (originalNode->op()) {
case SetLocal: {
+ if (changeRef)
+ ASSERT(originalNode->shouldGenerate());
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF(" It's a SetLocal.\n");
#endif
@@ -336,11 +336,16 @@ private:
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF(" It's a GetLocal.\n");
#endif
- m_graph.changeIndex(edge, originalNodeIndex, changeRef);
+ if (originalNode->shouldGenerate())
+ m_graph.changeIndex(edge, originalNodeIndex, changeRef);
+ // If we have a GetLocal that points to a child GetLocal that is dead, then
+ // we have no need to do anything: this original GetLocal is still valid.
break;
}
case Phi:
case SetArgument: {
+ if (changeRef)
+ ASSERT(originalNode->shouldGenerate());
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF(" It's Phi/SetArgument.\n");
#endif
diff --git a/Source/JavaScriptCore/dfg/DFGGraph.h b/Source/JavaScriptCore/dfg/DFGGraph.h
index d91d37394..b39845968 100644
--- a/Source/JavaScriptCore/dfg/DFGGraph.h
+++ b/Source/JavaScriptCore/dfg/DFGGraph.h
@@ -72,6 +72,12 @@ struct PutToBaseOperationData {
unsigned putToBaseOperationIndex;
};
+enum AddSpeculationMode {
+ DontSpeculateInteger,
+ SpeculateIntegerButAlwaysWatchOverflow,
+ SpeculateInteger
+};
+
//
// === Graph ===
@@ -209,7 +215,7 @@ public:
return speculationFromValue(node.valueOfJSConstant(m_codeBlock));
}
- bool addShouldSpeculateInteger(Node& add)
+ AddSpeculationMode addSpeculationMode(Node& add)
{
ASSERT(add.op() == ValueAdd || add.op() == ArithAdd || add.op() == ArithSub);
@@ -221,7 +227,12 @@ public:
if (right.hasConstant())
return addImmediateShouldSpeculateInteger(add, left, right);
- return Node::shouldSpeculateIntegerExpectingDefined(left, right) && add.canSpeculateInteger();
+ return (Node::shouldSpeculateIntegerExpectingDefined(left, right) && add.canSpeculateInteger()) ? SpeculateInteger : DontSpeculateInteger;
+ }
+
+ bool addShouldSpeculateInteger(Node& add)
+ {
+ return addSpeculationMode(add) != DontSpeculateInteger;
}
bool mulShouldSpeculateInteger(Node& mul)
@@ -699,26 +710,26 @@ private:
void handleSuccessor(Vector<BlockIndex, 16>& worklist, BlockIndex blockIndex, BlockIndex successorIndex);
- bool addImmediateShouldSpeculateInteger(Node& add, Node& variable, Node& immediate)
+ AddSpeculationMode addImmediateShouldSpeculateInteger(Node& add, Node& variable, Node& immediate)
{
ASSERT(immediate.hasConstant());
JSValue immediateValue = immediate.valueOfJSConstant(m_codeBlock);
if (!immediateValue.isNumber())
- return false;
+ return DontSpeculateInteger;
if (!variable.shouldSpeculateIntegerExpectingDefined())
- return false;
+ return DontSpeculateInteger;
if (immediateValue.isInt32())
- return add.canSpeculateInteger();
+ return add.canSpeculateInteger() ? SpeculateInteger : DontSpeculateInteger;
double doubleImmediate = immediateValue.asDouble();
const double twoToThe48 = 281474976710656.0;
if (doubleImmediate < -twoToThe48 || doubleImmediate > twoToThe48)
- return false;
+ return DontSpeculateInteger;
- return nodeCanTruncateInteger(add.arithNodeFlags());
+ return nodeCanTruncateInteger(add.arithNodeFlags()) ? SpeculateIntegerButAlwaysWatchOverflow : DontSpeculateInteger;
}
bool mulImmediateShouldSpeculateInteger(Node& mul, Node& variable, Node& immediate)
diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
index 4b8a17285..5b6c28ff7 100644
--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
@@ -285,9 +285,11 @@ private:
SpeculatedType left = m_graph[node.child1()].prediction();
SpeculatedType right = m_graph[node.child2()].prediction();
+ AddSpeculationMode mode = DontSpeculateInteger;
+
if (left && right) {
if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) {
- if (m_graph.addShouldSpeculateInteger(node))
+ if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
@@ -303,6 +305,9 @@ private:
if (m_graph[node.child1()].hasNumberResult() || m_graph[node.child2()].hasNumberResult())
flags &= ~NodeUsedAsOther;
+ if (mode != SpeculateInteger)
+ flags |= NodeUsedAsNumber;
+
changed |= m_graph[node.child1()].mergeFlags(flags);
changed |= m_graph[node.child2()].mergeFlags(flags);
break;
@@ -312,8 +317,10 @@ private:
SpeculatedType left = m_graph[node.child1()].prediction();
SpeculatedType right = m_graph[node.child2()].prediction();
+ AddSpeculationMode mode = DontSpeculateInteger;
+
if (left && right) {
- if (m_graph.addShouldSpeculateInteger(node))
+ if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
@@ -323,6 +330,9 @@ private:
flags &= ~NodeNeedsNegZero;
flags &= ~NodeUsedAsOther;
+ if (mode != SpeculateInteger)
+ flags |= NodeUsedAsNumber;
+
changed |= m_graph[node.child1()].mergeFlags(flags);
changed |= m_graph[node.child2()].mergeFlags(flags);
break;
@@ -332,8 +342,10 @@ private:
SpeculatedType left = m_graph[node.child1()].prediction();
SpeculatedType right = m_graph[node.child2()].prediction();
+ AddSpeculationMode mode = DontSpeculateInteger;
+
if (left && right) {
- if (m_graph.addShouldSpeculateInteger(node))
+ if ((mode = m_graph.addSpeculationMode(node)) != DontSpeculateInteger)
changed |= mergePrediction(SpecInt32);
else
changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
@@ -343,6 +355,9 @@ private:
flags &= ~NodeNeedsNegZero;
flags &= ~NodeUsedAsOther;
+ if (mode != SpeculateInteger)
+ flags |= NodeUsedAsNumber;
+
changed |= m_graph[node.child1()].mergeFlags(flags);
changed |= m_graph[node.child2()].mergeFlags(flags);
break;
@@ -721,6 +736,10 @@ private:
break;
case PutScopedVar:
+ changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
+ changed |= m_graph[node.child3()].mergeFlags(NodeUsedAsValue);
+ break;
+
case Return:
case Throw:
changed |= m_graph[node.child1()].mergeFlags(NodeUsedAsValue);
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index 07a509061..9a7e7df70 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -341,7 +341,7 @@ static bool tryCacheGetByID(ExecState* exec, JSValue baseValue, const Identifier
return false;
PropertyOffset offset = slot.cachedOffset();
- size_t count = normalizePrototypeChain(exec, baseValue, slot.slotBase(), propertyName, offset);
+ size_t count = normalizePrototypeChainForChainAccess(exec, baseValue, slot.slotBase(), propertyName, offset);
if (count == InvalidPrototypeChain)
return false;
@@ -569,7 +569,7 @@ static bool tryBuildGetByIDProtoList(ExecState* exec, JSValue baseValue, const I
ASSERT(slot.slotBase().isObject());
PropertyOffset offset = slot.cachedOffset();
- size_t count = normalizePrototypeChain(exec, baseValue, slot.slotBase(), propertyName, offset);
+ size_t count = normalizePrototypeChainForChainAccess(exec, baseValue, slot.slotBase(), propertyName, offset);
if (count == InvalidPrototypeChain)
return false;
diff --git a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
index 9d6060d60..4ee723d84 100644
--- a/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGStructureCheckHoistingPhase.cpp
@@ -201,7 +201,7 @@ public:
if (!value || !value.isCell()) {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
dataLogF("Zeroing the structure to hoist for %s because the OSR entry value is not a cell: %s.\n",
- m_graph.nameOfVariableAccessData(variable), value.description());
+ m_graph.nameOfVariableAccessData(variable), value);
#endif
iter->value.m_structure = 0;
continue;
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 9b69d1b3d..7d9e6f92e 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -785,9 +785,12 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
JSScope* scope = callFrame->scope();
int scopeDelta = 0;
if (!codeBlock->needsFullScopeChain() || codeBlock->codeType() != FunctionCode
- || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue())
- scopeDelta = depth(codeBlock, scope) - handler->scopeDepth;
- ASSERT(scopeDelta >= 0);
+ || callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) {
+ int currentDepth = depth(codeBlock, scope);
+ int targetDepth = handler->scopeDepth;
+ scopeDelta = currentDepth - targetDepth;
+ ASSERT(scopeDelta >= 0);
+ }
while (scopeDelta--)
scope = scope->next();
callFrame->setScope(scope);
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index f47ac08ef..fbef1fcb9 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -908,6 +908,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
// Uncacheable: give up.
if (!slot.isCacheable()) {
+ stubInfo->accessType = access_get_by_id_generic;
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
return;
}
@@ -916,6 +917,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
Structure* structure = baseCell->structure();
if (structure->isUncacheableDictionary() || structure->typeInfo().prohibitsPropertyCaching()) {
+ stubInfo->accessType = access_get_by_id_generic;
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
return;
}
@@ -934,6 +936,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
}
if (structure->isDictionary()) {
+ stubInfo->accessType = access_get_by_id_generic;
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
return;
}
@@ -943,6 +946,12 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
JSObject* slotBaseObject = asObject(slot.slotBase());
size_t offset = slot.cachedOffset();
+
+ if (structure->typeInfo().hasImpureGetOwnPropertySlot()) {
+ stubInfo->accessType = access_get_by_id_generic;
+ ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
+ return;
+ }
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
@@ -960,9 +969,10 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
}
PropertyOffset offset = slot.cachedOffset();
- size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
+ size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset);
if (count == InvalidPrototypeChain) {
stubInfo->accessType = access_get_by_id_generic;
+ ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
return;
}
@@ -1689,6 +1699,12 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
else if (slot.slotBase() == baseValue.asCell()->structure()->prototypeForLookup(callFrame)) {
ASSERT(!baseValue.asCell()->structure()->isDictionary());
+
+ if (baseValue.asCell()->structure()->typeInfo().hasImpureGetOwnPropertySlot()) {
+ ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
+ return JSValue::encode(result);
+ }
+
// Since we're accessing a prototype in a loop, it's a good bet that it
// should not be treated as a dictionary.
if (slotBaseObject->structure()->isDictionary()) {
@@ -1705,7 +1721,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
}
} else {
- size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
+ size_t count = normalizePrototypeChainForChainAccess(callFrame, baseValue, slot.slotBase(), propertyName, offset);
if (count == InvalidPrototypeChain) {
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
return JSValue::encode(result);
diff --git a/Source/JavaScriptCore/llint/LLIntExceptions.cpp b/Source/JavaScriptCore/llint/LLIntExceptions.cpp
index 5e6bba365..17c15aa51 100644
--- a/Source/JavaScriptCore/llint/LLIntExceptions.cpp
+++ b/Source/JavaScriptCore/llint/LLIntExceptions.cpp
@@ -50,7 +50,7 @@ void interpreterThrowInCaller(ExecState* exec, ReturnAddressPtr pc)
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
#if LLINT_SLOW_PATH_TRACING
- dataLogF("Throwing exception %s.\n", globalData->exception.description());
+ dataLog("Throwing exception ", globalData->exception, ".\n");
#endif
fixupPCforExceptionIfNeeded(exec);
genericThrow(
@@ -69,7 +69,7 @@ Instruction* returnToThrow(ExecState* exec, Instruction* pc)
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
#if LLINT_SLOW_PATH_TRACING
- dataLogF("Throwing exception %s (returnToThrow).\n", globalData->exception.description());
+ dataLog("Throwing exception ", globalData->exception, " (returnToThrow).\n");
#endif
fixupPCforExceptionIfNeeded(exec);
genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
@@ -82,7 +82,7 @@ void* callToThrow(ExecState* exec, Instruction* pc)
JSGlobalData* globalData = &exec->globalData();
NativeCallFrameTracer tracer(globalData, exec);
#if LLINT_SLOW_PATH_TRACING
- dataLogF("Throwing exception %s (callToThrow).\n", globalData->exception.description());
+ dataLog("Throwing exception ", globalData->exception, " (callToThrow).\n");
#endif
fixupPCforExceptionIfNeeded(exec);
genericThrow(globalData, exec, globalData->exception, pc - exec->codeBlock()->instructions().begin());
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 584100e50..0bd19d46f 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -635,8 +635,7 @@ LLINT_SLOW_PATH_DECL(slow_path_add)
JSValue v2 = LLINT_OP_C(3).jsValue();
#if LLINT_SLOW_PATH_TRACING
- dataLogF("Trying to add %s", v1.description());
- dataLogF(" to %s.\n", v2.description());
+ dataLog("Trying to add ", v1, " to ", v2, ".\n");
#endif
if (v1.isString() && !v2.isObject())
@@ -1367,7 +1366,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
}
#if LLINT_SLOW_PATH_TRACING
- dataLogF("Call callee is not a function: %s\n", callee.description());
+ dataLog("Call callee is not a function: ", callee, "\n");
#endif
ASSERT(callType == CallTypeNone);
@@ -1390,7 +1389,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
}
#if LLINT_SLOW_PATH_TRACING
- dataLogF("Constructor callee is not a function: %s\n", callee.description());
+ dataLog("Constructor callee is not a function: ", callee, "\n");
#endif
ASSERT(constructType == ConstructTypeNone);
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
index a9cb393b0..b2ce2483e 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.cpp
@@ -116,6 +116,17 @@ static double Ints2Double(uint32_t lo, uint32_t hi)
u.ival64 = (static_cast<uint64_t>(hi) << 32) | lo;
return u.dval;
}
+
+static void Double2Ints(double val, uint32_t& lo, uint32_t& hi)
+{
+ union {
+ double dval;
+ uint64_t ival64;
+ } u;
+ u.dval = val;
+ hi = static_cast<uint32_t>(u.ival64 >> 32);
+ lo = static_cast<uint32_t>(u.ival64);
+}
#endif // USE(JSVALUE32_64)
} // namespace LLint
diff --git a/Source/JavaScriptCore/offlineasm/ast.rb b/Source/JavaScriptCore/offlineasm/ast.rb
index 9333247dc..4f0c3fd88 100644
--- a/Source/JavaScriptCore/offlineasm/ast.rb
+++ b/Source/JavaScriptCore/offlineasm/ast.rb
@@ -1139,7 +1139,7 @@ class Not < Node
end
def children
- [@left, @right]
+ [@child]
end
def mapChildren
diff --git a/Source/JavaScriptCore/offlineasm/cloop.rb b/Source/JavaScriptCore/offlineasm/cloop.rb
index cbe7e2ca1..8d0838ebd 100644
--- a/Source/JavaScriptCore/offlineasm/cloop.rb
+++ b/Source/JavaScriptCore/offlineasm/cloop.rb
@@ -1025,7 +1025,7 @@ class Instruction
# 32-bit instruction: f2dii dblOp int32LoOp int32HiOp (based on ARMv7)
# Encode a 64-bit double into 2 32-bit ints (low and high).
when "fd2ii"
- $asm.putc "Double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clValue}, #{operands[2].clValue});"
+ $asm.putc "Double2Ints(#{operands[0].clValue(:double)}, #{operands[1].clValue(:uint32)}, #{operands[2].clValue(:uint32)});"
# 64-bit instruction: fq2d int64Op dblOp (based on X64)
# Copy a bit-encoded double in a 64-bit int register to a double register.
diff --git a/Source/JavaScriptCore/runtime/JSTypeInfo.h b/Source/JavaScriptCore/runtime/JSTypeInfo.h
index 6f63260fe..97fc64c1c 100644
--- a/Source/JavaScriptCore/runtime/JSTypeInfo.h
+++ b/Source/JavaScriptCore/runtime/JSTypeInfo.h
@@ -46,6 +46,7 @@ namespace JSC {
static const unsigned OverridesVisitChildren = 1 << 7;
static const unsigned OverridesGetPropertyNames = 1 << 8;
static const unsigned ProhibitsPropertyCaching = 1 << 9;
+ static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
class TypeInfo {
public:
@@ -54,7 +55,6 @@ namespace JSC {
, m_flags(flags & 0xff)
, m_flags2(flags >> 8)
{
- ASSERT(flags <= 0x3ff);
ASSERT(static_cast<int>(type) <= 0xff);
ASSERT(type >= CompoundType || !(flags & OverridesVisitChildren));
// No object that doesn't ImplementsHasInstance should override it!
@@ -80,6 +80,7 @@ namespace JSC {
bool overridesVisitChildren() const { return isSetOnFlags1(OverridesVisitChildren); }
bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
+ bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
static ptrdiff_t flagsOffset()
{
diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h
index 7301bf6ec..8e0a0a393 100644
--- a/Source/JavaScriptCore/runtime/Operations.h
+++ b/Source/JavaScriptCore/runtime/Operations.h
@@ -302,15 +302,18 @@ namespace JSC {
#define InvalidPrototypeChain (std::numeric_limits<size_t>::max())
- inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, PropertyOffset& slotOffset)
+ inline size_t normalizePrototypeChainForChainAccess(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, PropertyOffset& slotOffset)
{
JSCell* cell = base.asCell();
size_t count = 0;
-
+
while (slotBase != cell) {
if (cell->isProxy())
return InvalidPrototypeChain;
+ if (cell->structure()->typeInfo().hasImpureGetOwnPropertySlot())
+ return InvalidPrototypeChain;
+
JSValue v = cell->structure()->prototypeForLookup(callFrame);
// If we didn't find slotBase in base's prototype chain, then base
@@ -328,7 +331,7 @@ namespace JSC {
if (slotBase == cell)
slotOffset = cell->structure()->get(callFrame->globalData(), propertyName);
}
-
+
++count;
}
diff --git a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
index 0578f46b4..be7f1d1aa 100644
--- a/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
+++ b/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
@@ -783,16 +783,23 @@ sub GenerateHeader
$implIncludes{"${className}Custom.h"} = 1 if !$interface->extendedAttributes->{"JSCustomHeader"} && ($interface->extendedAttributes->{"CustomPutFunction"} || $interface->extendedAttributes->{"CustomNamedSetter"});
+ my $hasImpureNamedGetter =
+ $interface->extendedAttributes->{"NamedGetter"}
+ || $interface->extendedAttributes->{"CustomNamedGetter"}
+ || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"};
+
my $hasComplexGetter =
$interface->extendedAttributes->{"IndexedGetter"}
|| $interface->extendedAttributes->{"NumericIndexedGetter"}
- || $interface->extendedAttributes->{"CustomGetOwnPropertySlot"}
|| $interface->extendedAttributes->{"JSCustomGetOwnPropertySlotAndDescriptor"}
- || $interface->extendedAttributes->{"NamedGetter"}
- || $interface->extendedAttributes->{"CustomNamedGetter"};
+ || $hasImpureNamedGetter;
my $hasGetter = $numAttributes > 0 || !$interface->extendedAttributes->{"OmitConstructor"} || $hasComplexGetter;
+ if ($hasImpureNamedGetter) {
+ $structureFlags{"JSC::HasImpureGetOwnPropertySlot"} = 1;
+ }
+
# Getters
if ($hasGetter) {
push(@headerContent, " static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);\n");
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp
index 5716e39d3..7fc354d16 100644
--- a/Source/WebCore/loader/FrameLoader.cpp
+++ b/Source/WebCore/loader/FrameLoader.cpp
@@ -739,6 +739,7 @@ bool FrameLoader::allAncestorsAreComplete() const
void FrameLoader::checkCompleted()
{
+ RefPtr<Frame> protect(m_frame);
m_shouldCallCheckCompleted = false;
if (m_frame->view())
@@ -769,7 +770,6 @@ void FrameLoader::checkCompleted()
m_requestedHistoryItem = 0;
m_frame->document()->setReadyState(Document::Complete);
- RefPtr<Frame> protect(m_frame);
checkCallImplicitClose(); // if we didn't do it before
m_frame->navigationScheduler()->startTimer();
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index 33dc945e9..6c341ddb2 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -263,6 +263,7 @@ void RenderBox::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle
if (viewStyle->writingMode() != newStyle->writingMode() && (isRootRenderer || !document()->writingModeSetOnDocumentElement())) {
viewStyle->setWritingMode(newStyle->writingMode());
viewRenderer->setHorizontalWritingMode(newStyle->isHorizontalWritingMode());
+ viewRenderer->markAllDescendantsWithFloatsForLayout();
if (isBodyRenderer) {
document()->documentElement()->renderer()->style()->setWritingMode(newStyle->writingMode());
document()->documentElement()->renderer()->setHorizontalWritingMode(newStyle->isHorizontalWritingMode());
diff --git a/Source/WebCore/rendering/RenderFrameSet.cpp b/Source/WebCore/rendering/RenderFrameSet.cpp
index 543c2d353..e4e7e24bb 100644
--- a/Source/WebCore/rendering/RenderFrameSet.cpp
+++ b/Source/WebCore/rendering/RenderFrameSet.cpp
@@ -131,14 +131,14 @@ void RenderFrameSet::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
LayoutPoint adjustedPaintOffset = paintOffset + location();
- int rows = frameSet()->totalRows();
- int cols = frameSet()->totalCols();
+ size_t rows = m_rows.m_sizes.size();
+ size_t cols = m_cols.m_sizes.size();
LayoutUnit borderThickness = frameSet()->border();
LayoutUnit yPos = 0;
- for (int r = 0; r < rows; r++) {
+ for (size_t r = 0; r < rows; r++) {
LayoutUnit xPos = 0;
- for (int c = 0; c < cols; c++) {
+ for (size_t c = 0; c < cols; c++) {
child->paint(paintInfo, adjustedPaintOffset);
xPos += m_cols.m_sizes[c];
if (borderThickness && m_cols.m_allowBorder[c + 1]) {
diff --git a/Source/WebKit2/UIProcess/PageViewportController.cpp b/Source/WebKit2/UIProcess/PageViewportController.cpp
index 05ff8b98a..a34782c8f 100644
--- a/Source/WebKit2/UIProcess/PageViewportController.cpp
+++ b/Source/WebKit2/UIProcess/PageViewportController.cpp
@@ -45,7 +45,6 @@ PageViewportController::PageViewportController(WebKit::WebPageProxy* proxy, Page
, m_allowsUserScaling(false)
, m_minimumScaleToFit(1)
, m_initiallyFitToViewport(true)
- , m_hasSuspendedContent(false)
, m_hadUserInteraction(false)
, m_pageScaleFactor(1)
, m_viewportPosIsLocked(false)
@@ -177,7 +176,7 @@ void PageViewportController::pageTransitionViewportReady()
void PageViewportController::pageDidRequestScroll(const IntPoint& cssPosition)
{
// Ignore the request if suspended. Can only happen due to delay in event delivery.
- if (m_hasSuspendedContent)
+ if (m_webPageProxy->areActiveDOMObjectsAndAnimationsSuspended())
return;
FloatRect endVisibleContentRect(clampViewportToContents(cssPosition, m_pageScaleFactor), viewportSizeInContentsCoordinates());
@@ -246,26 +245,6 @@ WebCore::FloatSize PageViewportController::viewportSizeInContentsCoordinates() c
return WebCore::FloatSize(m_viewportSize.width() / m_pageScaleFactor, m_viewportSize.height() / m_pageScaleFactor);
}
-void PageViewportController::suspendContent()
-{
- if (m_hasSuspendedContent)
- return;
-
- m_hasSuspendedContent = true;
- m_webPageProxy->suspendActiveDOMObjectsAndAnimations();
-}
-
-void PageViewportController::resumeContent()
-{
- m_client->didResumeContent();
-
- if (!m_hasSuspendedContent)
- return;
-
- m_hasSuspendedContent = false;
- m_webPageProxy->resumeActiveDOMObjectsAndAnimations();
-}
-
void PageViewportController::applyScaleAfterRenderingContents(float scale)
{
m_pageScaleFactor = scale;
@@ -295,7 +274,7 @@ bool PageViewportController::updateMinimumScaleToFit(bool userInitiatedUpdate)
if (!fuzzyCompare(minimumScale, m_minimumScaleToFit, 0.001)) {
m_minimumScaleToFit = minimumScale;
- if (!hasSuspendedContent()) {
+ if (!m_webPageProxy->areActiveDOMObjectsAndAnimationsSuspended()) {
if (!m_hadUserInteraction || (userInitiatedUpdate && currentlyScaledToFit))
applyScaleAfterRenderingContents(m_minimumScaleToFit);
else {
diff --git a/Source/WebKit2/UIProcess/PageViewportController.h b/Source/WebKit2/UIProcess/PageViewportController.h
index dadbbbefe..fcc4e170d 100644
--- a/Source/WebKit2/UIProcess/PageViewportController.h
+++ b/Source/WebKit2/UIProcess/PageViewportController.h
@@ -22,8 +22,6 @@
#ifndef PageViewportController_h
#define PageViewportController_h
-#if USE(TILED_BACKING_STORE)
-
#include <WebCore/FloatPoint.h>
#include <WebCore/FloatRect.h>
#include <WebCore/FloatSize.h>
@@ -47,14 +45,10 @@ public:
PageViewportController(WebKit::WebPageProxy*, PageViewportControllerClient*);
virtual ~PageViewportController() { }
- void suspendContent();
- void resumeContent();
-
float innerBoundedViewportScale(float) const;
float outerBoundedViewportScale(float) const;
WebCore::FloatPoint clampViewportToContents(const WebCore::FloatPoint& viewportPos, float viewportScale);
- bool hasSuspendedContent() const { return m_hasSuspendedContent; }
bool hadUserInteraction() const { return m_hadUserInteraction; }
bool allowsUserScaling() const { return m_allowsUserScaling; }
@@ -94,7 +88,6 @@ private:
float m_minimumScaleToFit;
bool m_initiallyFitToViewport;
- bool m_hasSuspendedContent;
bool m_hadUserInteraction;
WebCore::FloatPoint m_viewportPos;
@@ -112,6 +105,4 @@ bool fuzzyCompare(float, float, float epsilon);
} // namespace WebKit
-#endif
-
#endif // PageViewportController_h
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h
index ff8ec5133..1b2e9a2b7 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.h
+++ b/Source/WebKit2/UIProcess/WebPageProxy.h
@@ -472,6 +472,7 @@ public:
void setCustomTextEncodingName(const String&);
String customTextEncodingName() const { return m_customTextEncodingName; }
+ bool areActiveDOMObjectsAndAnimationsSuspended() const { return m_isPageSuspended; }
void resumeActiveDOMObjectsAndAnimations();
void suspendActiveDOMObjectsAndAnimations();
diff --git a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp
index c0eb16ab9..61f2aaf57 100644
--- a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp
+++ b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.cpp
@@ -23,12 +23,14 @@
#include "config.h"
#include "PageViewportControllerClientQt.h"
+#include "WebPageProxy.h"
#include "qquickwebpage_p.h"
#include "qquickwebview_p.h"
#include "qwebkittest_p.h"
#include <QPointF>
#include <QTransform>
#include <QtQuick/qquickitem.h>
+#include <WKAPICast.h>
#include <WebCore/FloatRect.h>
#include <WebCore/FloatSize.h>
@@ -41,12 +43,14 @@ static const int kScaleAnimationDurationMillis = 250;
PageViewportControllerClientQt::PageViewportControllerClientQt(QQuickWebView* viewportItem, QQuickWebPage* pageItem)
: m_viewportItem(viewportItem)
, m_pageItem(pageItem)
+ , m_scaleChange(this)
+ , m_scrollChange(this)
+ , m_touchInteraction(this, false /* shouldSuspend */)
, m_scaleAnimation(new ScaleAnimation(this))
+ , m_activeInteractionCount(0)
, m_pinchStartScale(-1)
, m_lastCommittedScale(-1)
, m_zoomOutScale(0)
- , m_isUserInteracting(false)
- , m_ignoreViewportChanges(false)
{
m_scaleAnimation->setDuration(kScaleAnimationDurationMillis);
m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic);
@@ -76,6 +80,32 @@ void PageViewportControllerClientQt::ScaleAnimation::updateCurrentValue(const QV
m_controllerClient->setContentRectVisiblePositionAtScale(itemRect.topLeft(), itemScale);
}
+void PageViewportControllerClientQt::ViewportInteractionTracker::begin()
+{
+ if (m_inProgress)
+ return;
+
+ m_inProgress = true;
+
+ if (m_shouldSuspend)
+ toImpl(m_controllerClient->m_viewportItem->pageRef())->suspendActiveDOMObjectsAndAnimations();
+
+ ++(m_controllerClient->m_activeInteractionCount);
+}
+
+void PageViewportControllerClientQt::ViewportInteractionTracker::end()
+{
+ if (!m_inProgress)
+ return;
+
+ m_inProgress = false;
+
+ ASSERT(m_controllerClient->m_activeInteractionCount > 0);
+
+ if (!(--(m_controllerClient->m_activeInteractionCount)))
+ toImpl(m_controllerClient->m_viewportItem->pageRef())->resumeActiveDOMObjectsAndAnimations();
+}
+
PageViewportControllerClientQt::~PageViewportControllerClientQt()
{
}
@@ -103,7 +133,8 @@ void PageViewportControllerClientQt::animateContentRectVisible(const QRectF& con
QRectF viewportRectInContentCoords = m_viewportItem->mapRectToWebContent(m_viewportItem->boundingRect());
if (contentRect == viewportRectInContentCoords) {
- m_controller->resumeContent();
+ m_scaleChange.end();
+ updateViewportController();
return;
}
@@ -121,22 +152,20 @@ void PageViewportControllerClientQt::animateContentRectVisible(const QRectF& con
void PageViewportControllerClientQt::flickMoveStarted()
{
- m_controller->suspendContent();
-
+ m_scrollChange.begin();
m_lastScrollPosition = m_viewportItem->contentPos();
}
void PageViewportControllerClientQt::flickMoveEnded()
{
// This method is called on the end of the pan or pan kinetic animation.
-
- if (!m_isUserInteracting)
- m_controller->resumeContent();
+ m_scrollChange.end();
+ updateViewportController();
}
void PageViewportControllerClientQt::pageItemPositionChanged()
{
- if (m_ignoreViewportChanges)
+ if (m_scaleChange.inProgress())
return;
QPointF newPosition = m_viewportItem->contentPos();
@@ -150,13 +179,11 @@ void PageViewportControllerClientQt::scaleAnimationStateChanged(QAbstractAnimati
{
switch (newState) {
case QAbstractAnimation::Running:
- m_ignoreViewportChanges = true;
- m_viewportItem->cancelFlick();
- m_controller->suspendContent();
+ m_scaleChange.begin();
break;
case QAbstractAnimation::Stopped:
- m_ignoreViewportChanges = false;
- m_controller->resumeContent();
+ m_scaleChange.end();
+ updateViewportController();
break;
default:
break;
@@ -167,13 +194,14 @@ void PageViewportControllerClientQt::touchBegin()
{
m_controller->setHadUserInteraction(true);
- // Prevents resuming the page between the user's flicks of the page.
- m_isUserInteracting = true;
+ // Prevent resuming the page during transition between gestures while the user is interacting.
+ // The content is suspended as soon as a pan or pinch gesture or an animation is started.
+ m_touchInteraction.begin();
}
void PageViewportControllerClientQt::touchEnd()
{
- m_isUserInteracting = false;
+ m_touchInteraction.end();
}
void PageViewportControllerClientQt::focusEditableArea(const QRectF& caretArea, const QRectF& targetArea)
@@ -217,7 +245,7 @@ void PageViewportControllerClientQt::zoomToAreaGestureEnded(const QPointF& touch
if (!targetArea.isValid())
return;
- if (m_controller->hasSuspendedContent())
+ if (m_scrollChange.inProgress() || m_scaleChange.inProgress())
return;
const float margin = 10; // We want at least a little bit of margin.
@@ -425,9 +453,7 @@ void PageViewportControllerClientQt::pinchGestureStarted(const QPointF& pinchCen
return;
clearRelativeZoomState();
-
- m_ignoreViewportChanges = true;
- m_controller->suspendContent();
+ m_scaleChange.begin();
m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates;
m_pinchStartScale = m_pageItem->contentsScale();
@@ -435,11 +461,12 @@ void PageViewportControllerClientQt::pinchGestureStarted(const QPointF& pinchCen
void PageViewportControllerClientQt::pinchGestureRequestUpdate(const QPointF& pinchCenterInViewportCoordinates, qreal totalScaleFactor)
{
- ASSERT(m_controller->hasSuspendedContent());
+ ASSERT(m_scaleChange.inProgress());
if (!m_controller->allowsUserScaling())
return;
+ ASSERT(m_pinchStartScale > 0);
// Changes of the center position should move the page even if the zoom factor does not change.
const qreal pinchScale = m_pinchStartScale * totalScaleFactor;
@@ -456,12 +483,11 @@ void PageViewportControllerClientQt::pinchGestureRequestUpdate(const QPointF& pi
void PageViewportControllerClientQt::pinchGestureEnded()
{
- ASSERT(m_controller->hasSuspendedContent());
+ ASSERT(m_scaleChange.inProgress());
if (!m_controller->allowsUserScaling())
return;
- m_ignoreViewportChanges = false;
m_pinchStartScale = -1;
// This will take care of resuming the content, even if no animation was performed.
@@ -471,7 +497,8 @@ void PageViewportControllerClientQt::pinchGestureEnded()
void PageViewportControllerClientQt::pinchGestureCancelled()
{
m_pinchStartScale = -1;
- m_controller->resumeContent();
+ m_scaleChange.end();
+ updateViewportController();
}
void PageViewportControllerClientQt::didChangeContentsSize(const IntSize& newSize)
@@ -482,7 +509,7 @@ void PageViewportControllerClientQt::didChangeContentsSize(const IntSize& newSiz
// we didn't do scale adjustment.
emit m_viewportItem->experimental()->test()->contentsScaleCommitted();
- if (!m_controller->hasSuspendedContent())
+ if (!m_scaleChange.inProgress() && !m_scrollChange.inProgress())
setContentsRectToNearestValidBounds();
}
diff --git a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h
index 687f29193..22c4c3d3c 100644
--- a/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h
+++ b/Source/WebKit2/UIProcess/qt/PageViewportControllerClientQt.h
@@ -103,6 +103,24 @@ private:
virtual void updateCurrentValue(const QVariant&);
};
+ class ViewportInteractionTracker {
+ public:
+ ViewportInteractionTracker(PageViewportControllerClientQt* client, bool shouldSuspend = true)
+ : m_controllerClient(client)
+ , m_shouldSuspend(shouldSuspend)
+ , m_inProgress(false)
+ { }
+
+ void begin();
+ void end();
+ bool inProgress() const { return m_inProgress; }
+
+ private:
+ PageViewportControllerClientQt* m_controllerClient;
+ bool m_shouldSuspend;
+ bool m_inProgress;
+ };
+
struct ScaleStackItem {
ScaleStackItem(qreal scale, qreal xPosition)
: scale(scale)
@@ -113,6 +131,7 @@ private:
qreal xPosition;
};
+ friend class ViewportInteractionTracker;
friend class ScaleAnimation;
friend class ::QWebKitTest;
@@ -130,15 +149,18 @@ private:
void scaleContent(qreal itemScale, const QPointF& centerInCSSCoordinates = QPointF());
void clearRelativeZoomState();
+ ViewportInteractionTracker m_scaleChange;
+ ViewportInteractionTracker m_scrollChange;
+ ViewportInteractionTracker m_touchInteraction;
+
ScaleAnimation* m_scaleAnimation;
QPointF m_lastPinchCenterInViewportCoordinates;
QPointF m_lastScrollPosition;
+ int m_activeInteractionCount;
qreal m_pinchStartScale;
qreal m_lastCommittedScale;
qreal m_zoomOutScale;
QList<ScaleStackItem> m_scaleStack;
- bool m_isUserInteracting;
- bool m_ignoreViewportChanges;
};
} // namespace WebKit
diff --git a/Tools/MiniBrowser/qt/raw/View.cpp b/Tools/MiniBrowser/qt/raw/View.cpp
index 8e04fd00b..4c4d52855 100644
--- a/Tools/MiniBrowser/qt/raw/View.cpp
+++ b/Tools/MiniBrowser/qt/raw/View.cpp
@@ -62,7 +62,7 @@ View::View(const QString& url)
{
setSurfaceType(OpenGLSurface);
setGeometry(50, 50, 980, 600);
- setWindowFlags(Qt::Window | Qt::WindowTitleHint);
+ setFlags(Qt::Window | Qt::WindowTitleHint);
create();
m_context = new QOpenGLContext;