GCAwareJITStubRoutine.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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 "GCAwareJITStubRoutine.h"
  27. #if ENABLE(JIT)
  28. #include "Heap.h"
  29. #include "VM.h"
  30. #include "Operations.h"
  31. #include "SlotVisitor.h"
  32. #include "Structure.h"
  33. #if ENABLE(DETACHED_JIT)
  34. #include "ClosureCallStubRoutine.h"
  35. #endif
  36. namespace JSC {
  37. #if ENABLE(DETACHED_JIT)
  38. GCAwareJITStubRoutine::GCAwareJITStubRoutine(
  39. const MacroAssemblerCodeRef& code, VM& vm, GCAwareJITStubRoutineType type, bool isClosureCall)
  40. : JITStubRoutine(code, JITStubRoutine::e_GCAwareStubRoutineType)
  41. #else
  42. GCAwareJITStubRoutine::GCAwareJITStubRoutine(
  43. const MacroAssemblerCodeRef& code, VM& vm, bool isClosureCall)
  44. : JITStubRoutine(code)
  45. #endif
  46. , m_mayBeExecuting(false)
  47. , m_isJettisoned(false)
  48. , m_isClosureCall(isClosureCall)
  49. #if ENABLE(DETACHED_JIT)
  50. , m_gcAwareStubRoutineType(type)
  51. #endif
  52. {
  53. vm.heap.m_jitStubRoutines.add(this);
  54. }
  55. GCAwareJITStubRoutine::~GCAwareJITStubRoutine()
  56. {
  57. #if ENABLE(DETACHED_JIT)
  58. RELEASE_ASSERT(m_gcAwareStubRoutineType == e_GCAwareStubRoutineBaseType);
  59. RELEASE_ASSERT(m_stubRoutineType == e_GCAwareStubRoutineType);
  60. m_stubRoutineType = e_StubRoutineBaseType;
  61. #endif
  62. }
  63. #if ENABLE(DETACHED_JIT)
  64. void GCAwareJITStubRoutine::DETACHED_JIT_DTOR()
  65. {
  66. RELEASE_ASSERT(m_stubRoutineType == e_GCAwareStubRoutineType);
  67. switch (m_gcAwareStubRoutineType) {
  68. case e_MarkingGCAwareType:
  69. reinterpret_cast<MarkingGCAwareJITStubRoutineWithOneObject*>(this)->DETACHED_JIT_DTOR();
  70. break;
  71. case e_ClosureCallType:
  72. reinterpret_cast<ClosureCallStubRoutine*>(this)->DETACHED_JIT_DTOR();
  73. break;
  74. case e_GCAwareStubRoutineBaseType:
  75. delete this;
  76. break;
  77. case e_InvalidGCAwareType:
  78. ASSERT_NOT_REACHED();
  79. break;
  80. }
  81. }
  82. #endif
  83. void GCAwareJITStubRoutine::observeZeroRefCount()
  84. {
  85. if (m_isJettisoned) {
  86. // This case is needed for when the system shuts down. It may be that
  87. // the JIT stub routine set gets deleted before we get around to deleting
  88. // this guy. In that case the GC informs us that we're jettisoned already
  89. // and that we should delete ourselves as soon as the ref count reaches
  90. // zero.
  91. DETACHED_JIT_VIRTUAL_DELETE(this);
  92. return;
  93. }
  94. RELEASE_ASSERT(!m_refCount);
  95. m_isJettisoned = true;
  96. }
  97. void GCAwareJITStubRoutine::deleteFromGC()
  98. {
  99. ASSERT(m_isJettisoned);
  100. ASSERT(!m_refCount);
  101. ASSERT(!m_mayBeExecuting);
  102. DETACHED_JIT_VIRTUAL_DELETE(this);
  103. }
  104. #if !(ENABLE(DETACHED_JIT) && BUILDING_DETACHED_JIT)
  105. void GCAwareJITStubRoutine::markRequiredObjectsInternal(SlotVisitor& slot)
  106. {
  107. #if ENABLE(DETACHED_JIT)
  108. switch (m_gcAwareStubRoutineType) {
  109. case e_MarkingGCAwareType:
  110. reinterpret_cast<MarkingGCAwareJITStubRoutineWithOneObject*>(this)->markRequiredObjectsInternal(slot);
  111. break;
  112. case e_ClosureCallType:
  113. reinterpret_cast<ClosureCallStubRoutine*>(this)->markRequiredObjectsInternal(slot);
  114. break;
  115. case e_GCAwareStubRoutineBaseType:
  116. break;
  117. case e_InvalidGCAwareType:
  118. ASSERT_NOT_REACHED();
  119. break;
  120. }
  121. #endif
  122. }
  123. #endif
  124. MarkingGCAwareJITStubRoutineWithOneObject::MarkingGCAwareJITStubRoutineWithOneObject(
  125. const MacroAssemblerCodeRef& code, VM& vm, const JSCell* owner,
  126. JSCell* object)
  127. #if ENABLE(DETACHED_JIT)
  128. : GCAwareJITStubRoutine(code, vm, e_MarkingGCAwareType)
  129. #else
  130. : GCAwareJITStubRoutine(code, vm)
  131. #endif
  132. , m_object(vm, owner, object)
  133. {
  134. }
  135. MarkingGCAwareJITStubRoutineWithOneObject::~MarkingGCAwareJITStubRoutineWithOneObject()
  136. {
  137. #if ENABLE(DETACHED_JIT)
  138. RELEASE_ASSERT(m_gcAwareStubRoutineType == e_MarkingGCAwareType);
  139. m_gcAwareStubRoutineType = e_GCAwareStubRoutineBaseType;
  140. #endif
  141. }
  142. #if ENABLE(DETACHED_JIT)
  143. void MarkingGCAwareJITStubRoutineWithOneObject::DETACHED_JIT_DTOR()
  144. {
  145. RELEASE_ASSERT(m_gcAwareStubRoutineType == e_MarkingGCAwareType);
  146. delete this;
  147. }
  148. #endif
  149. #if !(ENABLE(DETACHED_JIT) && BUILDING_DETACHED_JIT)
  150. void MarkingGCAwareJITStubRoutineWithOneObject::markRequiredObjectsInternal(SlotVisitor& visitor)
  151. {
  152. visitor.append(&m_object);
  153. }
  154. #endif
  155. PassRefPtr<JITStubRoutine> createJITStubRoutine(
  156. const MacroAssemblerCodeRef& code,
  157. VM& vm,
  158. const JSCell*,
  159. bool makesCalls)
  160. {
  161. #if ENABLE(DETACHED_JIT)
  162. if (!makesCalls)
  163. return adoptRef(new JITStubRoutine(code, JITStubRoutine::e_StubRoutineBaseType));
  164. return static_pointer_cast<JITStubRoutine>(
  165. adoptRef(new GCAwareJITStubRoutine(code, vm, GCAwareJITStubRoutine::e_GCAwareStubRoutineBaseType)));
  166. #else
  167. if (!makesCalls)
  168. return adoptRef(new JITStubRoutine(code));
  169. return static_pointer_cast<JITStubRoutine>(
  170. adoptRef(new GCAwareJITStubRoutine(code, vm)));
  171. #endif
  172. }
  173. PassRefPtr<JITStubRoutine> createJITStubRoutine(
  174. const MacroAssemblerCodeRef& code,
  175. VM& vm,
  176. const JSCell* owner,
  177. bool makesCalls,
  178. JSCell* object)
  179. {
  180. #if ENABLE(DETACHED_JIT)
  181. if (!makesCalls)
  182. return adoptRef(new JITStubRoutine(code, JITStubRoutine::e_StubRoutineBaseType));
  183. #else
  184. if (!makesCalls)
  185. return adoptRef(new JITStubRoutine(code));
  186. #endif
  187. return static_pointer_cast<JITStubRoutine>(
  188. adoptRef(new MarkingGCAwareJITStubRoutineWithOneObject(code, vm, owner, object)));
  189. }
  190. } // namespace JSC
  191. #endif // ENABLE(JIT)