DFGArrayifySlowPathGenerator.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (C) 2012, 2013 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. #ifndef DFGArrayifySlowPathGenerator_h
  26. #define DFGArrayifySlowPathGenerator_h
  27. #include <wtf/Platform.h>
  28. #if ENABLE(DFG_JIT)
  29. #include "DFGArrayMode.h"
  30. #include "DFGCommon.h"
  31. #include "DFGOSRExitJumpPlaceholder.h"
  32. #include "DFGOperations.h"
  33. #include "DFGSlowPathGenerator.h"
  34. #include "DFGSpeculativeJIT.h"
  35. #include <wtf/Vector.h>
  36. namespace JSC { namespace DFG {
  37. class ArrayifySlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::JumpList> {
  38. public:
  39. ArrayifySlowPathGenerator(
  40. const MacroAssembler::JumpList& from, SpeculativeJIT* jit, Node* node, GPRReg baseGPR,
  41. GPRReg propertyGPR, GPRReg tempGPR, GPRReg structureGPR)
  42. : JumpingSlowPathGenerator<MacroAssembler::JumpList>(from, jit)
  43. , m_op(node->op())
  44. , m_arrayMode(node->arrayMode())
  45. , m_structure(node->op() == ArrayifyToStructure ? node->structure() : 0)
  46. , m_baseGPR(baseGPR)
  47. , m_propertyGPR(propertyGPR)
  48. , m_tempGPR(tempGPR)
  49. , m_structureGPR(structureGPR)
  50. {
  51. ASSERT(m_op == Arrayify || m_op == ArrayifyToStructure);
  52. jit->silentSpillAllRegistersImpl(false, m_plans, InvalidGPRReg);
  53. if (m_propertyGPR != InvalidGPRReg) {
  54. switch (m_arrayMode.type()) {
  55. case Array::Int32:
  56. case Array::Double:
  57. case Array::Contiguous:
  58. m_badPropertyJump = jit->backwardSpeculationCheck(Uncountable, JSValueRegs(), 0);
  59. break;
  60. default:
  61. break;
  62. }
  63. }
  64. m_badIndexingTypeJump = jit->backwardSpeculationCheck(BadIndexingType, JSValueSource::unboxedCell(m_baseGPR), 0);
  65. }
  66. protected:
  67. void generateInternal(SpeculativeJIT* jit)
  68. {
  69. linkFrom(jit);
  70. ASSERT(m_op == Arrayify || m_op == ArrayifyToStructure);
  71. if (m_propertyGPR != InvalidGPRReg) {
  72. switch (m_arrayMode.type()) {
  73. case Array::Int32:
  74. case Array::Double:
  75. case Array::Contiguous:
  76. m_badPropertyJump.fill(jit, jit->m_jit.branch32(
  77. MacroAssembler::AboveOrEqual, m_propertyGPR,
  78. MacroAssembler::TrustedImm32(MIN_SPARSE_ARRAY_INDEX)));
  79. break;
  80. default:
  81. break;
  82. }
  83. }
  84. for (unsigned i = 0; i < m_plans.size(); ++i)
  85. jit->silentSpill(m_plans[i]);
  86. switch (m_arrayMode.type()) {
  87. case Array::Int32:
  88. jit->callOperation(operationEnsureInt32, m_tempGPR, m_baseGPR);
  89. break;
  90. case Array::Double:
  91. jit->callOperation(operationEnsureDouble, m_tempGPR, m_baseGPR);
  92. break;
  93. case Array::Contiguous:
  94. if (m_arrayMode.conversion() == Array::RageConvert)
  95. jit->callOperation(operationRageEnsureContiguous, m_tempGPR, m_baseGPR);
  96. else
  97. jit->callOperation(operationEnsureContiguous, m_tempGPR, m_baseGPR);
  98. break;
  99. case Array::ArrayStorage:
  100. case Array::SlowPutArrayStorage:
  101. jit->callOperation(operationEnsureArrayStorage, m_tempGPR, m_baseGPR);
  102. break;
  103. default:
  104. CRASH();
  105. break;
  106. }
  107. for (unsigned i = m_plans.size(); i--;)
  108. jit->silentFill(m_plans[i], GPRInfo::regT0);
  109. if (m_op == ArrayifyToStructure) {
  110. ASSERT(m_structure);
  111. m_badIndexingTypeJump.fill(
  112. jit, jit->m_jit.branchWeakPtr(
  113. MacroAssembler::NotEqual,
  114. MacroAssembler::Address(m_baseGPR, JSCell::structureOffset()),
  115. m_structure));
  116. } else {
  117. // Alas, we need to reload the structure because silent spilling does not save
  118. // temporaries. Nor would it be useful for it to do so. Either way we're talking
  119. // about a load.
  120. jit->m_jit.loadPtr(
  121. MacroAssembler::Address(m_baseGPR, JSCell::structureOffset()), m_structureGPR);
  122. // Finally, check that we have the kind of array storage that we wanted to get.
  123. // Note that this is a backwards speculation check, which will result in the
  124. // bytecode operation corresponding to this arrayification being reexecuted.
  125. // That's fine, since arrayification is not user-visible.
  126. jit->m_jit.load8(
  127. MacroAssembler::Address(m_structureGPR, Structure::indexingTypeOffset()), m_structureGPR);
  128. m_badIndexingTypeJump.fill(
  129. jit, jit->jumpSlowForUnwantedArrayMode(m_structureGPR, m_arrayMode));
  130. }
  131. jumpTo(jit);
  132. }
  133. private:
  134. NodeType m_op;
  135. ArrayMode m_arrayMode;
  136. Structure* m_structure;
  137. GPRReg m_baseGPR;
  138. GPRReg m_propertyGPR;
  139. GPRReg m_tempGPR;
  140. GPRReg m_structureGPR;
  141. OSRExitJumpPlaceholder m_badPropertyJump;
  142. OSRExitJumpPlaceholder m_badIndexingTypeJump;
  143. Vector<SilentRegisterSavePlan, 2> m_plans;
  144. };
  145. } } // namespace JSC::DFG
  146. #endif // ENABLE(DFG_JIT)
  147. #endif // DFGArrayifySlowPathGenerator_h