196 for (int i = 0; i < N; i++) _bit_mask[i] = 0; 197 } 198 199 void InterpreterOopMap::iterate_oop(OffsetClosure* oop_closure) const { 200 int n = number_of_entries(); 201 int word_index = 0; 202 uintptr_t value = 0; 203 uintptr_t mask = 0; 204 // iterate over entries 205 for (int i = 0; i < n; i++, mask <<= bits_per_entry) { 206 // get current word 207 if (mask == 0) { 208 value = bit_mask()[word_index++]; 209 mask = 1; 210 } 211 // test for oop 212 if ((value & (mask << oop_bit_number)) != 0) oop_closure->offset_do(i); 213 } 214 } 215 216 217 #ifdef ENABLE_ZAP_DEAD_LOCALS 218 219 void InterpreterOopMap::iterate_all(OffsetClosure* oop_closure, OffsetClosure* value_closure, OffsetClosure* dead_closure) { 220 int n = number_of_entries(); 221 int word_index = 0; 222 uintptr_t value = 0; 223 uintptr_t mask = 0; 224 // iterate over entries 225 for (int i = 0; i < n; i++, mask <<= bits_per_entry) { 226 // get current word 227 if (mask == 0) { 228 value = bit_mask()[word_index++]; 229 mask = 1; 230 } 231 // test for dead values & oops, and for live values 232 if ((value & (mask << dead_bit_number)) != 0) dead_closure->offset_do(i); // call this for all dead values or oops 233 else if ((value & (mask << oop_bit_number)) != 0) oop_closure->offset_do(i); // call this for all live oops 234 else value_closure->offset_do(i); // call this for all live values 235 } 236 } 237 238 #endif 239 240 241 void InterpreterOopMap::print() const { 242 int n = number_of_entries(); 243 tty->print("oop map for "); 244 method()->print_value(); 245 tty->print(" @ %d = [%d] { ", bci(), n); 246 for (int i = 0; i < n; i++) { 247 if (is_dead(i)) tty->print("%d+ ", i); 248 else 249 if (is_oop(i)) tty->print("%d ", i); 250 } 251 tty->print_cr("}"); 252 } 253 254 class MaskFillerForNative: public NativeSignatureIterator { 255 private: 256 uintptr_t * _mask; // the bit mask to be filled 257 int _size; // the mask size in bits 258 259 void set_one(int i) { 260 i *= InterpreterOopMap::bits_per_entry; 280 void generate() { 281 NativeSignatureIterator::iterate(); 282 } 283 }; 284 285 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) { 286 // Check mask includes map 287 VerifyClosure blk(this); 288 iterate_oop(&blk); 289 if (blk.failed()) return false; 290 291 // Check if map is generated correctly 292 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards) 293 if (TraceOopMapGeneration && Verbose) tty->print("Locals (%d): ", max_locals); 294 295 for(int i = 0; i < max_locals; i++) { 296 bool v1 = is_oop(i) ? true : false; 297 bool v2 = vars[i].is_reference() ? true : false; 298 assert(v1 == v2, "locals oop mask generation error"); 299 if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0); 300 #ifdef ENABLE_ZAP_DEAD_LOCALS 301 bool v3 = is_dead(i) ? true : false; 302 bool v4 = !vars[i].is_live() ? true : false; 303 assert(v3 == v4, "locals live mask generation error"); 304 assert(!(v1 && v3), "dead value marked as oop"); 305 #endif 306 } 307 308 if (TraceOopMapGeneration && Verbose) { tty->cr(); tty->print("Stack (%d): ", stack_top); } 309 for(int j = 0; j < stack_top; j++) { 310 bool v1 = is_oop(max_locals + j) ? true : false; 311 bool v2 = stack[j].is_reference() ? true : false; 312 assert(v1 == v2, "stack oop mask generation error"); 313 if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0); 314 #ifdef ENABLE_ZAP_DEAD_LOCALS 315 bool v3 = is_dead(max_locals + j) ? true : false; 316 bool v4 = !stack[j].is_live() ? true : false; 317 assert(v3 == v4, "stack live mask generation error"); 318 assert(!(v1 && v3), "dead value marked as oop"); 319 #endif 320 } 321 if (TraceOopMapGeneration && Verbose) tty->cr(); 322 return true; 323 } 324 325 void OopMapCacheEntry::allocate_bit_mask() { 326 if (mask_size() > small_mask_limit) { 327 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed"); 328 _bit_mask[0] = (intptr_t) 329 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass); 330 } 331 } 332 333 void OopMapCacheEntry::deallocate_bit_mask() { 334 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) { 335 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]), 336 "This bit mask should not be in the resource area"); 337 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]); 338 debug_only(_bit_mask[0] = 0;) 339 } | 196 for (int i = 0; i < N; i++) _bit_mask[i] = 0; 197 } 198 199 void InterpreterOopMap::iterate_oop(OffsetClosure* oop_closure) const { 200 int n = number_of_entries(); 201 int word_index = 0; 202 uintptr_t value = 0; 203 uintptr_t mask = 0; 204 // iterate over entries 205 for (int i = 0; i < n; i++, mask <<= bits_per_entry) { 206 // get current word 207 if (mask == 0) { 208 value = bit_mask()[word_index++]; 209 mask = 1; 210 } 211 // test for oop 212 if ((value & (mask << oop_bit_number)) != 0) oop_closure->offset_do(i); 213 } 214 } 215 216 void InterpreterOopMap::print() const { 217 int n = number_of_entries(); 218 tty->print("oop map for "); 219 method()->print_value(); 220 tty->print(" @ %d = [%d] { ", bci(), n); 221 for (int i = 0; i < n; i++) { 222 if (is_dead(i)) tty->print("%d+ ", i); 223 else 224 if (is_oop(i)) tty->print("%d ", i); 225 } 226 tty->print_cr("}"); 227 } 228 229 class MaskFillerForNative: public NativeSignatureIterator { 230 private: 231 uintptr_t * _mask; // the bit mask to be filled 232 int _size; // the mask size in bits 233 234 void set_one(int i) { 235 i *= InterpreterOopMap::bits_per_entry; 255 void generate() { 256 NativeSignatureIterator::iterate(); 257 } 258 }; 259 260 bool OopMapCacheEntry::verify_mask(CellTypeState* vars, CellTypeState* stack, int max_locals, int stack_top) { 261 // Check mask includes map 262 VerifyClosure blk(this); 263 iterate_oop(&blk); 264 if (blk.failed()) return false; 265 266 // Check if map is generated correctly 267 // (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards) 268 if (TraceOopMapGeneration && Verbose) tty->print("Locals (%d): ", max_locals); 269 270 for(int i = 0; i < max_locals; i++) { 271 bool v1 = is_oop(i) ? true : false; 272 bool v2 = vars[i].is_reference() ? true : false; 273 assert(v1 == v2, "locals oop mask generation error"); 274 if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0); 275 } 276 277 if (TraceOopMapGeneration && Verbose) { tty->cr(); tty->print("Stack (%d): ", stack_top); } 278 for(int j = 0; j < stack_top; j++) { 279 bool v1 = is_oop(max_locals + j) ? true : false; 280 bool v2 = stack[j].is_reference() ? true : false; 281 assert(v1 == v2, "stack oop mask generation error"); 282 if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0); 283 } 284 if (TraceOopMapGeneration && Verbose) tty->cr(); 285 return true; 286 } 287 288 void OopMapCacheEntry::allocate_bit_mask() { 289 if (mask_size() > small_mask_limit) { 290 assert(_bit_mask[0] == 0, "bit mask should be new or just flushed"); 291 _bit_mask[0] = (intptr_t) 292 NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass); 293 } 294 } 295 296 void OopMapCacheEntry::deallocate_bit_mask() { 297 if (mask_size() > small_mask_limit && _bit_mask[0] != 0) { 298 assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]), 299 "This bit mask should not be in the resource area"); 300 FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]); 301 debug_only(_bit_mask[0] = 0;) 302 } |