You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by xl...@apache.org on 2007/04/20 16:45:59 UTC

svn commit: r530829 - in /harmony/enhanced/drlvm/trunk/vm/gc_gen/src: common/ gen/ mark_compact/ mark_sweep/ thread/ trace_forward/ utils/

Author: xli
Date: Fri Apr 20 07:45:58 2007
New Revision: 530829

URL: http://svn.apache.org/viewvc?view=rev&rev=530829
Log:
HARMONY-3700 : [DRLVM][GC] fix a LOS (large object space) adaptation bug

Modified:
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp
    harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/gc_common.cpp Fri Apr 20 07:45:58 2007
@@ -246,6 +246,11 @@
   return;
 }
 
+void gc_assign_free_area_to_mutators(GC* gc)
+{
+  gc_gen_assign_free_area_to_mutators((GC_Gen*)gc);
+}
+
 void gc_copy_interior_pointer_table_to_rootset();
 
 void gc_reclaim_heap(GC* gc, unsigned int gc_cause)
@@ -314,6 +319,8 @@
 
   //For_LOS_extend!
   gc_space_tuner_reset(gc);
+  
+  gc_assign_free_area_to_mutators(gc);
   
   vm_resume_threads_after();
   return;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/common/space_tuner.cpp Fri Apr 20 07:45:58 2007
@@ -94,7 +94,7 @@
   if((tuner->need_tune) && (!tuner->force_tune)) goto check_size;
   /*tuner->force_tune must be true here!*/
   los_fail_sz_uped = lspace_get_failure_size((Lspace*)lspace);
-  assert(!(los_fail_sz_uped % GC_BLOCK_SIZE_BYTES));
+  assert(!(los_fail_sz_uped % KB));
 
   if(tuner->kind == TRANS_FROM_LOS_TO_MOS){
     tuner->kind = TRANS_FROM_MOS_TO_LOS;
@@ -269,7 +269,7 @@
       return TRUE;
     }
     /*force tune here!*/
-    POINTER_SIZE_INT min_tuning_uped = los->failure_size;
+    POINTER_SIZE_INT min_tuning_uped = round_up_to_size(los->failure_size, GC_BLOCK_SIZE_BYTES);
     if(min_tuning_uped > max_free_for_tuning){
       tuner->tuning_size = 0;
       tuner->kind = TRANS_NOTHING;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.cpp Fri Apr 20 07:45:58 2007
@@ -245,15 +245,19 @@
   return;  
 }
 
-void* mos_alloc(unsigned size, Allocator *allocator){return mspace_alloc(size, allocator);}
-void* nos_alloc(unsigned size, Allocator *allocator){return fspace_alloc(size, allocator);}
-void* los_alloc(unsigned size, Allocator *allocator){return lspace_alloc(size, allocator);}
 Space* gc_get_nos(GC_Gen* gc){ return (Space*)gc->nos;}
 Space* gc_get_mos(GC_Gen* gc){ return (Space*)gc->mos;}
 Space* gc_get_los(GC_Gen* gc){ return (Space*)gc->los;}
 void gc_set_nos(GC_Gen* gc, Space* nos){ gc->nos = (Fspace*)nos;}
 void gc_set_mos(GC_Gen* gc, Space* mos){ gc->mos = (Mspace*)mos;}
 void gc_set_los(GC_Gen* gc, Space* los){ gc->los = (Lspace*)los;}
+
+void* mos_alloc(unsigned size, Allocator *allocator){return mspace_alloc(size, allocator);}
+void* nos_alloc(unsigned size, Allocator *allocator){return fspace_alloc(size, allocator);}
+void* los_alloc(unsigned size, Allocator *allocator){return lspace_alloc(size, allocator);}
+void* los_try_alloc(POINTER_SIZE_INT size, GC* gc){  return lspace_try_alloc((Lspace*)((GC_Gen*)gc)->los, size); }
+
+
 unsigned int gc_get_processor_num(GC_Gen* gc){ return gc->_num_processors;}
 
 
@@ -320,6 +324,25 @@
   
   return;
   
+}
+
+void gc_gen_assign_free_area_to_mutators(GC_Gen* gc)
+{
+  if(gc->cause == GC_CAUSE_LOS_IS_FULL){
+    Lspace* los = gc->los;
+    los->success_ptr = los_try_alloc(los->failure_size, (GC*)gc);      
+    los->failure_size = 0;
+     
+  }else{ 
+    Blocked_Space* nos = (Blocked_Space*)gc->nos;
+    if(nos->num_managed_blocks == 0) return;
+
+    Mutator *mutator = (Mutator *)gc_get_tls();   
+    allocator_init_free_block((Allocator*)mutator, (Block_Header*)nos->blocks);
+    nos->free_block_idx++;
+  }
+    
+  return;     
 }
 
 Boolean IS_FALLBACK_COMPACTION = FALSE; /* only for debugging, don't use it. */

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen.h Fri Apr 20 07:45:58 2007
@@ -150,12 +150,15 @@
 void* mos_alloc(unsigned size, Allocator *allocator);
 void* nos_alloc(unsigned size, Allocator *allocator);
 void* los_alloc(unsigned size, Allocator *allocator);
+void* los_try_alloc(POINTER_SIZE_INT size, GC* gc);
+
 Space* gc_get_nos(GC_Gen* gc);
 Space* gc_get_mos(GC_Gen* gc);
 Space* gc_get_los(GC_Gen* gc);
 void gc_set_nos(GC_Gen* gc, Space* nos);
 void gc_set_mos(GC_Gen* gc, Space* mos);
 void gc_set_los(GC_Gen* gc, Space* los);
+
 unsigned int gc_get_processor_num(GC_Gen* gc);
 
 void gc_decide_collection_algorithm(GC_Gen* gc, char* minor_algo, char* major_algo);
@@ -165,6 +168,8 @@
 
 void gc_gen_reclaim_heap(GC_Gen* gc);
 
+void gc_gen_assign_free_area_to_mutators(GC_Gen* gc);
+  
 void gc_gen_mode_adapt_init(GC_Gen *gc);
 
 void gc_gen_iterate_heap(GC_Gen *gc);

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/gen/gen_adapt.cpp Fri Apr 20 07:45:58 2007
@@ -272,10 +272,6 @@
   }
 
   gc_gen_mode_adapt(gc,pause_time);
-  /* a heuristic: when no free block at all after this collection, we can't  
-     do any allocation at all. The first allocation will trigger a major collection */
-  if( fspace->num_managed_blocks == 0 )
-     gc->force_major_collect = TRUE;
 
   return;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_alloc.cpp Fri Apr 20 07:45:58 2007
@@ -36,31 +36,9 @@
     }
     /* ok, got one */
     Block_Header* alloc_block = (Block_Header*)&(mspace->blocks[allocated_idx - mspace->first_block_idx]);
-    assert(alloc_block->status == BLOCK_FREE);
-    alloc_block->status = BLOCK_IN_USE;
-    /*For_statistic mos allocation infomation*/
     mspace->alloced_size += GC_BLOCK_SIZE_BYTES;
-    
-    /* set allocation context */
-    void* new_free = alloc_block->free;
-    allocator->free = new_free;
 
-#ifndef ALLOC_ZEROING
-
-    allocator->ceiling = alloc_block->ceiling;
-    memset(new_free, 0, GC_BLOCK_BODY_SIZE_BYTES);
-
-#else
-
-    /* the first-time zeroing area includes block header, to make subsequent allocs page aligned */
-    unsigned int zeroing_size = ZEROING_SIZE - GC_BLOCK_HEADER_SIZE_BYTES;
-    allocator->ceiling = (void*)((POINTER_SIZE_INT)new_free + zeroing_size);
-    memset(new_free, 0, zeroing_size);
-
-#endif /* #ifndef ALLOC_ZEROING */
-
-    allocator->end = alloc_block->ceiling;
-    allocator->alloc_block = (Block*)alloc_block; 
+    allocator_init_free_block(allocator, alloc_block);
     
     return TRUE;
   }

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_compact/mspace_slide_compact.cpp Fri Apr 20 07:45:58 2007
@@ -141,8 +141,10 @@
   if(block->status != BLOCK_DEST)
     return block;
   
-  while(block->status == BLOCK_DEST)
+  while(block->status == BLOCK_DEST) {
     block = block->next;
+    if(!block) break;
+  }
   next_block_for_dest = block;
   return block;
 }

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace.h Fri Apr 20 07:45:58 2007
@@ -52,8 +52,13 @@
   /* END of Space --> */
 
   Free_Area_Pool* free_pool;
-  /*Size of allocation which caused lspace alloc failure.*/
+  /*Size of allocation which caused lspace alloc failure.
+   *This one is used to assign area to failed collection inside gc.
+   *Resetted in every gc_assign_free_area_to_mutators
+   */
   POINTER_SIZE_INT failure_size;
+  void* success_ptr;
+  
   void* scompact_fa_start;
   void* scompact_fa_end;
 }Lspace;
@@ -61,6 +66,7 @@
 void lspace_initialize(GC* gc, void* reserved_base, POINTER_SIZE_INT lspace_size);
 void lspace_destruct(Lspace* lspace);
 Managed_Object_Handle lspace_alloc(POINTER_SIZE_INT size, Allocator* allocator);
+void* lspace_try_alloc(Lspace* lspace, POINTER_SIZE_INT alloc_size);
 void lspace_sliding_compact(Collector* collector, Lspace* lspace);
 void lspace_compute_object_target(Collector* collector, Lspace* lspace);
 void lspace_sweep(Lspace* lspace);
@@ -78,6 +84,7 @@
     while(!reach_heap_end){
         //FIXME: This while shoudl be if, try it!
         while(!*((POINTER_SIZE_INT*)next_area_start)){
+            assert(((Free_Area*)next_area_start)->size);
             next_area_start += ((Free_Area*)next_area_start)->size;
         }
         if(next_area_start < (POINTER_SIZE_INT)lspace->heap_end){

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/mark_sweep/lspace_alloc_collect.cpp Fri Apr 20 07:45:58 2007
@@ -148,59 +148,82 @@
     return NULL;
 }
 
+void* lspace_try_alloc(Lspace* lspace, POINTER_SIZE_INT alloc_size){
+  void* p_result = NULL;
+  Free_Area_Pool* pool = lspace->free_pool;  
+  unsigned int list_hint = pool_list_index_with_size(alloc_size);  
+  list_hint = pool_list_get_next_flag(pool, list_hint);  
+
+  while((!p_result) && (list_hint <= MAX_LIST_INDEX)){
+      /*List hint is not the last list, so look for it in former lists.*/
+      if(list_hint < MAX_LIST_INDEX){
+          p_result = free_pool_former_lists_atomic_take_area_piece(pool, list_hint, alloc_size);
+          if(p_result){
+              memset(p_result, 0, alloc_size);
+              POINTER_SIZE_INT vold = lspace->alloced_size;
+              POINTER_SIZE_INT vnew = vold + alloc_size;
+              while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){                      
+                  vold = lspace->alloced_size;
+                  vnew = vold + alloc_size;
+              }
+              return p_result;
+          }else{
+              list_hint ++;
+              list_hint = pool_list_get_next_flag(pool, list_hint);
+              continue;
+          }
+      }
+      /*List hint is the last list, so look for it in the last list.*/
+      else
+      {
+          p_result = free_pool_last_list_atomic_take_area_piece(pool, alloc_size);
+          if(p_result){
+              memset(p_result, 0, alloc_size);
+              POINTER_SIZE_INT vold = lspace->alloced_size;
+              POINTER_SIZE_INT vnew = vold + alloc_size;
+              while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){                      
+                  vold = lspace->alloced_size;
+                  vnew = vold + alloc_size;
+              }
+              return p_result;
+          }
+          else break;
+      }
+  }
+  return p_result;
+}
+
 void* lspace_alloc(POINTER_SIZE_INT size, Allocator *allocator)
 {
     unsigned int try_count = 0;
     void* p_result = NULL;
-    unsigned int  list_hint = 0;
     POINTER_SIZE_INT alloc_size = ALIGN_UP_TO_KILO(size);
     Lspace* lspace = (Lspace*)gc_get_los((GC_Gen*)allocator->gc);
     Free_Area_Pool* pool = lspace->free_pool;
-
+    
     while( try_count < 2 ){
-        list_hint = pool_list_index_with_size(alloc_size);
-        list_hint = pool_list_get_next_flag(pool, list_hint);
-        while((!p_result) && (list_hint <= MAX_LIST_INDEX)){
-            /*List hint is not the last list, so look for it in former lists.*/
-            if(list_hint < MAX_LIST_INDEX){
-                p_result = free_pool_former_lists_atomic_take_area_piece(pool, list_hint, alloc_size);
-                if(p_result){
-                    memset(p_result, 0, size);
-                    POINTER_SIZE_INT vold = lspace->alloced_size;
-                    POINTER_SIZE_INT vnew = vold + alloc_size;
-                    while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){                      
-                        vold = lspace->alloced_size;
-                        vnew = vold + alloc_size;
-                    }
-                    return p_result;
-                }else{
-                    list_hint ++;
-                    list_hint = pool_list_get_next_flag(pool, list_hint);
-                    continue;
-                }
-            }
-            /*List hint is the last list, so look for it in the last list.*/
-            else
-            {
-                p_result = free_pool_last_list_atomic_take_area_piece(pool, alloc_size);
-                if(p_result){
-                    memset(p_result, 0, size);
-                    POINTER_SIZE_INT vold = lspace->alloced_size;
-                    POINTER_SIZE_INT vnew = vold + alloc_size;
-                    while( vold != atomic_casptrsz(&lspace->alloced_size, vnew, vold) ){                      
-                        vold = lspace->alloced_size;
-                        vnew = vold + alloc_size;
-                    }
-                    return p_result;
-                }
-                else break;
-            }
-        }
+        if(p_result = lspace_try_alloc(lspace, alloc_size))
+          return p_result;
+
         /*Failled, no adequate area found in all lists, so GC at first, then get another try.*/   
         if(try_count == 0){
             vm_gc_lock_enum();
-            lspace->failure_size = round_up_to_size(alloc_size, GC_BLOCK_SIZE_BYTES);
+            /*Check again if there is space for the obj, for maybe other mutator 
+            threads issus a GC in the time gap of waiting the gc lock*/
+            if(p_result = lspace_try_alloc(lspace, alloc_size)){
+              vm_gc_unlock_enum();
+              return p_result;            
+            }
+            lspace->failure_size = round_up_to_size(alloc_size, KB);
+
             gc_reclaim_heap(allocator->gc, GC_CAUSE_LOS_IS_FULL);
+
+            if(lspace->success_ptr){
+              p_result = lspace->success_ptr;
+              lspace->success_ptr = NULL;
+              vm_gc_unlock_enum();
+              return p_result;
+            }
             vm_gc_unlock_enum();
             try_count ++;
         }else{
@@ -327,7 +350,6 @@
 
     /*For_statistic los information.*/
     lspace->alloced_size = 0;    
-    lspace->failure_size = 0;
     lspace->surviving_size = 0;
 
     los_boundary = lspace->heap_end;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/thread/gc_thread.h Fri Apr 20 07:45:58 2007
@@ -110,6 +110,34 @@
 
 }
 
+inline void allocator_init_free_block(Allocator* allocator, Block_Header* alloc_block)
+{
+    assert(alloc_block->status == BLOCK_FREE);
+    alloc_block->status = BLOCK_IN_USE;
+    
+    /* set allocation context */
+    void* new_free = alloc_block->free;
+    allocator->free = new_free;
+
+#ifndef ALLOC_ZEROING
+
+    allocator->ceiling = alloc_block->ceiling;
+    memset(new_free, 0, GC_BLOCK_BODY_SIZE_BYTES);
+
+#else
+    /* the first-time zeroing area includes block header, to make subsequent allocs page aligned */
+    unsigned int zeroing_size = ZEROING_SIZE - GC_BLOCK_HEADER_SIZE_BYTES;
+    allocator->ceiling = (void*)((POINTER_SIZE_INT)new_free + zeroing_size);
+    memset(new_free, 0, zeroing_size);
+
+#endif /* #ifndef ALLOC_ZEROING */
+
+    allocator->end = alloc_block->ceiling;
+    allocator->alloc_block = (Block*)alloc_block; 
+    
+    return;
+}
+
 inline void alloc_context_reset(Allocator* allocator)
 {
   Block_Header* block = (Block_Header*)allocator->alloc_block;

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/trace_forward/fspace_alloc.cpp Fri Apr 20 07:45:58 2007
@@ -21,7 +21,7 @@
 #include "fspace.h"
 
 static Boolean fspace_alloc_block(Fspace* fspace, Allocator* allocator)
-{
+{    
   alloc_context_reset(allocator);
 
   /* now try to get a new block */
@@ -36,29 +36,9 @@
     }
     /* ok, got one */
     Block_Header* alloc_block = (Block_Header*)&(fspace->blocks[allocated_idx - fspace->first_block_idx]);
-    assert(alloc_block->status == BLOCK_FREE);
-    alloc_block->status = BLOCK_IN_USE;
     
-    /* set allocation context */
-    void* new_free = alloc_block->free;
-    allocator->free = new_free;
-
-#ifndef ALLOC_ZEROING
-
-    allocator->ceiling = alloc_block->ceiling;
-    memset(new_free, 0, GC_BLOCK_BODY_SIZE_BYTES);
-
-#else
-    /* the first-time zeroing area includes block header, to make subsequent allocs page aligned */
-    unsigned int zeroing_size = ZEROING_SIZE - GC_BLOCK_HEADER_SIZE_BYTES;
-    allocator->ceiling = (void*)((POINTER_SIZE_INT)new_free + zeroing_size);
-    memset(new_free, 0, zeroing_size);
-
-#endif /* #ifndef ALLOC_ZEROING */
-
-    allocator->end = alloc_block->ceiling;
-    allocator->alloc_block = (Block*)alloc_block; 
-        
+    allocator_init_free_block(allocator, alloc_block);
+            
     return TRUE;
   }
 
@@ -84,12 +64,18 @@
     if ( !space_has_free_block((Blocked_Space*)fspace) ) {  
         if(attempts < 2) {
           gc_reclaim_heap(allocator->gc, GC_CAUSE_NOS_IS_FULL); 
+          if(allocator->alloc_block){
+            vm_gc_unlock_enum();  
+            break;
+          }
+          
           attempts++;
+          
         }else{
           vm_gc_unlock_enum();  
           return NULL;
         }
-    }    
+    }
     vm_gc_unlock_enum();  
   }
   

Modified: harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h?view=diff&rev=530829&r1=530828&r2=530829
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/gc_gen/src/utils/bit_ops.h Fri Apr 20 07:45:58 2007
@@ -95,9 +95,12 @@
   POINTER_SIZE_INT old_value = *p_word;
   POINTER_SIZE_INT mask = (POINTER_SIZE_INT)1 << bit_offset;
   POINTER_SIZE_INT new_value = old_value|mask;
-  
-  *p_word = new_value;
-  
+  while (true) {
+    POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value);
+    if (temp == old_value) break;
+    old_value = *p_word;
+    new_value = old_value|mask;
+  }
   return;
 }
 
@@ -114,9 +117,12 @@
   POINTER_SIZE_INT old_value = *p_word;
   POINTER_SIZE_INT mask = ~((POINTER_SIZE_INT)1 << bit_offset);
   POINTER_SIZE_INT new_value = old_value & mask;
-  
-  *p_word = new_value;
-  
+  while (true) {
+    POINTER_SIZE_INT temp = atomic_casptrsz(p_word, new_value, old_value);
+    if (temp == old_value) break;
+    old_value = *p_word;
+    new_value = old_value & mask;
+  }
   return;
 }
 #endif