Mercurial > hg > truffle
comparison src/share/vm/memory/metaspace.cpp @ 14211:a2a3f08b96fa
8029106: JVM crashes in Metachunk::Metachunk during parallel class redefinition (PrivateMLetController, anonymous-simple_copy_1)
Summary: Fixed overflow bug in VirtualSpaceNode::is_available
Reviewed-by: mgerdin, brutisso, coleenp, jmasa
author | stefank |
---|---|
date | Mon, 09 Dec 2013 10:03:39 +0100 |
parents | 11b116661830 |
children | db1ff6781ab4 40353abd7984 |
comparison
equal
deleted
inserted
replaced
14210:397385cc2c83 | 14211:a2a3f08b96fa |
---|---|
285 // Accessors | 285 // Accessors |
286 MemRegion* reserved() { return &_reserved; } | 286 MemRegion* reserved() { return &_reserved; } |
287 VirtualSpace* virtual_space() const { return (VirtualSpace*) &_virtual_space; } | 287 VirtualSpace* virtual_space() const { return (VirtualSpace*) &_virtual_space; } |
288 | 288 |
289 // Returns true if "word_size" is available in the VirtualSpace | 289 // Returns true if "word_size" is available in the VirtualSpace |
290 bool is_available(size_t word_size) { return _top + word_size <= end(); } | 290 bool is_available(size_t word_size) { return word_size <= pointer_delta(end(), _top, sizeof(MetaWord)); } |
291 | 291 |
292 MetaWord* top() const { return _top; } | 292 MetaWord* top() const { return _top; } |
293 void inc_top(size_t word_size) { _top += word_size; } | 293 void inc_top(size_t word_size) { _top += word_size; } |
294 | 294 |
295 uintx container_count() { return _container_count; } | 295 uintx container_count() { return _container_count; } |
3639 assert(cm.sum_free_chunks_count() == (num_small_chunks + num_spec_chunks), "should be space for 3 chunks"); | 3639 assert(cm.sum_free_chunks_count() == (num_small_chunks + num_spec_chunks), "should be space for 3 chunks"); |
3640 assert(cm.sum_free_chunks() == words_left, "sizes should add up"); | 3640 assert(cm.sum_free_chunks() == words_left, "sizes should add up"); |
3641 } | 3641 } |
3642 | 3642 |
3643 } | 3643 } |
3644 | |
3645 #define assert_is_available_positive(word_size) \ | |
3646 assert(vsn.is_available(word_size), \ | |
3647 err_msg(#word_size ": " PTR_FORMAT " bytes were not available in " \ | |
3648 "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \ | |
3649 (uintptr_t)(word_size * BytesPerWord), vsn.bottom(), vsn.end())); | |
3650 | |
3651 #define assert_is_available_negative(word_size) \ | |
3652 assert(!vsn.is_available(word_size), \ | |
3653 err_msg(#word_size ": " PTR_FORMAT " bytes should not be available in " \ | |
3654 "VirtualSpaceNode [" PTR_FORMAT ", " PTR_FORMAT ")", \ | |
3655 (uintptr_t)(word_size * BytesPerWord), vsn.bottom(), vsn.end())); | |
3656 | |
3657 static void test_is_available_positive() { | |
3658 // Reserve some memory. | |
3659 VirtualSpaceNode vsn(os::vm_allocation_granularity()); | |
3660 assert(vsn.initialize(), "Failed to setup VirtualSpaceNode"); | |
3661 | |
3662 // Commit some memory. | |
3663 size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord; | |
3664 bool expanded = vsn.expand_by(commit_word_size, commit_word_size); | |
3665 assert(expanded, "Failed to commit"); | |
3666 | |
3667 // Check that is_available accepts the committed size. | |
3668 assert_is_available_positive(commit_word_size); | |
3669 | |
3670 // Check that is_available accepts half the committed size. | |
3671 size_t expand_word_size = commit_word_size / 2; | |
3672 assert_is_available_positive(expand_word_size); | |
3673 } | |
3674 | |
3675 static void test_is_available_negative() { | |
3676 // Reserve some memory. | |
3677 VirtualSpaceNode vsn(os::vm_allocation_granularity()); | |
3678 assert(vsn.initialize(), "Failed to setup VirtualSpaceNode"); | |
3679 | |
3680 // Commit some memory. | |
3681 size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord; | |
3682 bool expanded = vsn.expand_by(commit_word_size, commit_word_size); | |
3683 assert(expanded, "Failed to commit"); | |
3684 | |
3685 // Check that is_available doesn't accept a too large size. | |
3686 size_t two_times_commit_word_size = commit_word_size * 2; | |
3687 assert_is_available_negative(two_times_commit_word_size); | |
3688 } | |
3689 | |
3690 static void test_is_available_overflow() { | |
3691 // Reserve some memory. | |
3692 VirtualSpaceNode vsn(os::vm_allocation_granularity()); | |
3693 assert(vsn.initialize(), "Failed to setup VirtualSpaceNode"); | |
3694 | |
3695 // Commit some memory. | |
3696 size_t commit_word_size = os::vm_allocation_granularity() / BytesPerWord; | |
3697 bool expanded = vsn.expand_by(commit_word_size, commit_word_size); | |
3698 assert(expanded, "Failed to commit"); | |
3699 | |
3700 // Calculate a size that will overflow the virtual space size. | |
3701 void* virtual_space_max = (void*)(uintptr_t)-1; | |
3702 size_t bottom_to_max = pointer_delta(virtual_space_max, vsn.bottom(), 1); | |
3703 size_t overflow_size = bottom_to_max + BytesPerWord; | |
3704 size_t overflow_word_size = overflow_size / BytesPerWord; | |
3705 | |
3706 // Check that is_available can handle the overflow. | |
3707 assert_is_available_negative(overflow_word_size); | |
3708 } | |
3709 | |
3710 static void test_is_available() { | |
3711 TestVirtualSpaceNodeTest::test_is_available_positive(); | |
3712 TestVirtualSpaceNodeTest::test_is_available_negative(); | |
3713 TestVirtualSpaceNodeTest::test_is_available_overflow(); | |
3714 } | |
3644 }; | 3715 }; |
3645 | 3716 |
3646 void TestVirtualSpaceNode_test() { | 3717 void TestVirtualSpaceNode_test() { |
3647 TestVirtualSpaceNodeTest::test(); | 3718 TestVirtualSpaceNodeTest::test(); |
3719 TestVirtualSpaceNodeTest::test_is_available(); | |
3648 } | 3720 } |
3649 | 3721 |
3650 #endif | 3722 #endif |