comparison src/share/vm/memory/metaspace.cpp @ 13439:fa76dce60db7

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
13438:ad72068ac41e 13439:fa76dce60db7
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