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
|