diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-09 09:42:44 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-09 09:42:44 +0100 |
commit | a59391482883479a9b28a6f1ace6d1ebd08a7ecd (patch) | |
tree | fa539db054a20a67bff2fc891c33b0f4ec632916 /Source/JavaScriptCore/bytecode | |
parent | cfd86b747d32ac22246a1aa908eaa720c63a88c1 (diff) | |
download | qtwebkit-a59391482883479a9b28a6f1ace6d1ebd08a7ecd.tar.gz |
Imported WebKit commit 7bcdfab9a40db7d16b4b95bb77d78b8a59c9e701 (http://svn.webkit.org/repository/webkit/trunk@134025)
New snapshot with numerious build fixes, including MSVC 2012 and ARM Thumb-2.
Diffstat (limited to 'Source/JavaScriptCore/bytecode')
-rw-r--r-- | Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp | 40 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h | 80 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ArrayProfile.cpp | 7 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ArrayProfile.h | 48 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/ByValInfo.h | 8 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.cpp | 52 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/CodeBlock.h | 12 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/DFGExitProfile.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/Instruction.h | 5 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/Opcode.h | 6 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/SpeculatedType.h | 26 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp | 19 | ||||
-rw-r--r-- | Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h | 11 |
13 files changed, 284 insertions, 32 deletions
diff --git a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp new file mode 100644 index 000000000..aa682da86 --- /dev/null +++ b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 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. + */ + +#include "config.h" +#include "ArrayAllocationProfile.h" + +namespace JSC { + +void ArrayAllocationProfile::updateIndexingType() +{ + if (!m_lastArray) + return; + m_currentIndexingType = leastUpperBoundOfIndexingTypes(m_currentIndexingType, m_lastArray->structure()->indexingType()); + m_lastArray = 0; +} + +} // namespace JSC + diff --git a/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h new file mode 100644 index 000000000..a1647fad4 --- /dev/null +++ b/Source/JavaScriptCore/bytecode/ArrayAllocationProfile.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 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 ArrayAllocationProfile_h +#define ArrayAllocationProfile_h + +#include "IndexingType.h" +#include "JSArray.h" + +namespace JSC { + +class ArrayAllocationProfile { +public: + ArrayAllocationProfile() + : m_currentIndexingType(ArrayWithUndecided) + , m_lastArray(0) + { + } + + IndexingType selectIndexingType() + { + if (m_lastArray && UNLIKELY(m_lastArray->structure()->indexingType() != m_currentIndexingType)) + updateIndexingType(); + return m_currentIndexingType; + } + + JSArray* updateLastAllocation(JSArray* lastArray) + { + m_lastArray = lastArray; + return lastArray; + } + + JS_EXPORT_PRIVATE void updateIndexingType(); + + static IndexingType selectIndexingTypeFor(ArrayAllocationProfile* profile) + { + if (!profile) + return ArrayWithUndecided; + return profile->selectIndexingType(); + } + + static JSArray* updateLastAllocationFor(ArrayAllocationProfile* profile, JSArray* lastArray) + { + if (profile) + profile->updateLastAllocation(lastArray); + return lastArray; + } + +private: + + IndexingType m_currentIndexingType; + JSArray* m_lastArray; +}; + +} // namespace JSC + +#endif // ArrayAllocationProfile_h + diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp index 5a87380fd..51baf332f 100644 --- a/Source/JavaScriptCore/bytecode/ArrayProfile.cpp +++ b/Source/JavaScriptCore/bytecode/ArrayProfile.cpp @@ -65,6 +65,13 @@ const char* arrayModesToString(ArrayModes arrayModes) return result; } +ArrayModes ArrayProfile::updatedObservedArrayModes() const +{ + if (m_lastSeenStructure) + return m_observedArrayModes | arrayModeFromStructure(m_lastSeenStructure); + return m_observedArrayModes; +} + void ArrayProfile::computeUpdatedPrediction(CodeBlock* codeBlock, OperationInProgress operation) { if (m_lastSeenStructure) { diff --git a/Source/JavaScriptCore/bytecode/ArrayProfile.h b/Source/JavaScriptCore/bytecode/ArrayProfile.h index 376684fc1..5116cd36f 100644 --- a/Source/JavaScriptCore/bytecode/ArrayProfile.h +++ b/Source/JavaScriptCore/bytecode/ArrayProfile.h @@ -45,15 +45,20 @@ typedef unsigned ArrayModes; #define ALL_NON_ARRAY_ARRAY_MODES \ (asArrayModes(NonArray) \ - | asArrayModes(NonArrayWithContiguous) \ - | asArrayModes(NonArrayWithArrayStorage) \ - | asArrayModes(NonArrayWithSlowPutArrayStorage)) + | asArrayModes(NonArrayWithInt32) \ + | asArrayModes(NonArrayWithDouble) \ + | asArrayModes(NonArrayWithContiguous) \ + | asArrayModes(NonArrayWithArrayStorage) \ + | asArrayModes(NonArrayWithSlowPutArrayStorage)) #define ALL_ARRAY_ARRAY_MODES \ (asArrayModes(ArrayClass) \ - | asArrayModes(ArrayWithContiguous) \ - | asArrayModes(ArrayWithArrayStorage) \ - | asArrayModes(ArrayWithSlowPutArrayStorage)) + | asArrayModes(ArrayWithUndecided) \ + | asArrayModes(ArrayWithInt32) \ + | asArrayModes(ArrayWithDouble) \ + | asArrayModes(ArrayWithContiguous) \ + | asArrayModes(ArrayWithArrayStorage) \ + | asArrayModes(ArrayWithSlowPutArrayStorage)) #define ALL_ARRAY_MODES (ALL_NON_ARRAY_ARRAY_MODES | ALL_ARRAY_ARRAY_MODES) @@ -79,6 +84,36 @@ inline bool arrayModesAlreadyChecked(ArrayModes proven, ArrayModes expected) return (expected | proven) == expected; } +inline bool arrayModesInclude(ArrayModes arrayModes, IndexingType shape) +{ + return !!(arrayModes & (asArrayModes(NonArray | shape) | asArrayModes(ArrayClass | shape))); +} + +inline bool shouldUseSlowPutArrayStorage(ArrayModes arrayModes) +{ + return arrayModesInclude(arrayModes, SlowPutArrayStorageShape); +} + +inline bool shouldUseFastArrayStorage(ArrayModes arrayModes) +{ + return arrayModesInclude(arrayModes, ArrayStorageShape); +} + +inline bool shouldUseContiguous(ArrayModes arrayModes) +{ + return arrayModesInclude(arrayModes, ContiguousShape); +} + +inline bool shouldUseDouble(ArrayModes arrayModes) +{ + return arrayModesInclude(arrayModes, DoubleShape); +} + +inline bool shouldUseInt32(ArrayModes arrayModes) +{ + return arrayModesInclude(arrayModes, Int32Shape); +} + class ArrayProfile { public: ArrayProfile() @@ -128,6 +163,7 @@ public: return !structureIsPolymorphic() && m_expectedStructure; } ArrayModes observedArrayModes() const { return m_observedArrayModes; } + ArrayModes updatedObservedArrayModes() const; // Computes the observed array modes without updating the profile. bool mayInterceptIndexedAccesses() const { return m_mayInterceptIndexedAccesses; } bool mayStoreToHole() const { return m_mayStoreToHole; } diff --git a/Source/JavaScriptCore/bytecode/ByValInfo.h b/Source/JavaScriptCore/bytecode/ByValInfo.h index 8cba4463d..3f79967df 100644 --- a/Source/JavaScriptCore/bytecode/ByValInfo.h +++ b/Source/JavaScriptCore/bytecode/ByValInfo.h @@ -39,6 +39,8 @@ namespace JSC { enum JITArrayMode { + JITInt32, + JITDouble, JITContiguous, JITArrayStorage, JITInt8Array, @@ -55,6 +57,8 @@ enum JITArrayMode { inline bool isOptimizableIndexingType(IndexingType indexingType) { switch (indexingType) { + case ALL_INT32_INDEXING_TYPES: + case ALL_DOUBLE_INDEXING_TYPES: case ALL_CONTIGUOUS_INDEXING_TYPES: case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: return true; @@ -77,6 +81,10 @@ inline bool hasOptimizableIndexing(Structure* structure) inline JITArrayMode jitArrayModeForIndexingType(IndexingType indexingType) { switch (indexingType) { + case ALL_INT32_INDEXING_TYPES: + return JITInt32; + case ALL_DOUBLE_INDEXING_TYPES: + return JITDouble; case ALL_CONTIGUOUS_INDEXING_TYPES: return JITContiguous; case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES: diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp index ceae3fcb2..83833c6ec 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp @@ -44,7 +44,7 @@ #include "JSValue.h" #include "LowLevelInterpreter.h" #include "RepatchBuffer.h" -#include "SlotVisitorInlineMethods.h" +#include "SlotVisitorInlines.h" #include <stdio.h> #include <wtf/StringExtras.h> #include <wtf/UnusedParam.h> @@ -654,6 +654,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int argc = (++it)->u.operand; dataLog("[%4d] new_array\t %s, %s, %d", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc); dumpBytecodeCommentAndNewLine(location); + ++it; // Skip array allocation profile. break; } case op_new_array_with_size: { @@ -661,6 +662,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int length = (++it)->u.operand; dataLog("[%4d] new_array_with_size\t %s, %s", location, registerName(exec, dst).data(), registerName(exec, length).data()); dumpBytecodeCommentAndNewLine(location); + ++it; // Skip array allocation profile. break; } case op_new_array_buffer: { @@ -669,6 +671,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int argc = (++it)->u.operand; dataLog("[%4d] new_array_buffer\t %s, %d, %d", location, registerName(exec, dst).data(), argv, argc); dumpBytecodeCommentAndNewLine(location); + ++it; // Skip array allocation profile. break; } case op_new_regexp: { @@ -1746,6 +1749,8 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin #if ENABLE(DFG_JIT) if (size_t size = unlinkedCodeBlock->numberOfArrayProfiles()) m_arrayProfiles.grow(size); + if (size_t size = unlinkedCodeBlock->numberOfArrayAllocationProfiles()) + m_arrayAllocationProfiles.grow(size); if (size_t size = unlinkedCodeBlock->numberOfValueProfiles()) m_valueProfiles.grow(size); #endif @@ -1800,19 +1805,32 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin break; } + case op_new_array: + case op_new_array_buffer: + case op_new_array_with_size: { + int arrayAllocationProfileIndex = pc[i + opLength - 1].u.operand; + instructions[i + opLength - 1] = &m_arrayAllocationProfiles[arrayAllocationProfileIndex]; + break; + } +#endif + case op_call: case op_call_eval: { +#if ENABLE(DFG_JIT) int arrayProfileIndex = pc[i + opLength - 1].u.operand; m_arrayProfiles[arrayProfileIndex] = ArrayProfile(i); instructions[i + opLength - 1] = &m_arrayProfiles[arrayProfileIndex]; - // fallthrough - } #endif #if ENABLE(LLINT) - case op_construct: instructions[i + 4] = &m_llintCallLinkInfos[pc[i + 4].u.operand]; +#endif break; + } + case op_construct: +#if ENABLE(LLINT) + instructions[i + 4] = &m_llintCallLinkInfos[pc[i + 4].u.operand]; #endif + break; case op_get_by_id_out_of_line: case op_get_by_id_self: case op_get_by_id_proto: @@ -2787,18 +2805,28 @@ void CodeBlock::updateAllPredictionsAndCountLiveness( #if ENABLE(DFG_JIT) m_lazyOperandValueProfiles.computeUpdatedPredictions(operation); #endif - - // Don't count the array profiles towards statistics, since each array profile - // site also has a value profile site - so we already know whether or not it's - // live. +} + +void CodeBlock::updateAllValueProfilePredictions(OperationInProgress operation) +{ + unsigned ignoredValue1, ignoredValue2; + updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2); +} + +void CodeBlock::updateAllArrayPredictions(OperationInProgress operation) +{ for (unsigned i = m_arrayProfiles.size(); i--;) m_arrayProfiles[i].computeUpdatedPrediction(this, operation); + + // Don't count these either, for similar reasons. + for (unsigned i = m_arrayAllocationProfiles.size(); i--;) + m_arrayAllocationProfiles[i].updateIndexingType(); } void CodeBlock::updateAllPredictions(OperationInProgress operation) { - unsigned ignoredValue1, ignoredValue2; - updateAllPredictionsAndCountLiveness(operation, ignoredValue1, ignoredValue2); + updateAllValueProfilePredictions(operation); + updateAllArrayPredictions(operation); } bool CodeBlock::shouldOptimizeNow() @@ -2814,12 +2842,14 @@ bool CodeBlock::shouldOptimizeNow() if (m_optimizationDelayCounter >= Options::maximumOptimizationDelay()) return true; + updateAllArrayPredictions(); + unsigned numberOfLiveNonArgumentValueProfiles; unsigned numberOfSamplesInProfiles; updateAllPredictionsAndCountLiveness(NoOperation, numberOfLiveNonArgumentValueProfiles, numberOfSamplesInProfiles); #if ENABLE(JIT_VERBOSE_OSR) - dataLog("Profile hotness: %lf, %lf\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles()); + dataLog("Profile hotness: %lf (%u / %u), %lf (%u / %u)\n", (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles(), numberOfLiveNonArgumentValueProfiles, numberOfValueProfiles(), (double)numberOfSamplesInProfiles / ValueProfile::numberOfBuckets / numberOfValueProfiles(), numberOfSamplesInProfiles, ValueProfile::numberOfBuckets * numberOfValueProfiles()); #endif if ((!numberOfValueProfiles() || (double)numberOfLiveNonArgumentValueProfiles / numberOfValueProfiles() >= Options::desiredProfileLivenessRate()) diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h index a28064940..0199935bb 100644 --- a/Source/JavaScriptCore/bytecode/CodeBlock.h +++ b/Source/JavaScriptCore/bytecode/CodeBlock.h @@ -755,6 +755,13 @@ namespace JSC { } ArrayProfile* getArrayProfile(unsigned bytecodeOffset); ArrayProfile* getOrAddArrayProfile(unsigned bytecodeOffset); + + unsigned numberOfArrayAllocationProfiles() const { return m_arrayAllocationProfiles.size(); } + ArrayAllocationProfile* addArrayAllocationProfile() + { + m_arrayAllocationProfiles.append(ArrayAllocationProfile()); + return &m_arrayAllocationProfiles.last(); + } #endif // Exception handling support @@ -1145,9 +1152,13 @@ namespace JSC { #if ENABLE(VALUE_PROFILER) bool shouldOptimizeNow(); + void updateAllValueProfilePredictions(OperationInProgress = NoOperation); + void updateAllArrayPredictions(OperationInProgress = NoOperation); void updateAllPredictions(OperationInProgress = NoOperation); #else bool shouldOptimizeNow() { return false; } + void updateAllValueProfilePredictions(OperationInProgress = NoOperation) { } + void updateAllArrayPredictions(OperationInProgress = NoOperation) { } void updateAllPredictions(OperationInProgress = NoOperation) { } #endif @@ -1330,6 +1341,7 @@ namespace JSC { SegmentedVector<ValueProfile, 8> m_valueProfiles; SegmentedVector<RareCaseProfile, 8> m_rareCaseProfiles; SegmentedVector<RareCaseProfile, 8> m_specialFastCaseProfiles; + SegmentedVector<ArrayAllocationProfile, 8> m_arrayAllocationProfiles; ArrayProfileVector m_arrayProfiles; unsigned m_executionEntryCount; #endif diff --git a/Source/JavaScriptCore/bytecode/DFGExitProfile.h b/Source/JavaScriptCore/bytecode/DFGExitProfile.h index 60d313ad4..7132adfd4 100644 --- a/Source/JavaScriptCore/bytecode/DFGExitProfile.h +++ b/Source/JavaScriptCore/bytecode/DFGExitProfile.h @@ -58,6 +58,8 @@ inline const char* exitKindToString(ExitKind kind) return "BadCache"; case BadWeakConstantCache: return "BadWeakConstantCache"; + case BadIndexingType: + return "BadIndexingType"; case Overflow: return "Overflow"; case NegativeZero: diff --git a/Source/JavaScriptCore/bytecode/Instruction.h b/Source/JavaScriptCore/bytecode/Instruction.h index 9fcf509f6..50b80e03c 100644 --- a/Source/JavaScriptCore/bytecode/Instruction.h +++ b/Source/JavaScriptCore/bytecode/Instruction.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 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 @@ -47,6 +47,7 @@ namespace JSC { // curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best // solution for now - will need to something smarter if/when we actually want mixed-mode operation. + class ArrayAllocationProfile; class ArrayProfile; class JSCell; class Structure; @@ -193,6 +194,7 @@ namespace JSC { Instruction(ValueProfile* profile) { u.profile = profile; } Instruction(ArrayProfile* profile) { u.arrayProfile = profile; } + Instruction(ArrayAllocationProfile* profile) { u.arrayAllocationProfile = profile; } Instruction(WriteBarrier<Unknown>* registerPointer) { u.registerPointer = registerPointer; } @@ -212,6 +214,7 @@ namespace JSC { LLIntCallLinkInfo* callLinkInfo; ValueProfile* profile; ArrayProfile* arrayProfile; + ArrayAllocationProfile* arrayAllocationProfile; void* pointer; bool* predicatePointer; } u; diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h index 8979d0b7b..38d314d78 100644 --- a/Source/JavaScriptCore/bytecode/Opcode.h +++ b/Source/JavaScriptCore/bytecode/Opcode.h @@ -48,9 +48,9 @@ namespace JSC { macro(op_convert_this, 3) \ \ macro(op_new_object, 2) \ - macro(op_new_array, 4) \ - macro(op_new_array_with_size, 3) \ - macro(op_new_array_buffer, 4) \ + macro(op_new_array, 5) \ + macro(op_new_array_with_size, 4) \ + macro(op_new_array_buffer, 5) \ macro(op_new_regexp, 3) \ macro(op_mov, 3) \ \ diff --git a/Source/JavaScriptCore/bytecode/SpeculatedType.h b/Source/JavaScriptCore/bytecode/SpeculatedType.h index 09ba9fdfa..656bc79ee 100644 --- a/Source/JavaScriptCore/bytecode/SpeculatedType.h +++ b/Source/JavaScriptCore/bytecode/SpeculatedType.h @@ -61,6 +61,7 @@ static const SpeculatedType SpecInt32 = 0x00800000; // It's definite static const SpeculatedType SpecDoubleReal = 0x01000000; // It's definitely a non-NaN double. static const SpeculatedType SpecDoubleNaN = 0x02000000; // It's definitely a NaN. static const SpeculatedType SpecDouble = 0x03000000; // It's either a non-NaN or a NaN double. +static const SpeculatedType SpecRealNumber = 0x01800000; // It's either an Int32 or a DoubleReal. static const SpeculatedType SpecNumber = 0x03800000; // It's either an Int32 or a Double. static const SpeculatedType SpecBoolean = 0x04000000; // It's definitely a Boolean. static const SpeculatedType SpecOther = 0x08000000; // It's definitely none of the above. @@ -228,6 +229,16 @@ inline bool isInt32Speculation(SpeculatedType value) return value == SpecInt32; } +inline bool isInt32SpeculationForArithmetic(SpeculatedType value) +{ + return !(value & SpecDouble); +} + +inline bool isInt32SpeculationExpectingDefined(SpeculatedType value) +{ + return isInt32Speculation(value & ~SpecOther); +} + inline bool isDoubleRealSpeculation(SpeculatedType value) { return value == SpecDoubleReal; @@ -238,11 +249,26 @@ inline bool isDoubleSpeculation(SpeculatedType value) return !!value && (value & SpecDouble) == value; } +inline bool isDoubleSpeculationForArithmetic(SpeculatedType value) +{ + return !!(value & SpecDouble); +} + +inline bool isRealNumberSpeculation(SpeculatedType value) +{ + return !!(value & SpecRealNumber) && !(value & ~SpecRealNumber); +} + inline bool isNumberSpeculation(SpeculatedType value) { return !!(value & SpecNumber) && !(value & ~SpecNumber); } +inline bool isNumberSpeculationExpectingDefined(SpeculatedType value) +{ + return isNumberSpeculation(value & ~SpecOther); +} + inline bool isBooleanSpeculation(SpeculatedType value) { return value == SpecBoolean; diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp index 8aa48404a..e98d4de0a 100644 --- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp +++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp @@ -80,8 +80,6 @@ void UnlinkedFunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visito COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); - visitor.append(&thisObject->m_codeBlockForCall); - visitor.append(&thisObject->m_codeBlockForConstruct); visitor.append(&thisObject->m_nameValue); visitor.append(&thisObject->m_symbolTableForCall); visitor.append(&thisObject->m_symbolTableForConstruct); @@ -112,12 +110,16 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(JSGlobalData { switch (specializationKind) { case CodeForCall: - if (m_codeBlockForCall) - return m_codeBlockForCall.get(); + if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForCall.get()) { + globalData.codeCache()->usedFunctionCode(globalData, codeBlock); + return codeBlock; + } break; case CodeForConstruct: - if (m_codeBlockForConstruct) - return m_codeBlockForConstruct.get(); + if (UnlinkedFunctionCodeBlock* codeBlock = m_codeBlockForConstruct.get()) { + globalData.codeCache()->usedFunctionCode(globalData, codeBlock); + return codeBlock; + } break; } @@ -128,11 +130,11 @@ UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::codeBlockFor(JSGlobalData switch (specializationKind) { case CodeForCall: - m_codeBlockForCall.set(globalData, this, result); + m_codeBlockForCall = PassWeak<UnlinkedFunctionCodeBlock>(result); m_symbolTableForCall.set(globalData, this, result->symbolTable()); break; case CodeForConstruct: - m_codeBlockForConstruct.set(globalData, this, result); + m_codeBlockForConstruct = PassWeak<UnlinkedFunctionCodeBlock>(result); m_symbolTableForConstruct.set(globalData, this, result->symbolTable()); break; } @@ -171,6 +173,7 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(JSGlobalData* globalData, Structure* struct , m_resolveOperationCount(0) , m_putToBaseOperationCount(1) , m_arrayProfileCount(0) + , m_arrayAllocationProfileCount(0) , m_valueProfileCount(0) , m_llintCallLinkInfoCount(0) #if ENABLE(BYTECODE_COMMENTS) diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h index bf3f5fdff..23937d773 100644 --- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h +++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h @@ -36,6 +36,7 @@ #include "Nodes.h" #include "RegExp.h" #include "SpecialPointer.h" +#include "Weak.h" #include <wtf/RefCountedArray.h> #include <wtf/Vector.h> @@ -56,6 +57,7 @@ class UnlinkedFunctionCodeBlock; typedef unsigned UnlinkedValueProfile; typedef unsigned UnlinkedArrayProfile; +typedef unsigned UnlinkedArrayAllocationProfile; typedef unsigned UnlinkedLLIntCallLinkInfo; struct ExecutableInfo { @@ -107,7 +109,7 @@ public: FunctionExecutable* link(JSGlobalData&, const SourceCode&, size_t lineOffset, size_t sourceOffset); - void clearCode() + void clearCodeForRecompilation() { m_symbolTableForCall.clear(); m_symbolTableForConstruct.clear(); @@ -135,8 +137,8 @@ public: private: UnlinkedFunctionExecutable(JSGlobalData*, Structure*, const SourceCode&, FunctionBodyNode*); - WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall; - WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; + Weak<UnlinkedFunctionCodeBlock> m_codeBlockForCall; + Weak<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; unsigned m_numCapturedVariables : 29; bool m_forceUsesArguments : 1; @@ -392,6 +394,8 @@ public: UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; } unsigned numberOfArrayProfiles() { return m_arrayProfileCount; } + UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; } + unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; } UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; } unsigned numberOfValueProfiles() { return m_valueProfileCount; } @@ -518,6 +522,7 @@ private: unsigned m_resolveOperationCount; unsigned m_putToBaseOperationCount; unsigned m_arrayProfileCount; + unsigned m_arrayAllocationProfileCount; unsigned m_valueProfileCount; unsigned m_llintCallLinkInfoCount; |