summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecode')
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.cpp16
-rw-r--r--Source/JavaScriptCore/bytecode/CodeBlock.h32
-rw-r--r--Source/JavaScriptCore/bytecode/DFGExitProfile.h3
-rw-r--r--Source/JavaScriptCore/bytecode/ExecutionCounter.cpp1
-rw-r--r--Source/JavaScriptCore/bytecode/Opcode.h3
-rw-r--r--Source/JavaScriptCore/bytecode/Operands.h161
-rw-r--r--Source/JavaScriptCore/bytecode/PredictedType.cpp51
-rw-r--r--Source/JavaScriptCore/bytecode/PredictedType.h41
-rw-r--r--Source/JavaScriptCore/bytecode/PredictionTracker.h76
-rw-r--r--Source/JavaScriptCore/bytecode/SamplingTool.h2
-rw-r--r--Source/JavaScriptCore/bytecode/StructureSet.h12
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.cpp2
-rw-r--r--Source/JavaScriptCore/bytecode/StructureStubInfo.h67
-rw-r--r--Source/JavaScriptCore/bytecode/ValueRecovery.h16
14 files changed, 335 insertions, 148 deletions
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 20972cc63..7b828acab 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -1248,17 +1248,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
dataLog("[%4d] throw_reference_error\t %s\n", location, constantName(exec, k0, getConstant(k0)).data());
break;
}
- case op_jsr: {
- int retAddrDst = (++it)->u.operand;
- int offset = (++it)->u.operand;
- dataLog("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).data(), offset, location + offset);
- break;
- }
- case op_sret: {
- int retAddrSrc = (++it)->u.operand;
- dataLog("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).data());
- break;
- }
case op_debug: {
int debugHookID = (++it)->u.operand;
int firstLine = (++it)->u.operand;
@@ -1443,6 +1432,7 @@ CodeBlock::CodeBlock(CopyParsedBlockTag, CodeBlock& other, SymbolTable* symTab)
, m_symbolTable(symTab)
, m_speculativeSuccessCounter(0)
, m_speculativeFailCounter(0)
+ , m_forcedOSRExitCounter(0)
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
#if ENABLE(JIT)
@@ -1765,7 +1755,7 @@ void CodeBlock::finalizeUnconditionally()
Interpreter* interpreter = m_globalData->interpreter;
// interpreter->classicEnabled() returns true if the old C++ interpreter is enabled. If that's enabled
// then we're not using LLInt.
- if (!interpreter->classicEnabled()) {
+ if (!interpreter->classicEnabled() && !!numberOfInstructions()) {
for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i) {
Instruction* curInstruction = &instructions()[m_propertyAccessInstructions[i]];
switch (interpreter->getOpcodeID(curInstruction[0].u.opcode)) {
@@ -1936,7 +1926,7 @@ void CodeBlock::stronglyVisitStrongReferences(SlotVisitor& visitor)
for (size_t i = 0; i < m_functionDecls.size(); ++i)
visitor.append(&m_functionDecls[i]);
#if ENABLE(CLASSIC_INTERPRETER)
- if (m_globalData->interpreter->classicEnabled()) {
+ if (m_globalData->interpreter->classicEnabled() && !!numberOfInstructions()) {
for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
visitStructures(visitor, &instructions()[m_propertyAccessInstructions[i]]);
for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h
index 469028097..778376f94 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h
@@ -56,7 +56,6 @@
#include "LazyOperandValueProfile.h"
#include "LineInfo.h"
#include "Nodes.h"
-#include "PredictionTracker.h"
#include "RegExpObject.h"
#include "StructureStubInfo.h"
#include "UString.h"
@@ -1006,12 +1005,15 @@ namespace JSC {
uint32_t speculativeSuccessCounter() const { return m_speculativeSuccessCounter; }
uint32_t speculativeFailCounter() const { return m_speculativeFailCounter; }
+ uint32_t forcedOSRExitCounter() const { return m_forcedOSRExitCounter; }
uint32_t* addressOfSpeculativeSuccessCounter() { return &m_speculativeSuccessCounter; }
uint32_t* addressOfSpeculativeFailCounter() { return &m_speculativeFailCounter; }
+ uint32_t* addressOfForcedOSRExitCounter() { return &m_forcedOSRExitCounter; }
static ptrdiff_t offsetOfSpeculativeSuccessCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeSuccessCounter); }
static ptrdiff_t offsetOfSpeculativeFailCounter() { return OBJECT_OFFSETOF(CodeBlock, m_speculativeFailCounter); }
+ static ptrdiff_t offsetOfForcedOSRExitCounter() { return OBJECT_OFFSETOF(CodeBlock, m_forcedOSRExitCounter); }
#if ENABLE(JIT)
// The number of failures that triggers the use of the ratio.
@@ -1020,12 +1022,20 @@ namespace JSC {
bool shouldReoptimizeNow()
{
- return Options::desiredSpeculativeSuccessFailRatio * speculativeFailCounter() >= speculativeSuccessCounter() && speculativeFailCounter() >= largeFailCountThreshold();
+ return (Options::desiredSpeculativeSuccessFailRatio *
+ speculativeFailCounter() >= speculativeSuccessCounter()
+ && speculativeFailCounter() >= largeFailCountThreshold())
+ || forcedOSRExitCounter() >=
+ Options::forcedOSRExitCountForReoptimization;
}
bool shouldReoptimizeFromLoopNow()
{
- return Options::desiredSpeculativeSuccessFailRatio * speculativeFailCounter() >= speculativeSuccessCounter() && speculativeFailCounter() >= largeFailCountThresholdForLoop();
+ return (Options::desiredSpeculativeSuccessFailRatio *
+ speculativeFailCounter() >= speculativeSuccessCounter()
+ && speculativeFailCounter() >= largeFailCountThresholdForLoop())
+ || forcedOSRExitCounter() >=
+ Options::forcedOSRExitCountForReoptimization;
}
#endif
@@ -1228,6 +1238,7 @@ namespace JSC {
int32_t m_totalJITExecutions;
uint32_t m_speculativeSuccessCounter;
uint32_t m_speculativeFailCounter;
+ uint32_t m_forcedOSRExitCounter;
uint16_t m_optimizationDelayCounter;
uint16_t m_reoptimizationRetryCounter;
@@ -1385,13 +1396,18 @@ namespace JSC {
#endif
};
+ inline CodeBlock* baselineCodeBlockForInlineCallFrame(InlineCallFrame* inlineCallFrame)
+ {
+ ASSERT(inlineCallFrame);
+ ExecutableBase* executable = inlineCallFrame->executable.get();
+ ASSERT(executable->structure()->classInfo() == &FunctionExecutable::s_info);
+ return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
+ }
+
inline CodeBlock* baselineCodeBlockForOriginAndBaselineCodeBlock(const CodeOrigin& codeOrigin, CodeBlock* baselineCodeBlock)
{
- if (codeOrigin.inlineCallFrame) {
- ExecutableBase* executable = codeOrigin.inlineCallFrame->executable.get();
- ASSERT(executable->structure()->classInfo() == &FunctionExecutable::s_info);
- return static_cast<FunctionExecutable*>(executable)->baselineCodeBlockFor(codeOrigin.inlineCallFrame->isCall ? CodeForCall : CodeForConstruct);
- }
+ if (codeOrigin.inlineCallFrame)
+ return baselineCodeBlockForInlineCallFrame(codeOrigin.inlineCallFrame);
return baselineCodeBlock;
}
diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.h b/Source/JavaScriptCore/bytecode/DFGExitProfile.h
index edabfabf9..31db084f5 100644
--- a/Source/JavaScriptCore/bytecode/DFGExitProfile.h
+++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.h
@@ -38,6 +38,7 @@ enum ExitKind {
BadCache, // We exited because an inline cache was wrong.
Overflow, // We exited because of overflow.
NegativeZero, // We exited because we encountered negative zero.
+ InadequateCoverage, // We exited because we ended up in code that didn't have profiling coverage.
Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
};
@@ -54,6 +55,8 @@ inline const char* exitKindToString(ExitKind kind)
return "Overflow";
case NegativeZero:
return "NegativeZero";
+ case InadequateCoverage:
+ return "InadequateCoverage";
default:
return "Unknown";
}
diff --git a/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
index b3fd3ef26..ea335005e 100644
--- a/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
+++ b/Source/JavaScriptCore/bytecode/ExecutionCounter.cpp
@@ -28,7 +28,6 @@
#include "CodeBlock.h"
#include "ExecutableAllocator.h"
-#include <wtf/DataLog.h>
namespace JSC {
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index 45598f899..a564de2da 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -189,9 +189,6 @@ namespace JSC {
macro(op_throw, 2) \
macro(op_throw_reference_error, 2) \
\
- macro(op_jsr, 3) \
- macro(op_sret, 2) \
- \
macro(op_debug, 4) \
macro(op_profile_will_call, 2) \
macro(op_profile_did_call, 2) \
diff --git a/Source/JavaScriptCore/bytecode/Operands.h b/Source/JavaScriptCore/bytecode/Operands.h
new file mode 100644
index 000000000..a05159f81
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/Operands.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Operands_h
+#define Operands_h
+
+#include "CallFrame.h"
+#include "JSObject.h"
+#include "ScopeChain.h"
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+// argument 0 is 'this'.
+inline bool operandIsArgument(int operand) { return operand < 0; }
+inline int operandToArgument(int operand) { return -operand + CallFrame::thisArgumentOffset(); }
+inline int argumentToOperand(int argument) { return -argument + CallFrame::thisArgumentOffset(); }
+
+template<typename T> struct OperandValueTraits;
+
+template<typename T>
+struct OperandValueTraits {
+ static T defaultValue() { return T(); }
+ static void dump(const T& value, FILE* out) { value.dump(out); }
+};
+
+template<typename T, typename Traits = OperandValueTraits<T> >
+class Operands {
+public:
+ Operands() { }
+
+ explicit Operands(size_t numArguments, size_t numLocals)
+ {
+ m_arguments.fill(Traits::defaultValue(), numArguments);
+ m_locals.fill(Traits::defaultValue(), numLocals);
+ }
+
+ size_t numberOfArguments() const { return m_arguments.size(); }
+ size_t numberOfLocals() const { return m_locals.size(); }
+
+ T& argument(size_t idx) { return m_arguments[idx]; }
+ const T& argument(size_t idx) const { return m_arguments[idx]; }
+
+ T& local(size_t idx) { return m_locals[idx]; }
+ const T& local(size_t idx) const { return m_locals[idx]; }
+
+ void ensureLocals(size_t size)
+ {
+ if (size <= m_locals.size())
+ return;
+
+ size_t oldSize = m_locals.size();
+ m_locals.resize(size);
+ for (size_t i = oldSize; i < m_locals.size(); ++i)
+ m_locals[i] = Traits::defaultValue();
+ }
+
+ void setLocal(size_t idx, const T& value)
+ {
+ ensureLocals(idx + 1);
+
+ m_locals[idx] = value;
+ }
+
+ T getLocal(size_t idx)
+ {
+ if (idx >= m_locals.size())
+ return Traits::defaultValue();
+ return m_locals[idx];
+ }
+
+ void setArgumentFirstTime(size_t idx, const T& value)
+ {
+ ASSERT(m_arguments[idx] == Traits::defaultValue());
+ argument(idx) = value;
+ }
+
+ void setLocalFirstTime(size_t idx, const T& value)
+ {
+ ASSERT(idx >= m_locals.size() || m_locals[idx] == Traits::defaultValue());
+ setLocal(idx, value);
+ }
+
+ T& operand(int operand)
+ {
+ if (operandIsArgument(operand)) {
+ int argument = operandToArgument(operand);
+ return m_arguments[argument];
+ }
+
+ return m_locals[operand];
+ }
+
+ const T& operand(int operand) const { return const_cast<const T&>(const_cast<Operands*>(this)->operand(operand)); }
+
+ void setOperand(int operand, const T& value)
+ {
+ if (operandIsArgument(operand)) {
+ int argument = operandToArgument(operand);
+ m_arguments[argument] = value;
+ return;
+ }
+
+ setLocal(operand, value);
+ }
+
+ void clear()
+ {
+ for (size_t i = 0; i < m_arguments.size(); ++i)
+ m_arguments[i] = Traits::defaultValue();
+ for (size_t i = 0; i < m_locals.size(); ++i)
+ m_locals[i] = Traits::defaultValue();
+ }
+
+private:
+ Vector<T, 8> m_arguments;
+ Vector<T, 16> m_locals;
+};
+
+template<typename T, typename Traits>
+void dumpOperands(Operands<T, Traits>& operands, FILE* out)
+{
+ for (size_t argument = 0; argument < operands.numberOfArguments(); ++argument) {
+ if (argument)
+ fprintf(out, " ");
+ Traits::dump(operands.argument(argument), out);
+ }
+ fprintf(out, " : ");
+ for (size_t local = 0; local < operands.numberOfLocals(); ++local) {
+ if (local)
+ fprintf(out, " ");
+ Traits::dump(operands.local(local), out);
+ }
+}
+
+} // namespace JSC
+
+#endif // Operands_h
+
diff --git a/Source/JavaScriptCore/bytecode/PredictedType.cpp b/Source/JavaScriptCore/bytecode/PredictedType.cpp
index b04ff1f57..e8a71772b 100644
--- a/Source/JavaScriptCore/bytecode/PredictedType.cpp
+++ b/Source/JavaScriptCore/bytecode/PredictedType.cpp
@@ -30,7 +30,6 @@
#include "PredictedType.h"
#include "JSArray.h"
-#include "JSByteArray.h"
#include "JSFunction.h"
#include "ValueProfile.h"
#include <wtf/BoundsCheckedPointer.h>
@@ -68,11 +67,6 @@ const char* predictionToString(PredictedType value)
else
isTop = false;
- if (value & PredictByteArray)
- ptr.strcat("Bytearray");
- else
- isTop = false;
-
if (value & PredictInt8Array)
ptr.strcat("Int8array");
else
@@ -166,6 +160,49 @@ const char* predictionToString(PredictedType value)
return description;
}
+const char* predictionToAbbreviatedString(PredictedType prediction)
+{
+ if (isFinalObjectPrediction(prediction))
+ return "<Final>";
+ if (isArrayPrediction(prediction))
+ return "<Array>";
+ if (isStringPrediction(prediction))
+ return "<String>";
+ if (isFunctionPrediction(prediction))
+ return "<Function>";
+ if (isInt8ArrayPrediction(prediction))
+ return "<Int8array>";
+ if (isInt16ArrayPrediction(prediction))
+ return "<Int16array>";
+ if (isInt32ArrayPrediction(prediction))
+ return "<Int32array>";
+ if (isUint8ArrayPrediction(prediction))
+ return "<Uint8array>";
+ if (isUint16ArrayPrediction(prediction))
+ return "<Uint16array>";
+ if (isUint32ArrayPrediction(prediction))
+ return "<Uint32array>";
+ if (isFloat32ArrayPrediction(prediction))
+ return "<Float32array>";
+ if (isFloat64ArrayPrediction(prediction))
+ return "<Float64array>";
+ if (isObjectPrediction(prediction))
+ return "<Object>";
+ if (isCellPrediction(prediction))
+ return "<Cell>";
+ if (isInt32Prediction(prediction))
+ return "<Int32>";
+ if (isDoublePrediction(prediction))
+ return "<Double>";
+ if (isNumberPrediction(prediction))
+ return "<Number>";
+ if (isBooleanPrediction(prediction))
+ return "<Boolean>";
+ if (isOtherPrediction(prediction))
+ return "<Other>";
+ return "";
+}
+
PredictedType predictionFromClassInfo(const ClassInfo* classInfo)
{
if (classInfo == &JSFinalObject::s_info)
@@ -180,8 +217,6 @@ PredictedType predictionFromClassInfo(const ClassInfo* classInfo)
if (classInfo->isSubClassOf(&JSFunction::s_info))
return PredictFunction;
- if (classInfo->isSubClassOf(&JSByteArray::s_info))
- return PredictByteArray;
if (classInfo->typedArrayStorageType != TypedArrayNone) {
switch (classInfo->typedArrayStorageType) {
diff --git a/Source/JavaScriptCore/bytecode/PredictedType.h b/Source/JavaScriptCore/bytecode/PredictedType.h
index 0b7916610..54b308124 100644
--- a/Source/JavaScriptCore/bytecode/PredictedType.h
+++ b/Source/JavaScriptCore/bytecode/PredictedType.h
@@ -39,7 +39,6 @@ typedef uint32_t PredictedType;
static const PredictedType PredictNone = 0x00000000; // We don't know anything yet.
static const PredictedType PredictFinalObject = 0x00000001; // It's definitely a JSFinalObject.
static const PredictedType PredictArray = 0x00000002; // It's definitely a JSArray.
-static const PredictedType PredictByteArray = 0x00000004; // It's definitely a JSByteArray or one of its subclasses.
static const PredictedType PredictFunction = 0x00000008; // It's definitely a JSFunction or one of its subclasses.
static const PredictedType PredictInt8Array = 0x00000010; // It's definitely an Int8Array or one of its subclasses.
static const PredictedType PredictInt16Array = 0x00000020; // It's definitely an Int16Array or one of its subclasses.
@@ -50,7 +49,7 @@ static const PredictedType PredictUint16Array = 0x00000200; // It's defini
static const PredictedType PredictUint32Array = 0x00000400; // It's definitely an Uint32Array or one of its subclasses.
static const PredictedType PredictFloat32Array = 0x00000800; // It's definitely an Uint16Array or one of its subclasses.
static const PredictedType PredictFloat64Array = 0x00001000; // It's definitely an Uint16Array or one of its subclasses.
-static const PredictedType PredictObjectOther = 0x00002000; // It's definitely an object but not JSFinalObject, JSArray, JSByteArray, or JSFunction.
+static const PredictedType PredictObjectOther = 0x00002000; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
static const PredictedType PredictObjectMask = 0x00003fff; // Bitmask used for testing for any kind of object prediction.
static const PredictedType PredictString = 0x00004000; // It's definitely a JSString.
static const PredictedType PredictCellOther = 0x00008000; // It's definitely a JSCell but not a subclass of JSObject and definitely not a JSString.
@@ -65,7 +64,7 @@ static const PredictedType PredictOther = 0x08000000; // It's defini
static const PredictedType PredictTop = 0x0fffffff; // It can be any of the above.
static const PredictedType PredictEmpty = 0x10000000; // It's definitely an empty value marker.
static const PredictedType PredictEmptyOrTop = 0x1fffffff; // It can be any of the above.
-static const PredictedType FixedIndexedStorageMask = PredictByteArray | PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint8ClampedArray | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array;
+static const PredictedType FixedIndexedStorageMask = PredictInt8Array | PredictInt16Array | PredictInt32Array | PredictUint8Array | PredictUint8ClampedArray | PredictUint16Array | PredictUint32Array | PredictFloat32Array | PredictFloat64Array;
typedef bool (*PredictionChecker)(PredictedType);
@@ -109,11 +108,6 @@ inline bool isFunctionPrediction(PredictedType value)
return value == PredictFunction;
}
-inline bool isByteArrayPrediction(PredictedType value)
-{
- return value == PredictByteArray;
-}
-
inline bool isInt8ArrayPrediction(PredictedType value)
{
return value == PredictInt8Array;
@@ -159,25 +153,35 @@ inline bool isFloat64ArrayPrediction(PredictedType value)
return value == PredictFloat64Array;
}
-inline bool isActionableMutableArrayPrediction(PredictedType value)
+inline bool isActionableIntMutableArrayPrediction(PredictedType value)
{
- return isArrayPrediction(value)
- || isByteArrayPrediction(value)
-#if CPU(X86) || CPU(X86_64)
- || isInt8ArrayPrediction(value)
+ return isInt8ArrayPrediction(value)
|| isInt16ArrayPrediction(value)
-#endif
|| isInt32ArrayPrediction(value)
|| isUint8ArrayPrediction(value)
|| isUint8ClampedArrayPrediction(value)
|| isUint16ArrayPrediction(value)
- || isUint32ArrayPrediction(value)
-#if CPU(X86) || CPU(X86_64)
- || isFloat32ArrayPrediction(value)
-#endif
+ || isUint32ArrayPrediction(value);
+}
+
+inline bool isActionableFloatMutableArrayPrediction(PredictedType value)
+{
+ return isFloat32ArrayPrediction(value)
|| isFloat64ArrayPrediction(value);
}
+inline bool isActionableTypedMutableArrayPrediction(PredictedType value)
+{
+ return isActionableIntMutableArrayPrediction(value)
+ || isActionableFloatMutableArrayPrediction(value);
+}
+
+inline bool isActionableMutableArrayPrediction(PredictedType value)
+{
+ return isArrayPrediction(value)
+ || isActionableTypedMutableArrayPrediction(value);
+}
+
inline bool isActionableArrayPrediction(PredictedType value)
{
return isStringPrediction(value)
@@ -225,6 +229,7 @@ inline bool isEmptyPrediction(PredictedType value)
}
const char* predictionToString(PredictedType value);
+const char* predictionToAbbreviatedString(PredictedType value);
// Merge two predictions. Note that currently this just does left | right. It may
// seem tempting to do so directly, but you would be doing so at your own peril,
diff --git a/Source/JavaScriptCore/bytecode/PredictionTracker.h b/Source/JavaScriptCore/bytecode/PredictionTracker.h
deleted file mode 100644
index 7551cd3f3..000000000
--- a/Source/JavaScriptCore/bytecode/PredictionTracker.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PredictionTracker_h
-#define PredictionTracker_h
-
-#include "PredictedType.h"
-#include <wtf/HashMap.h>
-
-namespace JSC {
-
-struct PredictionSlot {
-public:
- PredictionSlot()
- : m_value(PredictNone)
- {
- }
- PredictedType m_value;
-};
-
-class PredictionTracker {
-public:
- PredictionTracker()
- {
- }
-
- bool predictGlobalVar(unsigned varNumber, PredictedType prediction)
- {
- HashMap<unsigned, PredictionSlot>::iterator iter = m_globalVars.find(varNumber + 1);
- if (iter == m_globalVars.end()) {
- PredictionSlot predictionSlot;
- bool result = mergePrediction(predictionSlot.m_value, prediction);
- m_globalVars.add(varNumber + 1, predictionSlot);
- return result;
- }
- return mergePrediction(iter->second.m_value, prediction);
- }
-
- PredictedType getGlobalVarPrediction(unsigned varNumber)
- {
- HashMap<unsigned, PredictionSlot>::iterator iter = m_globalVars.find(varNumber + 1);
- if (iter == m_globalVars.end())
- return PredictNone;
- return iter->second.m_value;
- }
-
-private:
- HashMap<unsigned, PredictionSlot> m_globalVars;
-};
-
-} // namespace JSC
-
-#endif // PredictionTracker_h
-
diff --git a/Source/JavaScriptCore/bytecode/SamplingTool.h b/Source/JavaScriptCore/bytecode/SamplingTool.h
index fcb1986fd..52a6e35ad 100644
--- a/Source/JavaScriptCore/bytecode/SamplingTool.h
+++ b/Source/JavaScriptCore/bytecode/SamplingTool.h
@@ -124,7 +124,7 @@ namespace JSC {
static void sample();
- static void dump();
+ JS_EXPORT_PRIVATE static void dump();
private:
const char* m_name;
diff --git a/Source/JavaScriptCore/bytecode/StructureSet.h b/Source/JavaScriptCore/bytecode/StructureSet.h
index 344183b45..bfc30fc3c 100644
--- a/Source/JavaScriptCore/bytecode/StructureSet.h
+++ b/Source/JavaScriptCore/bytecode/StructureSet.h
@@ -27,13 +27,12 @@
#define StructureSet_h
#include "PredictedType.h"
+#include "Structure.h"
#include <stdio.h>
#include <wtf/Vector.h>
namespace JSC {
-class Structure;
-
namespace DFG {
class StructureAbstractValue;
}
@@ -107,6 +106,15 @@ public:
size_t size() const { return m_structures.size(); }
+ bool allAreUsingInlinePropertyStorage() const
+ {
+ for (size_t i = 0; i < m_structures.size(); ++i) {
+ if (!m_structures[i]->isUsingInlineStorage())
+ return false;
+ }
+ return true;
+ }
+
Structure* at(size_t i) const { return m_structures.at(i); }
Structure* operator[](size_t i) const { return at(i); }
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
index f2657b785..f66860a45 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.cpp
@@ -92,7 +92,7 @@ bool StructureStubInfo::visitWeakReferences()
}
case access_get_by_id_proto_list: {
PolymorphicAccessStructureList* polymorphicStructures = u.getByIdProtoList.structureList;
- if (!polymorphicStructures->visitWeak(u.getByIdSelfList.listSize))
+ if (!polymorphicStructures->visitWeak(u.getByIdProtoList.listSize))
return false;
break;
}
diff --git a/Source/JavaScriptCore/bytecode/StructureStubInfo.h b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
index 8fad5c0cc..03c64bf39 100644
--- a/Source/JavaScriptCore/bytecode/StructureStubInfo.h
+++ b/Source/JavaScriptCore/bytecode/StructureStubInfo.h
@@ -122,8 +122,8 @@ namespace JSC {
{
accessType = access_get_by_id_self_list;
- u.getByIdProtoList.structureList = structureList;
- u.getByIdProtoList.listSize = listSize;
+ u.getByIdSelfList.structureList = structureList;
+ u.getByIdSelfList.listSize = listSize;
}
void initGetByIdProtoList(PolymorphicAccessStructureList* structureList, int listSize)
@@ -163,8 +163,8 @@ namespace JSC {
void reset()
{
- accessType = access_unset;
deref();
+ accessType = access_unset;
stubRoutine = MacroAssemblerCodeRef();
}
@@ -186,27 +186,60 @@ namespace JSC {
int8_t accessType;
int8_t seen;
-
+
#if ENABLE(DFG_JIT)
CodeOrigin codeOrigin;
- int8_t registersFlushed;
- int8_t baseGPR;
+#endif // ENABLE(DFG_JIT)
+
+ union {
+ struct {
+ int8_t registersFlushed;
+ int8_t baseGPR;
#if USE(JSVALUE32_64)
- int8_t valueTagGPR;
+ int8_t valueTagGPR;
#endif
- int8_t valueGPR;
- int8_t scratchGPR;
- int16_t deltaCallToDone;
- int16_t deltaCallToStructCheck;
- int16_t deltaCallToSlowCase;
- int16_t deltaCheckImmToCall;
+ int8_t valueGPR;
+ int8_t scratchGPR;
+ int16_t deltaCallToDone;
+ int16_t deltaCallToStructCheck;
+ int16_t deltaCallToSlowCase;
+ int16_t deltaCheckImmToCall;
#if USE(JSVALUE64)
- int16_t deltaCallToLoadOrStore;
+ int16_t deltaCallToLoadOrStore;
#else
- int16_t deltaCallToTagLoadOrStore;
- int16_t deltaCallToPayloadLoadOrStore;
+ int16_t deltaCallToTagLoadOrStore;
+ int16_t deltaCallToPayloadLoadOrStore;
#endif
-#endif // ENABLE(DFG_JIT)
+ } dfg;
+ struct {
+ union {
+ struct {
+ int16_t structureToCompare;
+ int16_t structureCheck;
+#if USE(JSVALUE64)
+ int16_t displacementLabel;
+#else
+ int16_t displacementLabel1;
+ int16_t displacementLabel2;
+#endif
+ int16_t putResult;
+ int16_t coldPathBegin;
+ } get;
+ struct {
+ int16_t structureToCompare;
+#if USE(JSVALUE64)
+ int16_t displacementLabel;
+#else
+ int16_t displacementLabel1;
+ int16_t displacementLabel2;
+#endif
+ } put;
+ } u;
+ int16_t methodCheckProtoObj;
+ int16_t methodCheckProtoStructureToCompare;
+ int16_t methodCheckPutFunction;
+ } baseline;
+ } patch;
union {
struct {
diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.h b/Source/JavaScriptCore/bytecode/ValueRecovery.h
index 4d2134e0a..007c6d3b7 100644
--- a/Source/JavaScriptCore/bytecode/ValueRecovery.h
+++ b/Source/JavaScriptCore/bytecode/ValueRecovery.h
@@ -192,6 +192,8 @@ public:
ValueRecoveryTechnique technique() const { return m_technique; }
+ bool isConstant() const { return m_technique == Constant; }
+
bool isInRegisters() const
{
switch (m_technique) {
@@ -208,6 +210,20 @@ public:
}
}
+ bool isAlreadyInRegisterFile() const
+ {
+ switch (technique()) {
+ case AlreadyInRegisterFile:
+ case AlreadyInRegisterFileAsUnboxedInt32:
+ case AlreadyInRegisterFileAsUnboxedCell:
+ case AlreadyInRegisterFileAsUnboxedBoolean:
+ case AlreadyInRegisterFileAsUnboxedDouble:
+ return true;
+ default:
+ return false;
+ }
+ }
+
MacroAssembler::RegisterID gpr() const
{
ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR);