< prev index next >

src/hotspot/share/interpreter/oopMapCache.cpp

Print this page




 179   // but the space for the bit_mask is not freed.
 180   assert(_resource_allocate_bit_mask, "Trying to free C heap space");
 181   if (mask_size() > small_mask_limit) {
 182     FREE_RESOURCE_ARRAY(uintptr_t, _bit_mask[0], mask_word_size());
 183   }
 184 }
 185 
 186 bool InterpreterOopMap::is_empty() const {
 187   bool result = _method == NULL;
 188   assert(_method != NULL || (_bci == 0 &&
 189     (_mask_size == 0 || _mask_size == USHRT_MAX) &&
 190     _bit_mask[0] == 0), "Should be completely empty");
 191   return result;
 192 }
 193 
 194 void InterpreterOopMap::initialize() {
 195   _method    = NULL;
 196   _mask_size = USHRT_MAX;  // This value should cause a failure quickly
 197   _bci       = 0;
 198   _expression_stack_size = 0;

 199   for (int i = 0; i < N; i++) _bit_mask[i] = 0;
 200 }
 201 
 202 void InterpreterOopMap::iterate_oop(OffsetClosure* oop_closure) const {
 203   int n = number_of_entries();
 204   int word_index = 0;
 205   uintptr_t value = 0;
 206   uintptr_t mask = 0;
 207   // iterate over entries
 208   for (int i = 0; i < n; i++, mask <<= bits_per_entry) {
 209     // get current word
 210     if (mask == 0) {
 211       value = bit_mask()[word_index++];
 212       mask = 1;
 213     }
 214     // test for oop
 215     if ((value & (mask << oop_bit_number)) != 0) oop_closure->offset_do(i);
 216   }
 217 }
 218 


 333     EXCEPTION_MARK;
 334     OopMapForCacheEntry gen(method, bci, this);
 335     gen.compute_map(CATCH);
 336   }
 337 }
 338 
 339 
 340 void OopMapCacheEntry::set_mask(CellTypeState *vars, CellTypeState *stack, int stack_top) {
 341   // compute bit mask size
 342   int max_locals = method()->max_locals();
 343   int n_entries = max_locals + stack_top;
 344   set_mask_size(n_entries * bits_per_entry);
 345   allocate_bit_mask();
 346   set_expression_stack_size(stack_top);
 347 
 348   // compute bits
 349   int word_index = 0;
 350   uintptr_t value = 0;
 351   uintptr_t mask = 1;
 352 

 353   CellTypeState* cell = vars;
 354   for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
 355     // store last word
 356     if (mask == 0) {
 357       bit_mask()[word_index++] = value;
 358       value = 0;
 359       mask = 1;
 360     }
 361 
 362     // switch to stack when done with locals
 363     if (entry_index == max_locals) {
 364       cell = stack;
 365     }
 366 
 367     // set oop bit
 368     if ( cell->is_reference()) {
 369       value |= (mask << oop_bit_number );

 370     }
 371 
 372     // set dead bit
 373     if (!cell->is_live()) {
 374       value |= (mask << dead_bit_number);
 375       assert(!cell->is_reference(), "dead value marked as oop");
 376     }
 377   }
 378 
 379   // make sure last word is stored
 380   bit_mask()[word_index] = value;
 381 
 382   // verify bit mask
 383   assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
 384 }
 385 
 386 void OopMapCacheEntry::flush() {
 387   deallocate_bit_mask();
 388   initialize();
 389 }
 390 
 391 
 392 // Implementation of OopMapCache
 393 
 394 void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) {
 395   assert(_resource_allocate_bit_mask,
 396     "Should not resource allocate the _bit_mask");
 397 
 398   set_method(from->method());
 399   set_bci(from->bci());
 400   set_mask_size(from->mask_size());
 401   set_expression_stack_size(from->expression_stack_size());

 402 
 403   // Is the bit mask contained in the entry?
 404   if (from->mask_size() <= small_mask_limit) {
 405     memcpy((void *)_bit_mask, (void *)from->_bit_mask,
 406       mask_word_size() * BytesPerWord);
 407   } else {
 408     // The expectation is that this InterpreterOopMap is a recently created
 409     // and empty. It is used to get a copy of a cached entry.
 410     // If the bit mask has a value, it should be in the
 411     // resource area.
 412     assert(_bit_mask[0] == 0 ||
 413       Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
 414       "The bit mask should have been allocated from a resource area");
 415     // Allocate the bit_mask from a Resource area for performance.  Allocating
 416     // from the C heap as is done for OopMapCache has a significant
 417     // performance impact.
 418     _bit_mask[0] = (uintptr_t) NEW_RESOURCE_ARRAY(uintptr_t, mask_word_size());
 419     assert(_bit_mask[0] != 0, "bit mask was not allocated");
 420     memcpy((void*) _bit_mask[0], (void*) from->_bit_mask[0],
 421       mask_word_size() * BytesPerWord);




 179   // but the space for the bit_mask is not freed.
 180   assert(_resource_allocate_bit_mask, "Trying to free C heap space");
 181   if (mask_size() > small_mask_limit) {
 182     FREE_RESOURCE_ARRAY(uintptr_t, _bit_mask[0], mask_word_size());
 183   }
 184 }
 185 
 186 bool InterpreterOopMap::is_empty() const {
 187   bool result = _method == NULL;
 188   assert(_method != NULL || (_bci == 0 &&
 189     (_mask_size == 0 || _mask_size == USHRT_MAX) &&
 190     _bit_mask[0] == 0), "Should be completely empty");
 191   return result;
 192 }
 193 
 194 void InterpreterOopMap::initialize() {
 195   _method    = NULL;
 196   _mask_size = USHRT_MAX;  // This value should cause a failure quickly
 197   _bci       = 0;
 198   _expression_stack_size = 0;
 199   _num_oops  = 0;
 200   for (int i = 0; i < N; i++) _bit_mask[i] = 0;
 201 }
 202 
 203 void InterpreterOopMap::iterate_oop(OffsetClosure* oop_closure) const {
 204   int n = number_of_entries();
 205   int word_index = 0;
 206   uintptr_t value = 0;
 207   uintptr_t mask = 0;
 208   // iterate over entries
 209   for (int i = 0; i < n; i++, mask <<= bits_per_entry) {
 210     // get current word
 211     if (mask == 0) {
 212       value = bit_mask()[word_index++];
 213       mask = 1;
 214     }
 215     // test for oop
 216     if ((value & (mask << oop_bit_number)) != 0) oop_closure->offset_do(i);
 217   }
 218 }
 219 


 334     EXCEPTION_MARK;
 335     OopMapForCacheEntry gen(method, bci, this);
 336     gen.compute_map(CATCH);
 337   }
 338 }
 339 
 340 
 341 void OopMapCacheEntry::set_mask(CellTypeState *vars, CellTypeState *stack, int stack_top) {
 342   // compute bit mask size
 343   int max_locals = method()->max_locals();
 344   int n_entries = max_locals + stack_top;
 345   set_mask_size(n_entries * bits_per_entry);
 346   allocate_bit_mask();
 347   set_expression_stack_size(stack_top);
 348 
 349   // compute bits
 350   int word_index = 0;
 351   uintptr_t value = 0;
 352   uintptr_t mask = 1;
 353 
 354   _num_oops = 0;
 355   CellTypeState* cell = vars;
 356   for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
 357     // store last word
 358     if (mask == 0) {
 359       bit_mask()[word_index++] = value;
 360       value = 0;
 361       mask = 1;
 362     }
 363 
 364     // switch to stack when done with locals
 365     if (entry_index == max_locals) {
 366       cell = stack;
 367     }
 368 
 369     // set oop bit
 370     if ( cell->is_reference()) {
 371       value |= (mask << oop_bit_number );
 372       _num_oops++;
 373     }
 374 
 375     // set dead bit
 376     if (!cell->is_live()) {
 377       value |= (mask << dead_bit_number);
 378       assert(!cell->is_reference(), "dead value marked as oop");
 379     }
 380   }
 381 
 382   // make sure last word is stored
 383   bit_mask()[word_index] = value;
 384 
 385   // verify bit mask
 386   assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
 387 }
 388 
 389 void OopMapCacheEntry::flush() {
 390   deallocate_bit_mask();
 391   initialize();
 392 }
 393 
 394 
 395 // Implementation of OopMapCache
 396 
 397 void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) {
 398   assert(_resource_allocate_bit_mask,
 399     "Should not resource allocate the _bit_mask");
 400 
 401   set_method(from->method());
 402   set_bci(from->bci());
 403   set_mask_size(from->mask_size());
 404   set_expression_stack_size(from->expression_stack_size());
 405   _num_oops = from->num_oops();
 406 
 407   // Is the bit mask contained in the entry?
 408   if (from->mask_size() <= small_mask_limit) {
 409     memcpy((void *)_bit_mask, (void *)from->_bit_mask,
 410       mask_word_size() * BytesPerWord);
 411   } else {
 412     // The expectation is that this InterpreterOopMap is a recently created
 413     // and empty. It is used to get a copy of a cached entry.
 414     // If the bit mask has a value, it should be in the
 415     // resource area.
 416     assert(_bit_mask[0] == 0 ||
 417       Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
 418       "The bit mask should have been allocated from a resource area");
 419     // Allocate the bit_mask from a Resource area for performance.  Allocating
 420     // from the C heap as is done for OopMapCache has a significant
 421     // performance impact.
 422     _bit_mask[0] = (uintptr_t) NEW_RESOURCE_ARRAY(uintptr_t, mask_word_size());
 423     assert(_bit_mask[0] != 0, "bit mask was not allocated");
 424     memcpy((void*) _bit_mask[0], (void*) from->_bit_mask[0],
 425       mask_word_size() * BytesPerWord);


< prev index next >