HandleSet.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (C) 2011 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. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "HandleSet.h"
  27. #include "HandleBlock.h"
  28. #include "HandleBlockInlines.h"
  29. #include "HeapRootVisitor.h"
  30. #include "JSObject.h"
  31. #include "Operations.h"
  32. #include <wtf/DataLog.h>
  33. namespace JSC {
  34. HandleSet::HandleSet(VM* vm)
  35. : m_vm(vm)
  36. , m_nextToFinalize(0)
  37. {
  38. grow();
  39. }
  40. HandleSet::~HandleSet()
  41. {
  42. while (!m_blockList.isEmpty())
  43. m_vm->heap.blockAllocator().deallocate(HandleBlock::destroy(m_blockList.removeHead()));
  44. }
  45. void HandleSet::grow()
  46. {
  47. HandleBlock* newBlock = HandleBlock::create(m_vm->heap.blockAllocator().allocate<HandleBlock>(), this);
  48. m_blockList.append(newBlock);
  49. for (int i = newBlock->nodeCapacity() - 1; i >= 0; --i) {
  50. Node* node = newBlock->nodeAtIndex(i);
  51. new (NotNull, node) Node;
  52. m_freeList.push(node);
  53. }
  54. }
  55. void HandleSet::visitStrongHandles(HeapRootVisitor& heapRootVisitor)
  56. {
  57. Node* end = m_strongList.end();
  58. for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
  59. #if ENABLE(GC_VALIDATION)
  60. RELEASE_ASSERT(isLiveNode(node));
  61. #endif
  62. heapRootVisitor.visit(node->slot());
  63. }
  64. }
  65. void HandleSet::writeBarrier(HandleSlot slot, const JSValue& value)
  66. {
  67. // Forbid assignment to handles during the finalization phase, since it would violate many GC invariants.
  68. // File a bug with stack trace if you hit this.
  69. RELEASE_ASSERT(!m_nextToFinalize);
  70. if (!value == !*slot && slot->isCell() == value.isCell())
  71. return;
  72. Node* node = toNode(slot);
  73. #if ENABLE(GC_VALIDATION)
  74. RELEASE_ASSERT(isLiveNode(node));
  75. #endif
  76. SentinelLinkedList<Node>::remove(node);
  77. if (!value || !value.isCell()) {
  78. m_immediateList.push(node);
  79. return;
  80. }
  81. m_strongList.push(node);
  82. #if ENABLE(GC_VALIDATION)
  83. RELEASE_ASSERT(isLiveNode(node));
  84. #endif
  85. }
  86. unsigned HandleSet::protectedGlobalObjectCount()
  87. {
  88. unsigned count = 0;
  89. Node* end = m_strongList.end();
  90. for (Node* node = m_strongList.begin(); node != end; node = node->next()) {
  91. JSValue value = *node->slot();
  92. if (value.isObject() && asObject(value.asCell())->isGlobalObject())
  93. count++;
  94. }
  95. return count;
  96. }
  97. #if ENABLE(GC_VALIDATION) || !ASSERT_DISABLED
  98. bool HandleSet::isLiveNode(Node* node)
  99. {
  100. if (node->prev()->next() != node)
  101. return false;
  102. if (node->next()->prev() != node)
  103. return false;
  104. return true;
  105. }
  106. #endif
  107. } // namespace JSC