< prev index next >

src/hotspot/share/runtime/synchronizer.cpp

Print this page

1058         // We can't safely induce a STW safepoint from om_alloc() as our thread
1059         // state may not be appropriate for such activities and callers may hold
1060         // naked oops, so instead we defer the action.
1061         InduceScavenge(self, "om_alloc");
1062       }
1063       continue;
1064     }
1065 
1066     // 3: allocate a block of new ObjectMonitors
1067     // Both the local and global free lists are empty -- resort to malloc().
1068     // In the current implementation ObjectMonitors are TSM - immortal.
1069     // Ideally, we'd write "new ObjectMonitor[_BLOCKSIZE], but we want
1070     // each ObjectMonitor to start at the beginning of a cache line,
1071     // so we use align_up().
1072     // A better solution would be to use C++ placement-new.
1073     // BEWARE: As it stands currently, we don't run the ctors!
1074     assert(_BLOCKSIZE > 1, "invariant");
1075     size_t neededsize = sizeof(PaddedObjectMonitor) * _BLOCKSIZE;
1076     PaddedObjectMonitor* temp;
1077     size_t aligned_size = neededsize + (DEFAULT_CACHE_LINE_SIZE - 1);
1078     void* real_malloc_addr = (void*)NEW_C_HEAP_ARRAY(char, aligned_size,
1079                                                      mtInternal);
1080     temp = (PaddedObjectMonitor*)align_up(real_malloc_addr, DEFAULT_CACHE_LINE_SIZE);
1081 
1082     // NOTE: (almost) no way to recover if allocation failed.
1083     // We might be able to induce a STW safepoint and scavenge enough
1084     // ObjectMonitors to permit progress.
1085     if (temp == NULL) {
1086       vm_exit_out_of_memory(neededsize, OOM_MALLOC_ERROR,
1087                             "Allocate ObjectMonitors");
1088     }
1089     (void)memset((void *) temp, 0, neededsize);
1090 
1091     // Format the block.
1092     // initialize the linked list, each monitor points to its next
1093     // forming the single linked free list, the very first monitor
1094     // will points to next block, which forms the block list.
1095     // The trick of using the 1st element in the block as g_block_list
1096     // linkage should be reconsidered.  A better implementation would
1097     // look like: class Block { Block * next; int N; ObjectMonitor Body [N] ; }
1098 
1099     for (int i = 1; i < _BLOCKSIZE; i++) {
1100       temp[i]._next_om = (ObjectMonitor *)&temp[i+1];
1101     }
1102 
1103     // terminate the last monitor as the end of list
1104     temp[_BLOCKSIZE - 1]._next_om = NULL;
1105 
1106     // Element [0] is reserved for global list linkage
1107     temp[0].set_object(CHAINMARKER);
1108 

1058         // We can't safely induce a STW safepoint from om_alloc() as our thread
1059         // state may not be appropriate for such activities and callers may hold
1060         // naked oops, so instead we defer the action.
1061         InduceScavenge(self, "om_alloc");
1062       }
1063       continue;
1064     }
1065 
1066     // 3: allocate a block of new ObjectMonitors
1067     // Both the local and global free lists are empty -- resort to malloc().
1068     // In the current implementation ObjectMonitors are TSM - immortal.
1069     // Ideally, we'd write "new ObjectMonitor[_BLOCKSIZE], but we want
1070     // each ObjectMonitor to start at the beginning of a cache line,
1071     // so we use align_up().
1072     // A better solution would be to use C++ placement-new.
1073     // BEWARE: As it stands currently, we don't run the ctors!
1074     assert(_BLOCKSIZE > 1, "invariant");
1075     size_t neededsize = sizeof(PaddedObjectMonitor) * _BLOCKSIZE;
1076     PaddedObjectMonitor* temp;
1077     size_t aligned_size = neededsize + (DEFAULT_CACHE_LINE_SIZE - 1);
1078     void* real_malloc_addr = NEW_C_HEAP_ARRAY(char, aligned_size, mtInternal);

1079     temp = (PaddedObjectMonitor*)align_up(real_malloc_addr, DEFAULT_CACHE_LINE_SIZE);








1080     (void)memset((void *) temp, 0, neededsize);
1081 
1082     // Format the block.
1083     // initialize the linked list, each monitor points to its next
1084     // forming the single linked free list, the very first monitor
1085     // will points to next block, which forms the block list.
1086     // The trick of using the 1st element in the block as g_block_list
1087     // linkage should be reconsidered.  A better implementation would
1088     // look like: class Block { Block * next; int N; ObjectMonitor Body [N] ; }
1089 
1090     for (int i = 1; i < _BLOCKSIZE; i++) {
1091       temp[i]._next_om = (ObjectMonitor *)&temp[i+1];
1092     }
1093 
1094     // terminate the last monitor as the end of list
1095     temp[_BLOCKSIZE - 1]._next_om = NULL;
1096 
1097     // Element [0] is reserved for global list linkage
1098     temp[0].set_object(CHAINMARKER);
1099 
< prev index next >