diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-05-07 11:21:11 +0200 |
commit | 2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch) | |
tree | 988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/JavaScriptCore/bytecode | |
parent | dd91e772430dc294e3bf478c119ef8d43c0a3358 (diff) | |
download | qtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz |
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/JavaScriptCore/bytecode')
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.cpp | 16 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.h | 32 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/DFGExitProfile.h | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ExecutionCounter.cpp | 1 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/Opcode.h | 3 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/Operands.h | 161 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/PredictedType.cpp | 51 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/PredictedType.h | 41 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/PredictionTracker.h | 76 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/SamplingTool.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/StructureSet.h | 12 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/StructureStubInfo.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/StructureStubInfo.h | 67 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ValueRecovery.h | 16 |
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); |