ArrayProfile.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /*
  2. * Copyright (C) 2012 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "ArrayProfile.h"
  27. #include "CodeBlock.h"
  28. #include <wtf/StringExtras.h>
  29. #include <wtf/StringPrintStream.h>
  30. namespace JSC {
  31. void dumpArrayModes(PrintStream& out, ArrayModes arrayModes)
  32. {
  33. if (!arrayModes) {
  34. out.print("0:<empty>");
  35. return;
  36. }
  37. if (arrayModes == ALL_ARRAY_MODES) {
  38. out.print("TOP");
  39. return;
  40. }
  41. out.print(arrayModes, ":");
  42. if (arrayModes & asArrayModes(NonArray))
  43. out.print("NonArray");
  44. if (arrayModes & asArrayModes(NonArrayWithInt32))
  45. out.print("NonArrayWithInt32");
  46. if (arrayModes & asArrayModes(NonArrayWithDouble))
  47. out.print("NonArrayWithDouble");
  48. if (arrayModes & asArrayModes(NonArrayWithContiguous))
  49. out.print("NonArrayWithContiguous");
  50. if (arrayModes & asArrayModes(NonArrayWithArrayStorage))
  51. out.print("NonArrayWithArrayStorage");
  52. if (arrayModes & asArrayModes(NonArrayWithSlowPutArrayStorage))
  53. out.print("NonArrayWithSlowPutArrayStorage");
  54. if (arrayModes & asArrayModes(ArrayClass))
  55. out.print("ArrayClass");
  56. if (arrayModes & asArrayModes(ArrayWithUndecided))
  57. out.print("ArrayWithUndecided");
  58. if (arrayModes & asArrayModes(ArrayWithInt32))
  59. out.print("ArrayWithInt32");
  60. if (arrayModes & asArrayModes(ArrayWithDouble))
  61. out.print("ArrayWithDouble");
  62. if (arrayModes & asArrayModes(ArrayWithContiguous))
  63. out.print("ArrayWithContiguous");
  64. if (arrayModes & asArrayModes(ArrayWithArrayStorage))
  65. out.print("ArrayWithArrayStorage");
  66. if (arrayModes & asArrayModes(ArrayWithSlowPutArrayStorage))
  67. out.print("ArrayWithSlowPutArrayStorage");
  68. }
  69. ArrayModes ArrayProfile::updatedObservedArrayModes() const
  70. {
  71. if (m_lastSeenStructure)
  72. return m_observedArrayModes | arrayModeFromStructure(m_lastSeenStructure);
  73. return m_observedArrayModes;
  74. }
  75. void ArrayProfile::computeUpdatedPrediction(CodeBlock* codeBlock, OperationInProgress operation)
  76. {
  77. const bool verbose = false;
  78. if (m_lastSeenStructure) {
  79. m_observedArrayModes |= arrayModeFromStructure(m_lastSeenStructure);
  80. m_mayInterceptIndexedAccesses |=
  81. m_lastSeenStructure->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero();
  82. if (!codeBlock->globalObject()->isOriginalArrayStructure(m_lastSeenStructure))
  83. m_usesOriginalArrayStructures = false;
  84. if (!structureIsPolymorphic()) {
  85. if (!m_expectedStructure)
  86. m_expectedStructure = m_lastSeenStructure;
  87. else if (m_expectedStructure != m_lastSeenStructure) {
  88. if (verbose)
  89. dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure polymorphic because ", RawPointer(m_expectedStructure), " (", m_expectedStructure->classInfo()->className, ") != ", RawPointer(m_lastSeenStructure), " (", m_lastSeenStructure->classInfo()->className, ")\n");
  90. m_expectedStructure = polymorphicStructure();
  91. }
  92. }
  93. m_lastSeenStructure = 0;
  94. }
  95. if (hasTwoOrMoreBitsSet(m_observedArrayModes)) {
  96. if (verbose)
  97. dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure polymorphic because two or more bits are set in m_observedArrayModes\n");
  98. m_expectedStructure = polymorphicStructure();
  99. }
  100. if (operation == Collection
  101. && expectedStructure()
  102. && !Heap::isMarked(m_expectedStructure)) {
  103. if (verbose)
  104. dataLog(*codeBlock, " bc#", m_bytecodeOffset, ": making structure during GC\n");
  105. m_expectedStructure = polymorphicStructure();
  106. }
  107. }
  108. CString ArrayProfile::briefDescription(CodeBlock* codeBlock)
  109. {
  110. computeUpdatedPrediction(codeBlock);
  111. StringPrintStream out;
  112. bool hasPrinted = false;
  113. if (m_observedArrayModes) {
  114. if (hasPrinted)
  115. out.print(", ");
  116. out.print(ArrayModesDump(m_observedArrayModes));
  117. hasPrinted = true;
  118. }
  119. if (structureIsPolymorphic()) {
  120. if (hasPrinted)
  121. out.print(", ");
  122. out.print("struct = TOP");
  123. hasPrinted = true;
  124. } else if (m_expectedStructure) {
  125. if (hasPrinted)
  126. out.print(", ");
  127. out.print("struct = ", RawPointer(m_expectedStructure));
  128. hasPrinted = true;
  129. }
  130. if (m_mayStoreToHole) {
  131. if (hasPrinted)
  132. out.print(", ");
  133. out.print("Hole");
  134. hasPrinted = true;
  135. }
  136. if (m_outOfBounds) {
  137. if (hasPrinted)
  138. out.print(", ");
  139. out.print("OutOfBounds");
  140. hasPrinted = true;
  141. }
  142. if (m_mayInterceptIndexedAccesses) {
  143. if (hasPrinted)
  144. out.print(", ");
  145. out.print("Intercept");
  146. hasPrinted = true;
  147. }
  148. if (m_usesOriginalArrayStructures) {
  149. if (hasPrinted)
  150. out.print(", ");
  151. out.print("Original");
  152. hasPrinted = true;
  153. }
  154. UNUSED_PARAM(hasPrinted);
  155. return out.toCString();
  156. }
  157. } // namespace JSC