summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/JavaScriptCore.pri2
-rw-r--r--Source/JavaScriptCore/LLIntOffsetsExtractor.pro6
-rw-r--r--Source/JavaScriptCore/Target.pri2
-rw-r--r--Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp17
-rw-r--r--Source/JavaScriptCore/dfg/DFGFixupPhase.cpp14
-rw-r--r--Source/JavaScriptCore/dfg/DFGRepatch.cpp4
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp7
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.cpp12
-rw-r--r--Source/JavaScriptCore/heap/MarkStack.h16
-rw-r--r--Source/JavaScriptCore/heap/MarkStackInlines.h10
-rw-r--r--Source/JavaScriptCore/heap/WeakSet.cpp2
-rw-r--r--Source/JavaScriptCore/jit/JIT.h2
-rw-r--r--Source/JavaScriptCore/jit/JITStubs.cpp71
-rw-r--r--Source/JavaScriptCore/runtime/Executable.cpp4
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.cpp24
-rw-r--r--Source/JavaScriptCore/runtime/JSArray.h4
-rw-r--r--Source/JavaScriptCore/runtime/JSObject.h1
-rw-r--r--Source/JavaScriptCore/runtime/Options.h1
-rw-r--r--Source/JavaScriptCore/yarr/YarrJIT.cpp12
19 files changed, 154 insertions, 57 deletions
diff --git a/Source/JavaScriptCore/JavaScriptCore.pri b/Source/JavaScriptCore/JavaScriptCore.pri
index 859f4a20d..629a4838c 100644
--- a/Source/JavaScriptCore/JavaScriptCore.pri
+++ b/Source/JavaScriptCore/JavaScriptCore.pri
@@ -33,7 +33,7 @@ INCLUDEPATH += \
$$JAVASCRIPTCORE_GENERATED_SOURCES_DIR
# Pick up the right version of LLIntAssembly.h
-macx:INCLUDEPATH+=$$JAVASCRIPTCORE_GENERATED_SOURCES_DIR/$$activeBuildConfig()
+macx:INCLUDEPATH+=$$JAVASCRIPTCORE_GENERATED_SOURCES_DIR/$$targetSubDir()
win32-*: LIBS += -lwinmm
diff --git a/Source/JavaScriptCore/LLIntOffsetsExtractor.pro b/Source/JavaScriptCore/LLIntOffsetsExtractor.pro
index 97b3529b7..d119bbf08 100644
--- a/Source/JavaScriptCore/LLIntOffsetsExtractor.pro
+++ b/Source/JavaScriptCore/LLIntOffsetsExtractor.pro
@@ -58,9 +58,9 @@ llint.CONFIG += no_link
QMAKE_EXTRA_COMPILERS += llint
macx {
- DESTDIR = $$activeBuildConfig()
- llint.output = $$activeBuildConfig()/$$llint.output
- INCLUDEPATH += $$activeBuildConfig()
+ DESTDIR = $$targetSubDir()
+ llint.output = $$targetSubDir()/$$llint.output
+ INCLUDEPATH += $$targetSubDir()
}
# Compilation of this file will automatically depend on LLIntDesiredOffsets.h
diff --git a/Source/JavaScriptCore/Target.pri b/Source/JavaScriptCore/Target.pri
index e1da901c1..0f2659ec9 100644
--- a/Source/JavaScriptCore/Target.pri
+++ b/Source/JavaScriptCore/Target.pri
@@ -30,7 +30,7 @@ include(yarr/yarr.pri)
INSTALLDEPS += all
-debug_and_release: INCLUDEPATH += $$JAVASCRIPTCORE_GENERATED_SOURCES_DIR/$$activeBuildConfig()
+debug_and_release: INCLUDEPATH += $$JAVASCRIPTCORE_GENERATED_SOURCES_DIR/$$targetSubDir()
SOURCES += \
API/JSBase.cpp \
diff --git a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
index b02e0112c..35c553cf8 100644
--- a/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGArgumentsSimplificationPhase.cpp
@@ -621,26 +621,27 @@ public:
continue;
for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
NodeIndex nodeIndex = block->at(indexInBlock);
- Node& node = m_graph[nodeIndex];
- if (node.op() != CreateArguments)
+ Node* nodePtr = &m_graph[nodeIndex];
+ if (nodePtr->op() != CreateArguments)
continue;
// If this is a CreateArguments for an InlineCallFrame* that does
// not create arguments, then replace it with a PhantomArguments.
// PhantomArguments is a non-executing node that just indicates
// that the node should be reified as an arguments object on OSR
// exit.
- if (m_createsArguments.contains(node.codeOrigin.inlineCallFrame))
+ if (m_createsArguments.contains(nodePtr->codeOrigin.inlineCallFrame))
continue;
- if (node.shouldGenerate()) {
- Node phantom(Phantom, node.codeOrigin);
- phantom.children = node.children;
+ if (nodePtr->shouldGenerate()) {
+ Node phantom(Phantom, nodePtr->codeOrigin);
+ phantom.children = nodePtr->children;
phantom.ref();
NodeIndex phantomNodeIndex = m_graph.size();
m_graph.append(phantom);
insertionSet.append(indexInBlock, phantomNodeIndex);
+ nodePtr = &m_graph[nodeIndex];
}
- node.setOpAndDefaultFlags(PhantomArguments);
- node.children.reset();
+ nodePtr->setOpAndDefaultFlags(PhantomArguments);
+ nodePtr->children.reset();
changed = true;
}
insertionSet.execute(*block);
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 1ba40def3..b98d824f5 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -317,8 +317,8 @@ private:
&& node.canSpeculateInteger()) {
if (isX86())
break;
- fixDoubleEdge(0);
- fixDoubleEdge(1);
+ injectInt32ToDoubleNode(0);
+ injectInt32ToDoubleNode(1);
Node& oldDivision = m_graph[m_compileIndex];
@@ -540,11 +540,19 @@ private:
Node& source = m_graph[m_compileIndex];
Edge& edge = m_graph.child(source, childIndex);
- if (!m_graph[edge].shouldSpeculateInteger()) {
+ if (m_graph[edge].prediction() & SpecDouble) {
edge.setUseKind(DoubleUse);
return;
}
+ injectInt32ToDoubleNode(childIndex);
+ }
+
+ void injectInt32ToDoubleNode(unsigned childIndex)
+ {
+ Node& source = m_graph[m_compileIndex];
+ Edge& edge = m_graph.child(source, childIndex);
+
NodeIndex resultIndex = (NodeIndex)m_graph.size();
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
diff --git a/Source/JavaScriptCore/dfg/DFGRepatch.cpp b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
index 9a7e7df70..bba3a5b43 100644
--- a/Source/JavaScriptCore/dfg/DFGRepatch.cpp
+++ b/Source/JavaScriptCore/dfg/DFGRepatch.cpp
@@ -1214,12 +1214,12 @@ void dfgLinkClosureCall(ExecState* exec, CallLinkInfo& callLinkInfo, CodeBlock*
JITCompiler::Jump done = stubJit.jump();
slowPath.link(&stubJit);
- stubJit.move(CCallHelpers::TrustedImmPtr(callLinkInfo.callReturnLocation.executableAddress()), GPRInfo::nonArgGPR2);
- stubJit.restoreReturnAddressBeforeReturn(GPRInfo::nonArgGPR2);
stubJit.move(calleeGPR, GPRInfo::nonArgGPR0);
#if USE(JSVALUE32_64)
stubJit.move(CCallHelpers::TrustedImm32(JSValue::CellTag), GPRInfo::nonArgGPR1);
#endif
+ stubJit.move(CCallHelpers::TrustedImmPtr(callLinkInfo.callReturnLocation.executableAddress()), GPRInfo::nonArgGPR2);
+ stubJit.restoreReturnAddressBeforeReturn(GPRInfo::nonArgGPR2);
JITCompiler::Jump slow = stubJit.jump();
LinkBuffer patchBuffer(*globalData, &stubJit, callerCodeBlock);
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index d7f7b2fab..4f2889b8f 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -2250,8 +2250,7 @@ void SpeculativeJIT::compileInt32ToDouble(Node& node)
// than a int->double conversion. On 32_64, unfortunately, we currently don't have
// any such mechanism - though we could have it, if we just provisioned some memory
// in CodeBlock for the double form of integer constants.
- if (at(node.child1()).hasConstant()) {
- ASSERT(isInt32Constant(node.child1().index()));
+ if (isInt32Constant(node.child1().index())) {
FPRTemporary result(this);
GPRTemporary temp(this);
m_jit.move(MacroAssembler::Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(node.child1().index()))), temp.gpr());
@@ -3097,11 +3096,11 @@ void SpeculativeJIT::compileIntegerArithDivForX86(Node& node)
speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
} else {
JITCompiler::Jump zero = m_jit.branchTest32(JITCompiler::Zero, op2GPR);
- JITCompiler::Jump notNeg2ToThe31 = m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1));
+ JITCompiler::Jump isNeg2ToThe31 = m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1));
zero.link(&m_jit);
m_jit.move(TrustedImm32(0), eax.gpr());
+ isNeg2ToThe31.link(&m_jit);
done = m_jit.jump();
- notNeg2ToThe31.link(&m_jit);
}
safeDenominator.link(&m_jit);
diff --git a/Source/JavaScriptCore/heap/MarkStack.cpp b/Source/JavaScriptCore/heap/MarkStack.cpp
index 755a0ad50..39907c715 100644
--- a/Source/JavaScriptCore/heap/MarkStack.cpp
+++ b/Source/JavaScriptCore/heap/MarkStack.cpp
@@ -31,7 +31,6 @@
#include "CopiedSpace.h"
#include "CopiedSpaceInlines.h"
#include "Heap.h"
-#include "Options.h"
#include "JSArray.h"
#include "JSCell.h"
#include "JSObject.h"
@@ -45,13 +44,13 @@
namespace JSC {
+COMPILE_ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize, blockSizeMatch);
+
MarkStackArray::MarkStackArray(BlockAllocator& blockAllocator)
: m_blockAllocator(blockAllocator)
- , m_segmentCapacity(MarkStackSegment::capacityFromSize(Options::gcMarkStackSegmentSize()))
, m_top(0)
, m_numberOfSegments(0)
{
- ASSERT(MarkStackSegment::blockSize == WeakBlock::blockSize);
m_segments.push(MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>()));
m_numberOfSegments++;
}
@@ -64,7 +63,7 @@ MarkStackArray::~MarkStackArray()
void MarkStackArray::expand()
{
- ASSERT(m_segments.head()->m_top == m_segmentCapacity);
+ ASSERT(m_segments.head()->m_top == s_segmentCapacity);
MarkStackSegment* nextSegment = MarkStackSegment::create(m_blockAllocator.allocate<MarkStackSegment>());
m_numberOfSegments++;
@@ -97,8 +96,6 @@ void MarkStackArray::donateSomeCellsTo(MarkStackArray& other)
// we prefer donating whole segments over donating individual cells,
// even if this skews away from our 1 / 2 target.
- ASSERT(m_segmentCapacity == other.m_segmentCapacity);
-
size_t segmentsToDonate = m_numberOfSegments / 2; // If we only have one segment (our head) we don't donate any segments.
if (!segmentsToDonate) {
@@ -141,7 +138,6 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
// To reduce copying costs, we prefer stealing a whole segment over stealing
// individual cells, even if this skews away from our 1 / N target.
- ASSERT(m_segmentCapacity == other.m_segmentCapacity);
validatePrevious();
other.validatePrevious();
@@ -151,7 +147,7 @@ void MarkStackArray::stealSomeCellsFrom(MarkStackArray& other, size_t idleThread
MarkStackSegment* otherHead = other.m_segments.removeHead();
MarkStackSegment* myHead = m_segments.removeHead();
- ASSERT(other.m_segments.head()->m_top == m_segmentCapacity);
+ ASSERT(other.m_segments.head()->m_top == s_segmentCapacity);
m_segments.push(other.m_segments.removeHead());
diff --git a/Source/JavaScriptCore/heap/MarkStack.h b/Source/JavaScriptCore/heap/MarkStack.h
index 2a7f04450..c97b6a735 100644
--- a/Source/JavaScriptCore/heap/MarkStack.h
+++ b/Source/JavaScriptCore/heap/MarkStack.h
@@ -75,16 +75,6 @@ public:
{
return bitwise_cast<const JSCell**>(this + 1);
}
-
- static size_t capacityFromSize(size_t size)
- {
- return (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*);
- }
-
- static size_t sizeFromCapacity(size_t capacity)
- {
- return sizeof(MarkStackSegment) + capacity * sizeof(const JSCell*);
- }
static const size_t blockSize = 4 * KB;
@@ -111,6 +101,10 @@ public:
bool isEmpty();
private:
+ template <size_t size> struct CapacityFromSize {
+ static const size_t value = (size - sizeof(MarkStackSegment)) / sizeof(const JSCell*);
+ };
+
JS_EXPORT_PRIVATE void expand();
size_t postIncTop();
@@ -124,7 +118,7 @@ private:
DoublyLinkedList<MarkStackSegment> m_segments;
BlockAllocator& m_blockAllocator;
- size_t m_segmentCapacity;
+ JS_EXPORT_PRIVATE static const size_t s_segmentCapacity = CapacityFromSize<MarkStackSegment::blockSize>::value;
size_t m_top;
size_t m_numberOfSegments;
diff --git a/Source/JavaScriptCore/heap/MarkStackInlines.h b/Source/JavaScriptCore/heap/MarkStackInlines.h
index 1595e843e..c577de602 100644
--- a/Source/JavaScriptCore/heap/MarkStackInlines.h
+++ b/Source/JavaScriptCore/heap/MarkStackInlines.h
@@ -52,8 +52,8 @@ inline size_t MarkStackArray::preDecTop()
inline void MarkStackArray::setTopForFullSegment()
{
- ASSERT(m_segments.head()->m_top == m_segmentCapacity);
- m_top = m_segmentCapacity;
+ ASSERT(m_segments.head()->m_top == s_segmentCapacity);
+ m_top = s_segmentCapacity;
}
inline void MarkStackArray::setTopForEmptySegment()
@@ -82,7 +82,7 @@ inline void MarkStackArray::validatePrevious()
inline void MarkStackArray::append(const JSCell* cell)
{
- if (m_top == m_segmentCapacity)
+ if (m_top == s_segmentCapacity)
expand();
m_segments.head()->data()[postIncTop()] = cell;
}
@@ -102,7 +102,7 @@ inline bool MarkStackArray::isEmpty()
if (m_top)
return false;
if (m_segments.head()->next()) {
- ASSERT(m_segments.head()->next()->m_top == m_segmentCapacity);
+ ASSERT(m_segments.head()->next()->m_top == s_segmentCapacity);
return false;
}
return true;
@@ -110,7 +110,7 @@ inline bool MarkStackArray::isEmpty()
inline size_t MarkStackArray::size()
{
- return m_top + m_segmentCapacity * (m_numberOfSegments - 1);
+ return m_top + s_segmentCapacity * (m_numberOfSegments - 1);
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/heap/WeakSet.cpp b/Source/JavaScriptCore/heap/WeakSet.cpp
index 67b1d0613..7cedaee85 100644
--- a/Source/JavaScriptCore/heap/WeakSet.cpp
+++ b/Source/JavaScriptCore/heap/WeakSet.cpp
@@ -84,7 +84,7 @@ WeakBlock::FreeCell* WeakSet::addAllocator()
void WeakSet::removeAllocator(WeakBlock* block)
{
m_blocks.remove(block);
- WeakBlock::destroy(block);
+ heap()->blockAllocator().deallocate(WeakBlock::destroy(block));
}
} // namespace JSC
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index c0d60add1..bbbc3b1c7 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -555,7 +555,7 @@ namespace JSC {
static const int sequenceGetByIdHotPathInstructionSpace = 36;
static const int sequenceGetByIdHotPathConstantSpace = 4;
// sequenceGetByIdSlowCase
- static const int sequenceGetByIdSlowCaseInstructionSpace = 64;
+ static const int sequenceGetByIdSlowCaseInstructionSpace = 80;
static const int sequenceGetByIdSlowCaseConstantSpace = 4;
// sequencePutById
static const int sequencePutByIdInstructionSpace = 36;
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index eca0fb079..64acfeef5 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -364,7 +364,7 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#else // USE(JSVALUE32_64)
-#if COMPILER(GCC) && CPU(X86_64)
+#if COMPILER(GCC) && CPU(X86_64) && !OS(WINDOWS)
// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
// need to change the assembly trampolines below to match.
@@ -433,6 +433,75 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"ret" "\n"
);
+#elif COMPILER(GCC) && CPU(X86_64) && OS(WINDOWS)
+
+// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
+// need to change the assembly trampolines below to match.
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x58, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
+
+asm (
+".text\n"
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+ // Dump register parameters to their home address
+ "movq %r9, 0x20(%rsp)" "\n"
+ "movq %r8, 0x18(%rsp)" "\n"
+ "movq %rdx, 0x10(%rsp)" "\n"
+ "movq %rcx, 0x8(%rsp)" "\n"
+
+ "pushq %rbp" "\n"
+ "movq %rsp, %rbp" "\n"
+ "pushq %r12" "\n"
+ "pushq %r13" "\n"
+ "pushq %r14" "\n"
+ "pushq %r15" "\n"
+ "pushq %rbx" "\n"
+
+ // Decrease rsp to point to the start of our JITStackFrame
+ "subq $0x58, %rsp" "\n"
+ "movq $512, %r12" "\n"
+ "movq $0xFFFF000000000000, %r14" "\n"
+ "movq $0xFFFF000000000002, %r15" "\n"
+ "movq %r8, %r13" "\n"
+ "call *%rcx" "\n"
+ "addq $0x58, %rsp" "\n"
+ "popq %rbx" "\n"
+ "popq %r15" "\n"
+ "popq %r14" "\n"
+ "popq %r13" "\n"
+ "popq %r12" "\n"
+ "popq %rbp" "\n"
+ "ret" "\n"
+".globl " SYMBOL_STRING(ctiTrampolineEnd) "\n"
+HIDE_SYMBOL(ctiTrampolineEnd) "\n"
+SYMBOL_STRING(ctiTrampolineEnd) ":" "\n"
+);
+
+asm (
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+ "movq %rsp, %rcx" "\n"
+ "call " LOCAL_REFERENCE(cti_vm_throw) "\n"
+ "int3" "\n"
+);
+
+asm (
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+ "addq $0x58, %rsp" "\n"
+ "popq %rbx" "\n"
+ "popq %r15" "\n"
+ "popq %r14" "\n"
+ "popq %r13" "\n"
+ "popq %r12" "\n"
+ "popq %rbp" "\n"
+ "ret" "\n"
+);
+
#elif COMPILER(MSVC) && CPU(X86_64)
// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 746e281e3..ff4c2ff76 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -522,7 +522,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* s
UNUSED_PARAM(bytecodeIndex);
#endif
ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall);
- JSObject* exception;
+ JSObject* exception = 0;
OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForCall, exception);
if (!newCodeBlock)
return exception;
@@ -558,7 +558,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSSco
#endif
ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct);
- JSObject* exception;
+ JSObject* exception = 0;
OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, CodeForConstruct, exception);
if (!newCodeBlock)
return exception;
diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp
index 4ba5cc2bd..c742804f7 100644
--- a/Source/JavaScriptCore/runtime/JSArray.cpp
+++ b/Source/JavaScriptCore/runtime/JSArray.cpp
@@ -1347,7 +1347,7 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
// Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
for (; numDefined < usedVectorLength; ++numDefined) {
- if (numDefined > m_butterfly->vectorLength())
+ if (numDefined >= m_butterfly->vectorLength())
break;
JSValue v = getHolyIndexQuickly(numDefined);
if (!v || v.isUndefined())
@@ -1356,7 +1356,7 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
tree.insert(numDefined);
}
for (unsigned i = numDefined; i < usedVectorLength; ++i) {
- if (i > m_butterfly->vectorLength())
+ if (i >= m_butterfly->vectorLength())
break;
JSValue v = getHolyIndexQuickly(i);
if (v) {
@@ -1384,6 +1384,7 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
iter.start_iter_least(tree);
JSGlobalData& globalData = exec->globalData();
for (unsigned i = 0; i < elementsToExtractThreshold; ++i) {
+ ASSERT(i < butterfly()->vectorLength());
if (structure()->indexingType() == ArrayWithDouble)
butterfly()->contiguousDouble()[i] = tree.abstractor().m_nodes[*iter].value.asNumber();
else
@@ -1398,12 +1399,15 @@ void JSArray::sortVector(ExecState* exec, JSValue compareFunction, CallType call
break;
default:
- for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i)
+ for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i) {
+ ASSERT(i < butterfly()->vectorLength());
currentIndexingData()[i].setUndefined();
+ }
}
// Ensure that unused values in the vector are zeroed out.
for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i) {
+ ASSERT(i < butterfly()->vectorLength());
if (structure()->indexingType() == ArrayWithDouble)
butterfly()->contiguousDouble()[i] = QNaN;
else
@@ -1533,6 +1537,7 @@ void JSArray::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t le
vector = 0;
vectorEnd = 0;
for (; i < m_butterfly->publicLength(); ++i) {
+ ASSERT(i < butterfly()->vectorLength());
double v = m_butterfly->contiguousDouble()[i];
if (v != v)
break;
@@ -1578,6 +1583,7 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
unsigned numUndefined = 0;
for (; numDefined < myRelevantLength; ++numDefined) {
+ ASSERT(numDefined < m_butterfly->vectorLength());
if (indexingType == ArrayWithInt32) {
JSValue v = m_butterfly->contiguousInt32()[numDefined].get();
if (!v)
@@ -1597,11 +1603,13 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
}
for (unsigned i = numDefined; i < myRelevantLength; ++i) {
+ ASSERT(i < m_butterfly->vectorLength());
if (indexingType == ArrayWithInt32) {
JSValue v = m_butterfly->contiguousInt32()[i].get();
if (!v)
continue;
ASSERT(v.isInt32());
+ ASSERT(numDefined < m_butterfly->vectorLength());
m_butterfly->contiguousInt32()[numDefined++].setWithoutWriteBarrier(v);
continue;
}
@@ -1609,6 +1617,7 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
double v = m_butterfly->contiguousDouble()[i];
if (v != v)
continue;
+ ASSERT(numDefined < m_butterfly->vectorLength());
m_butterfly->contiguousDouble()[numDefined++] = v;
continue;
}
@@ -1616,8 +1625,10 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
if (v) {
if (v.isUndefined())
++numUndefined;
- else
+ else {
+ ASSERT(numDefined < m_butterfly->vectorLength());
indexingData<indexingType>()[numDefined++].setWithoutWriteBarrier(v);
+ }
}
}
@@ -1633,11 +1644,14 @@ void JSArray::compactForSorting(unsigned& numDefined, unsigned& newRelevantLengt
break;
default:
- for (unsigned i = numDefined; i < newRelevantLength; ++i)
+ for (unsigned i = numDefined; i < newRelevantLength; ++i) {
+ ASSERT(i < m_butterfly->vectorLength());
indexingData<indexingType>()[i].setUndefined();
+ }
break;
}
for (unsigned i = newRelevantLength; i < myRelevantLength; ++i) {
+ ASSERT(i < m_butterfly->vectorLength());
if (indexingType == ArrayWithDouble)
m_butterfly->contiguousDouble()[i] = QNaN;
else
diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h
index ea1ed9047..cef3b53ad 100644
--- a/Source/JavaScriptCore/runtime/JSArray.h
+++ b/Source/JavaScriptCore/runtime/JSArray.h
@@ -245,6 +245,10 @@ inline JSArray* JSArray::tryCreateUninitialized(JSGlobalData& globalData, Struct
butterfly = Butterfly::fromBase(temp, 0, 0);
butterfly->setVectorLength(vectorLength);
butterfly->setPublicLength(initialLength);
+ if (hasDouble(structure->indexingType())) {
+ for (unsigned i = initialLength; i < vectorLength; ++i)
+ butterfly->contiguousDouble()[i] = QNaN;
+ }
} else {
void* temp;
if (!globalData.heap.tryAllocateStorage(Butterfly::totalSize(0, 0, true, ArrayStorage::sizeFor(vectorLength)), &temp))
diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h
index 957ba8227..428e51f3c 100644
--- a/Source/JavaScriptCore/runtime/JSObject.h
+++ b/Source/JavaScriptCore/runtime/JSObject.h
@@ -862,6 +862,7 @@ protected:
JSValue getHolyIndexQuickly(unsigned i)
{
+ ASSERT(i < m_butterfly->vectorLength());
switch (structure()->indexingType()) {
case ALL_INT32_INDEXING_TYPES:
case ALL_CONTIGUOUS_INDEXING_TYPES:
diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h
index 5ad30bde3..bf4a0cf75 100644
--- a/Source/JavaScriptCore/runtime/Options.h
+++ b/Source/JavaScriptCore/runtime/Options.h
@@ -117,7 +117,6 @@ namespace JSC {
v(double, structureCheckVoteRatioForHoisting, 1) \
\
v(unsigned, minimumNumberOfScansBetweenRebalance, 100) \
- v(unsigned, gcMarkStackSegmentSize, pageSize()) \
v(unsigned, numberOfGCMarkers, computeNumberOfGCMarkers(7)) \
v(unsigned, opaqueRootMergeThreshold, 1000) \
v(double, minHeapUtilization, 0.8) \
diff --git a/Source/JavaScriptCore/yarr/YarrJIT.cpp b/Source/JavaScriptCore/yarr/YarrJIT.cpp
index d5b215413..1aef49bdf 100644
--- a/Source/JavaScriptCore/yarr/YarrJIT.cpp
+++ b/Source/JavaScriptCore/yarr/YarrJIT.cpp
@@ -756,7 +756,11 @@ class YarrGenerator : private MacroAssembler {
const RegisterID character = regT0;
int maxCharactersAtOnce = m_charSize == Char8 ? 4 : 2;
unsigned ignoreCaseMask = 0;
+#if CPU(BIG_ENDIAN)
+ int allCharacters = ch << (m_charSize == Char8 ? 24 : 16);
+#else
int allCharacters = ch;
+#endif
int numberCharacters;
int startTermPosition = term->inputPosition;
@@ -765,7 +769,11 @@ class YarrGenerator : private MacroAssembler {
ASSERT(!m_pattern.m_ignoreCase || isASCIIAlpha(ch) || isCanonicallyUnique(ch));
if (m_pattern.m_ignoreCase && isASCIIAlpha(ch))
+#if CPU(BIG_ENDIAN)
+ ignoreCaseMask |= 32 << (m_charSize == Char8 ? 24 : 16);
+#else
ignoreCaseMask |= 32;
+#endif
for (numberCharacters = 1; numberCharacters < maxCharactersAtOnce && nextOp->m_op == OpTerm; ++numberCharacters, nextOp = &m_ops[opIndex + numberCharacters]) {
PatternTerm* nextTerm = nextOp->m_term;
@@ -778,7 +786,11 @@ class YarrGenerator : private MacroAssembler {
nextOp->m_isDeadCode = true;
+#if CPU(BIG_ENDIAN)
+ int shiftAmount = (m_charSize == Char8 ? 24 : 16) - ((m_charSize == Char8 ? 8 : 16) * numberCharacters);
+#else
int shiftAmount = (m_charSize == Char8 ? 8 : 16) * numberCharacters;
+#endif
UChar currentCharacter = nextTerm->patternCharacter;