OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 5032 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5043 } | 5043 } |
5044 private: | 5044 private: |
5045 bool m_dummy; | 5045 bool m_dummy; |
5046 }; | 5046 }; |
5047 | 5047 |
5048 class ClassWithGarbageCollectingMixinConstructor | 5048 class ClassWithGarbageCollectingMixinConstructor |
5049 : public GarbageCollected<ClassWithGarbageCollectingMixinConstructor> | 5049 : public GarbageCollected<ClassWithGarbageCollectingMixinConstructor> |
5050 , public MixinWithGarbageCollectionInConstructor { | 5050 , public MixinWithGarbageCollectionInConstructor { |
5051 USING_GARBAGE_COLLECTED_MIXIN(ClassWithGarbageCollectingMixinConstructor); | 5051 USING_GARBAGE_COLLECTED_MIXIN(ClassWithGarbageCollectingMixinConstructor); |
5052 public: | 5052 public: |
5053 ClassWithGarbageCollectingMixinConstructor() : m_wrapper(IntWrapper::create(
32)) | 5053 static int s_traceCalled; |
| 5054 |
| 5055 ClassWithGarbageCollectingMixinConstructor() |
| 5056 : m_traceCounter(TraceCounter::create()) |
| 5057 , m_wrapper(IntWrapper::create(32)) |
5054 { | 5058 { |
5055 } | 5059 } |
5056 | 5060 |
5057 DEFINE_INLINE_VIRTUAL_TRACE() | 5061 DEFINE_INLINE_VIRTUAL_TRACE() |
5058 { | 5062 { |
| 5063 s_traceCalled++; |
| 5064 visitor->trace(m_traceCounter); |
5059 visitor->trace(m_wrapper); | 5065 visitor->trace(m_wrapper); |
5060 } | 5066 } |
5061 | 5067 |
5062 void verify() | 5068 void verify() |
5063 { | 5069 { |
5064 EXPECT_EQ(32, m_wrapper->value()); | 5070 EXPECT_EQ(32, m_wrapper->value()); |
| 5071 EXPECT_EQ(0, m_traceCounter->traceCount()); |
| 5072 EXPECT_EQ(0, s_traceCalled); |
5065 } | 5073 } |
5066 | 5074 |
5067 private: | 5075 private: |
| 5076 Member<TraceCounter> m_traceCounter; |
5068 Member<IntWrapper> m_wrapper; | 5077 Member<IntWrapper> m_wrapper; |
5069 }; | 5078 }; |
5070 | 5079 |
| 5080 int ClassWithGarbageCollectingMixinConstructor::s_traceCalled = 0; |
| 5081 |
5071 // Regression test for out of bounds call through vtable. | 5082 // Regression test for out of bounds call through vtable. |
5072 // Passes if it doesn't crash. | 5083 // Passes if it doesn't crash. |
5073 TEST(HeapTest, GarbageCollectionDuringMixinConstruction) | 5084 TEST(HeapTest, GarbageCollectionDuringMixinConstruction) |
5074 { | 5085 { |
5075 ClassWithGarbageCollectingMixinConstructor* a = | 5086 ClassWithGarbageCollectingMixinConstructor* a = |
5076 new ClassWithGarbageCollectingMixinConstructor(); | 5087 new ClassWithGarbageCollectingMixinConstructor(); |
5077 a->verify(); | 5088 a->verify(); |
5078 } | 5089 } |
5079 | 5090 |
5080 static RecursiveMutex& recursiveMutex() | 5091 static RecursiveMutex& recursiveMutex() |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5561 } // namespace | 5572 } // namespace |
5562 | 5573 |
5563 TEST(HeapTest, StackGrowthDirection) | 5574 TEST(HeapTest, StackGrowthDirection) |
5564 { | 5575 { |
5565 // The implementation of marking probes stack usage as it runs, | 5576 // The implementation of marking probes stack usage as it runs, |
5566 // and has a builtin assumption that the stack grows towards | 5577 // and has a builtin assumption that the stack grows towards |
5567 // lower addresses. | 5578 // lower addresses. |
5568 EXPECT_EQ(GrowsTowardsLower, stackGrowthDirection()); | 5579 EXPECT_EQ(GrowsTowardsLower, stackGrowthDirection()); |
5569 } | 5580 } |
5570 | 5581 |
| 5582 class TestMixinAllocationA : public GarbageCollected<TestMixinAllocationA>, publ
ic GarbageCollectedMixin { |
| 5583 USING_GARBAGE_COLLECTED_MIXIN(TestMixinAllocationA); |
| 5584 public: |
| 5585 TestMixinAllocationA() |
| 5586 { |
| 5587 // Completely wrong in general, but test only |
| 5588 // runs this constructor while constructing another mixin. |
| 5589 ASSERT(ThreadState::current()->isGCForbidden()); |
| 5590 } |
| 5591 |
| 5592 DEFINE_INLINE_VIRTUAL_TRACE() { } |
| 5593 }; |
| 5594 |
| 5595 class TestMixinAllocationB : public TestMixinAllocationA { |
| 5596 USING_GARBAGE_COLLECTED_MIXIN_NESTED(TestMixinAllocationB, TestMixinAllocati
onA); |
| 5597 public: |
| 5598 TestMixinAllocationB() |
| 5599 { |
| 5600 // Completely wrong in general, but test only |
| 5601 // runs this constructor while constructing another mixin. |
| 5602 ASSERT(ThreadState::current()->isGCForbidden()); |
| 5603 } |
| 5604 |
| 5605 DEFINE_INLINE_TRACE() { TestMixinAllocationA::trace(visitor); } |
| 5606 }; |
| 5607 |
| 5608 class TestMixinAllocationC final : public TestMixinAllocationB { |
| 5609 USING_GARBAGE_COLLECTED_MIXIN_NESTED(TestMixinAllocationC, TestMixinAllocati
onB); |
| 5610 public: |
| 5611 TestMixinAllocationC() |
| 5612 { |
| 5613 ASSERT(!ThreadState::current()->isGCForbidden()); |
| 5614 } |
| 5615 |
| 5616 DEFINE_INLINE_TRACE() { TestMixinAllocationB::trace(visitor); } |
| 5617 }; |
| 5618 |
| 5619 TEST(HeapTest, NestedMixinConstruction) |
| 5620 { |
| 5621 TestMixinAllocationC* object = new TestMixinAllocationC(); |
| 5622 EXPECT_TRUE(object); |
| 5623 } |
| 5624 |
| 5625 class ObjectWithLargeAmountsOfAllocationInConstructor { |
| 5626 public: |
| 5627 ObjectWithLargeAmountsOfAllocationInConstructor(size_t numberOfLargeObjectsT
oAllocate, ClassWithMember* member) |
| 5628 { |
| 5629 // Should a constructor allocate plenty in its constructor, |
| 5630 // and it is a base of GC mixin, GCs will remain locked out |
| 5631 // regardless, as we cannot safely trace the leftmost GC |
| 5632 // mixin base. |
| 5633 ASSERT(ThreadState::current()->isGCForbidden()); |
| 5634 for (size_t i = 0; i < numberOfLargeObjectsToAllocate; i++) { |
| 5635 LargeHeapObject* largeObject = LargeHeapObject::create(); |
| 5636 EXPECT_TRUE(largeObject); |
| 5637 EXPECT_EQ(0, member->traceCount()); |
| 5638 } |
| 5639 } |
| 5640 }; |
| 5641 |
| 5642 class TestMixinAllocatingObject final : public TestMixinAllocationB, public Obje
ctWithLargeAmountsOfAllocationInConstructor { |
| 5643 USING_GARBAGE_COLLECTED_MIXIN_NESTED(TestMixinAllocatingObject, TestMixinAll
ocationB); |
| 5644 public: |
| 5645 static TestMixinAllocatingObject* create(ClassWithMember* member) |
| 5646 { |
| 5647 return new TestMixinAllocatingObject(member); |
| 5648 } |
| 5649 |
| 5650 DEFINE_INLINE_TRACE() |
| 5651 { |
| 5652 visitor->trace(m_traceCounter); |
| 5653 TestMixinAllocationB::trace(visitor); |
| 5654 } |
| 5655 |
| 5656 int traceCount() const { return m_traceCounter->traceCount(); } |
| 5657 |
| 5658 private: |
| 5659 TestMixinAllocatingObject(ClassWithMember* member) |
| 5660 : ObjectWithLargeAmountsOfAllocationInConstructor(600, member) |
| 5661 , m_traceCounter(TraceCounter::create()) |
| 5662 { |
| 5663 ASSERT(!ThreadState::current()->isGCForbidden()); |
| 5664 // The large object allocation should trigger a GC.. |
| 5665 LargeHeapObject* largeObject = LargeHeapObject::create(); |
| 5666 EXPECT_TRUE(largeObject); |
| 5667 EXPECT_GT(member->traceCount(), 0); |
| 5668 EXPECT_GT(traceCount(), 0); |
| 5669 } |
| 5670 |
| 5671 Member<TraceCounter> m_traceCounter; |
| 5672 }; |
| 5673 |
| 5674 TEST(HeapTest, MixinConstructionNoGC) |
| 5675 { |
| 5676 Persistent<ClassWithMember> object = ClassWithMember::create(); |
| 5677 EXPECT_EQ(0, object->traceCount()); |
| 5678 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object.
get()); |
| 5679 EXPECT_TRUE(mixin); |
| 5680 EXPECT_GT(object->traceCount(), 0); |
| 5681 EXPECT_GT(mixin->traceCount(), 0); |
| 5682 } |
| 5683 |
5571 } // namespace blink | 5684 } // namespace blink |
OLD | NEW |