blob: 272d49c585445bdf29f62c2be466deebb3b37f68 [file] [log] [blame]
/*
* 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 "ArrayProfile.h"
#include "CodeBlock.h"
#include <wtf/StringExtras.h>
#include <wtf/StringPrintStream.h>
namespace JSC {
void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
{
if (!arrayModes) {
out.print("0:<empty>");
return;
}
if (arrayModes == ALL_ARRAY_MODES) {
out.print("TOP");
return;
}
out.print(arrayModes, ":");
if (arrayModes & asArrayModes(NonArray))
out.print("NonArray");
if (arrayModes & asArrayModes(NonArrayWithInt32))
out.print("NonArrayWithInt32");
if (arrayModes & asArrayModes(NonArrayWithDouble))
out.print("NonArrayWithDouble");
if (arrayModes & asArrayModes(NonArrayWithContiguous))
out.print("NonArrayWithContiguous");
if (arrayModes & asArrayModes(NonArrayWithArrayStorage))
out.print("NonArrayWithArrayStorage");
if (arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage))
out.print("NonArrayWithSlowPutArrayStorage");
if (arrayModes & asArrayModes(ArrayClass))
out.print("ArrayClass");
if (arrayModes & asArrayModes(ArrayWithUndecided))
out.print("ArrayWithUndecided");
if (arrayModes & asArrayModes(ArrayWithInt32))
out.print("ArrayWithInt32");
if (arrayModes & asArrayModes(ArrayWithDouble))
out.print("ArrayWithDouble");
if (arrayModes & asArrayModes(ArrayWithContiguous))
out.print("ArrayWithContiguous");
if (arrayModes & asArrayModes(ArrayWithArrayStorage))
out.print("ArrayWithArrayStorage");
if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage))
out.print("ArrayWithSlowPutArrayStorage");
}
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) {
m_observedArrayModes |= arrayModeFromStructure(m_lastSeenStructure);
m_mayInterceptIndexedAccesses |=
m_lastSeenStructure->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero();
if (!codeBlock->globalObject()->isOriginalArrayStructure(m_lastSeenStructure))
m_usesOriginalArrayStructures = false;
if (!structureIsPolymorphic()) {
if (!m_expectedStructure)
m_expectedStructure = m_lastSeenStructure;
else if (m_expectedStructure != m_lastSeenStructure)
m_expectedStructure = polymorphicStructure();
}
m_lastSeenStructure = 0;
}
if (hasTwoOrMoreBitsSet(m_observedArrayModes))
m_expectedStructure = polymorphicStructure();
if (operation == Collection
&& expectedStructure()
&& !Heap::isMarked(m_expectedStructure))
m_expectedStructure = polymorphicStructure();
}
CString ArrayProfile::briefDescription(CodeBlock* codeBlock)
{
computeUpdatedPrediction(codeBlock);
StringPrintStream out;
bool hasPrinted = false;
if (m_observedArrayModes) {
if (hasPrinted)
out.print(", ");
out.print(ArrayModesDump(m_observedArrayModes));
hasPrinted = true;
}
if (structureIsPolymorphic()) {
if (hasPrinted)
out.print(", ");
out.print("struct = TOP");
hasPrinted = true;
} else if (m_expectedStructure) {
if (hasPrinted)
out.print(", ");
out.print("struct = ", RawPointer(m_expectedStructure));
hasPrinted = true;
}
if (m_mayStoreToHole) {
if (hasPrinted)
out.print(", ");
out.print("Hole");
hasPrinted = true;
}
if (m_outOfBounds) {
if (hasPrinted)
out.print(", ");
out.print("OutOfBounds");
hasPrinted = true;
}
if (m_mayInterceptIndexedAccesses) {
if (hasPrinted)
out.print(", ");
out.print("Intercept");
hasPrinted = true;
}
if (m_usesOriginalArrayStructures) {
if (hasPrinted)
out.print(", ");
out.print("Original");
hasPrinted = true;
}
UNUSED_PARAM(hasPrinted);
return out.toCString();
}
} // namespace JSC