< prev index next >

src/hotspot/share/interpreter/oopMapCache.cpp

Print this page

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

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

341     if (!gen.compute_map(Thread::current())) {
342       fatal("Unrecoverable verification or out-of-memory error");
343     }
344   }
345 }
346 
347 
348 void OopMapCacheEntry::set_mask(CellTypeState *vars, CellTypeState *stack, int stack_top) {
349   // compute bit mask size
350   int max_locals = method()->max_locals();
351   int n_entries = max_locals + stack_top;
352   set_mask_size(n_entries * bits_per_entry);
353   allocate_bit_mask();
354   set_expression_stack_size(stack_top);
355 
356   // compute bits
357   int word_index = 0;
358   uintptr_t value = 0;
359   uintptr_t mask = 1;
360 

361   CellTypeState* cell = vars;
362   for (int entry_index = 0; entry_index < n_entries; entry_index++, mask <<= bits_per_entry, cell++) {
363     // store last word
364     if (mask == 0) {
365       bit_mask()[word_index++] = value;
366       value = 0;
367       mask = 1;
368     }
369 
370     // switch to stack when done with locals
371     if (entry_index == max_locals) {
372       cell = stack;
373     }
374 
375     // set oop bit
376     if ( cell->is_reference()) {
377       value |= (mask << oop_bit_number );

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

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

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

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