Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @ 187:790e66e5fbac
6687581: Make CMS work with compressed oops
Summary: Make FreeChunk read markword instead of LSB in _klass pointer to indicate that it's a FreeChunk for compressed oops.
Reviewed-by: ysr, jmasa
author | coleenp |
---|---|
date | Mon, 09 Jun 2008 11:51:19 -0400 |
parents | ba764ed4b6f2 |
children | d1605aabd0a1 12eea04c8b06 6aae2f9d0294 |
comparison
equal
deleted
inserted
replaced
185:8759d37f2524 | 187:790e66e5fbac |
---|---|
803 NOT_PRODUCT(verify_objects_initialized()); | 803 NOT_PRODUCT(verify_objects_initialized()); |
804 assert(MemRegion(bottom(), end()).contains(p), "p not in space"); | 804 assert(MemRegion(bottom(), end()).contains(p), "p not in space"); |
805 // This must be volatile, or else there is a danger that the compiler | 805 // This must be volatile, or else there is a danger that the compiler |
806 // will compile the code below into a sometimes-infinite loop, by keeping | 806 // will compile the code below into a sometimes-infinite loop, by keeping |
807 // the value read the first time in a register. | 807 // the value read the first time in a register. |
808 oop o = (oop)p; | |
809 volatile oop* second_word_addr = o->klass_addr(); | |
810 while (true) { | 808 while (true) { |
811 klassOop k = (klassOop)(*second_word_addr); | |
812 // We must do this until we get a consistent view of the object. | 809 // We must do this until we get a consistent view of the object. |
813 if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) { | 810 if (FreeChunk::indicatesFreeChunk(p)) { |
814 FreeChunk* fc = (FreeChunk*)p; | 811 volatile FreeChunk* fc = (volatile FreeChunk*)p; |
815 volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr()); | 812 size_t res = fc->size(); |
816 size_t res = (*sz_addr); | 813 // If the object is still a free chunk, return the size, else it |
817 klassOop k2 = (klassOop)(*second_word_addr); // Read to confirm. | 814 // has been allocated so try again. |
818 if (k == k2) { | 815 if (FreeChunk::indicatesFreeChunk(p)) { |
819 assert(res != 0, "Block size should not be 0"); | 816 assert(res != 0, "Block size should not be 0"); |
820 return res; | 817 return res; |
821 } | 818 } |
822 } else if (k != NULL) { | 819 } else { |
823 assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop."); | 820 // must read from what 'p' points to in each loop. |
824 assert(o->is_parsable(), "Should be parsable"); | 821 klassOop k = ((volatile oopDesc*)p)->klass_or_null(); |
825 assert(o->is_oop(true /* ignore mark word */), "Should be an oop."); | 822 if (k != NULL) { |
826 size_t res = o->size_given_klass(k->klass_part()); | 823 assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop."); |
827 res = adjustObjectSize(res); | 824 oop o = (oop)p; |
828 assert(res != 0, "Block size should not be 0"); | 825 assert(o->is_parsable(), "Should be parsable"); |
829 return res; | 826 assert(o->is_oop(true /* ignore mark word */), "Should be an oop."); |
827 size_t res = o->size_given_klass(k->klass_part()); | |
828 res = adjustObjectSize(res); | |
829 assert(res != 0, "Block size should not be 0"); | |
830 return res; | |
831 } | |
830 } | 832 } |
831 } | 833 } |
832 } | 834 } |
833 | 835 |
834 // A variant of the above that uses the Printezis bits for | 836 // A variant of the above that uses the Printezis bits for |
843 const { | 845 const { |
844 assert(MemRegion(bottom(), end()).contains(p), "p not in space"); | 846 assert(MemRegion(bottom(), end()).contains(p), "p not in space"); |
845 // This must be volatile, or else there is a danger that the compiler | 847 // This must be volatile, or else there is a danger that the compiler |
846 // will compile the code below into a sometimes-infinite loop, by keeping | 848 // will compile the code below into a sometimes-infinite loop, by keeping |
847 // the value read the first time in a register. | 849 // the value read the first time in a register. |
848 oop o = (oop)p; | |
849 volatile oop* second_word_addr = o->klass_addr(); | |
850 DEBUG_ONLY(uint loops = 0;) | 850 DEBUG_ONLY(uint loops = 0;) |
851 while (true) { | 851 while (true) { |
852 klassOop k = (klassOop)(*second_word_addr); | |
853 // We must do this until we get a consistent view of the object. | 852 // We must do this until we get a consistent view of the object. |
854 if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) { | 853 if (FreeChunk::indicatesFreeChunk(p)) { |
855 FreeChunk* fc = (FreeChunk*)p; | 854 volatile FreeChunk* fc = (volatile FreeChunk*)p; |
856 volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr()); | 855 size_t res = fc->size(); |
857 size_t res = (*sz_addr); | 856 if (FreeChunk::indicatesFreeChunk(p)) { |
858 klassOop k2 = (klassOop)(*second_word_addr); // Read to confirm. | |
859 if (k == k2) { | |
860 assert(res != 0, "Block size should not be 0"); | 857 assert(res != 0, "Block size should not be 0"); |
861 assert(loops == 0, "Should be 0"); | 858 assert(loops == 0, "Should be 0"); |
862 return res; | 859 return res; |
863 } | 860 } |
864 } else if (k != NULL && o->is_parsable()) { | |
865 assert(k->is_oop(), "Should really be klass oop."); | |
866 assert(o->is_oop(), "Should be an oop"); | |
867 size_t res = o->size_given_klass(k->klass_part()); | |
868 res = adjustObjectSize(res); | |
869 assert(res != 0, "Block size should not be 0"); | |
870 return res; | |
871 } else { | 861 } else { |
872 return c->block_size_if_printezis_bits(p); | 862 // must read from what 'p' points to in each loop. |
863 klassOop k = ((volatile oopDesc*)p)->klass_or_null(); | |
864 if (k != NULL && ((oopDesc*)p)->is_parsable()) { | |
865 assert(k->is_oop(), "Should really be klass oop."); | |
866 oop o = (oop)p; | |
867 assert(o->is_oop(), "Should be an oop"); | |
868 size_t res = o->size_given_klass(k->klass_part()); | |
869 res = adjustObjectSize(res); | |
870 assert(res != 0, "Block size should not be 0"); | |
871 return res; | |
872 } else { | |
873 return c->block_size_if_printezis_bits(p); | |
874 } | |
873 } | 875 } |
874 assert(loops == 0, "Can loop at most once"); | 876 assert(loops == 0, "Can loop at most once"); |
875 DEBUG_ONLY(loops++;) | 877 DEBUG_ONLY(loops++;) |
876 } | 878 } |
877 } | 879 } |
905 // (i.e., that the block start calculation may look at objects | 907 // (i.e., that the block start calculation may look at objects |
906 // at address below "p" in finding the object that contains "p" | 908 // at address below "p" in finding the object that contains "p" |
907 // and those objects (if garbage) may have been modified to hold | 909 // and those objects (if garbage) may have been modified to hold |
908 // live range information. | 910 // live range information. |
909 // assert(ParallelGCThreads > 0 || _bt.block_start(p) == p, "Should be a block boundary"); | 911 // assert(ParallelGCThreads > 0 || _bt.block_start(p) == p, "Should be a block boundary"); |
910 klassOop k = oop(p)->klass(); | 912 if (FreeChunk::indicatesFreeChunk(p)) return false; |
911 intptr_t ki = (intptr_t)k; | 913 klassOop k = oop(p)->klass_or_null(); |
912 if (FreeChunk::secondWordIndicatesFreeChunk(ki)) return false; | |
913 if (k != NULL) { | 914 if (k != NULL) { |
914 // Ignore mark word because it may have been used to | 915 // Ignore mark word because it may have been used to |
915 // chain together promoted objects (the last one | 916 // chain together promoted objects (the last one |
916 // would have a null value). | 917 // would have a null value). |
917 assert(oop(p)->is_oop(true), "Should be an oop"); | 918 assert(oop(p)->is_oop(true), "Should be an oop"); |
1025 assert(is_aligned((void*)res), "alignment check"); | 1026 assert(is_aligned((void*)res), "alignment check"); |
1026 | 1027 |
1027 FreeChunk* fc = (FreeChunk*)res; | 1028 FreeChunk* fc = (FreeChunk*)res; |
1028 fc->markNotFree(); | 1029 fc->markNotFree(); |
1029 assert(!fc->isFree(), "shouldn't be marked free"); | 1030 assert(!fc->isFree(), "shouldn't be marked free"); |
1030 assert(oop(fc)->klass() == NULL, "should look uninitialized"); | 1031 assert(oop(fc)->klass_or_null() == NULL, "should look uninitialized"); |
1031 // Verify that the block offset table shows this to | 1032 // Verify that the block offset table shows this to |
1032 // be a single block, but not one which is unallocated. | 1033 // be a single block, but not one which is unallocated. |
1033 _bt.verify_single_block(res, size); | 1034 _bt.verify_single_block(res, size); |
1034 _bt.verify_not_unallocated(res, size); | 1035 _bt.verify_not_unallocated(res, size); |
1035 // mangle a just allocated object with a distinct pattern. | 1036 // mangle a just allocated object with a distinct pattern. |
2591 res = fl->getChunkAtHead(); | 2592 res = fl->getChunkAtHead(); |
2592 assert(res != NULL, "Why was count non-zero?"); | 2593 assert(res != NULL, "Why was count non-zero?"); |
2593 } | 2594 } |
2594 res->markNotFree(); | 2595 res->markNotFree(); |
2595 assert(!res->isFree(), "shouldn't be marked free"); | 2596 assert(!res->isFree(), "shouldn't be marked free"); |
2596 assert(oop(res)->klass() == NULL, "should look uninitialized"); | 2597 assert(oop(res)->klass_or_null() == NULL, "should look uninitialized"); |
2597 // mangle a just allocated object with a distinct pattern. | 2598 // mangle a just allocated object with a distinct pattern. |
2598 debug_only(res->mangleAllocated(word_sz)); | 2599 debug_only(res->mangleAllocated(word_sz)); |
2599 return (HeapWord*)res; | 2600 return (HeapWord*)res; |
2600 } | 2601 } |
2601 | 2602 |