src/share/vm/code/stubs.cpp

Print this page
rev 4202 : 8008555: Debugging code in compiled method sometimes leaks memory
Summary: support for strings that have same life-time as code that uses them.
Reviewed-by:


  84   // Note: Currently StubQueues are never destroyed so nothing needs to be done here.
  85   //       If we want to implement the destructor, we need to release the BufferBlob
  86   //       allocated in the constructor (i.e., we need to keep it around or look it
  87   //       up via CodeCache::find_blob(...).
  88   Unimplemented();
  89 }
  90 
  91 
  92 Stub* StubQueue::stub_containing(address pc) const {
  93   if (contains(pc)) {
  94     for (Stub* s = first(); s != NULL; s = next(s)) {
  95       if (stub_contains(s, pc)) return s;
  96     }
  97   }
  98   return NULL;
  99 }
 100 
 101 
 102 Stub* StubQueue::request_committed(int code_size) {
 103   Stub* s = request(code_size);
 104   CodeComments comments;
 105   if (s != NULL) commit(code_size, comments);
 106   return s;
 107 }
 108 
 109 
 110 Stub* StubQueue::request(int requested_code_size) {
 111   assert(requested_code_size > 0, "requested_code_size must be > 0");
 112   if (_mutex != NULL) _mutex->lock();
 113   Stub* s = current_stub();
 114   int requested_size = round_to(stub_code_size_to_size(requested_code_size), CodeEntryAlignment);
 115   if (requested_size <= available_space()) {
 116     if (is_contiguous()) {
 117       // Queue: |...|XXXXXXX|.............|
 118       //        ^0  ^begin  ^end          ^size = limit
 119       assert(_buffer_limit == _buffer_size, "buffer must be fully usable");
 120       if (_queue_end + requested_size <= _buffer_size) {
 121         // code fits in at the end => nothing to do
 122         CodeComments comments;
 123         stub_initialize(s, requested_size, comments);
 124         return s;
 125       } else {
 126         // stub doesn't fit in at the queue end
 127         // => reduce buffer limit & wrap around
 128         assert(!is_empty(), "just checkin'");
 129         _buffer_limit = _queue_end;
 130         _queue_end = 0;
 131       }
 132     }
 133   }
 134   if (requested_size <= available_space()) {
 135     assert(!is_contiguous(), "just checkin'");
 136     assert(_buffer_limit <= _buffer_size, "queue invariant broken");
 137     // Queue: |XXX|.......|XXXXXXX|.......|
 138     //        ^0  ^end    ^begin  ^limit  ^size
 139     s = current_stub();
 140     CodeComments comments;
 141     stub_initialize(s, requested_size, comments);
 142     return s;
 143   }
 144   // Not enough space left
 145   if (_mutex != NULL) _mutex->unlock();
 146   return NULL;
 147 }
 148 
 149 
 150 void StubQueue::commit(int committed_code_size, CodeComments& comments) {
 151   assert(committed_code_size > 0, "committed_code_size must be > 0");
 152   int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment);
 153   Stub* s = current_stub();
 154   assert(committed_size <= stub_size(s), "committed size must not exceed requested size");
 155   stub_initialize(s, committed_size, comments);
 156   _queue_end += committed_size;
 157   _number_of_stubs++;
 158   if (_mutex != NULL) _mutex->unlock();
 159   debug_only(stub_verify(s);)
 160 }
 161 
 162 
 163 void StubQueue::remove_first() {
 164   if (number_of_stubs() == 0) return;
 165   Stub* s = first();
 166   debug_only(stub_verify(s);)
 167   stub_finalize(s);
 168   _queue_begin += stub_size(s);
 169   assert(_queue_begin <= _buffer_limit, "sanity check");
 170   if (_queue_begin == _queue_end) {
 171     // buffer empty
 172     // => reset queue indices
 173     _queue_begin  = 0;
 174     _queue_end    = 0;
 175     _buffer_limit = _buffer_size;




  84   // Note: Currently StubQueues are never destroyed so nothing needs to be done here.
  85   //       If we want to implement the destructor, we need to release the BufferBlob
  86   //       allocated in the constructor (i.e., we need to keep it around or look it
  87   //       up via CodeCache::find_blob(...).
  88   Unimplemented();
  89 }
  90 
  91 
  92 Stub* StubQueue::stub_containing(address pc) const {
  93   if (contains(pc)) {
  94     for (Stub* s = first(); s != NULL; s = next(s)) {
  95       if (stub_contains(s, pc)) return s;
  96     }
  97   }
  98   return NULL;
  99 }
 100 
 101 
 102 Stub* StubQueue::request_committed(int code_size) {
 103   Stub* s = request(code_size);
 104   CodeStrings strings;
 105   if (s != NULL) commit(code_size, strings);
 106   return s;
 107 }
 108 
 109 
 110 Stub* StubQueue::request(int requested_code_size) {
 111   assert(requested_code_size > 0, "requested_code_size must be > 0");
 112   if (_mutex != NULL) _mutex->lock();
 113   Stub* s = current_stub();
 114   int requested_size = round_to(stub_code_size_to_size(requested_code_size), CodeEntryAlignment);
 115   if (requested_size <= available_space()) {
 116     if (is_contiguous()) {
 117       // Queue: |...|XXXXXXX|.............|
 118       //        ^0  ^begin  ^end          ^size = limit
 119       assert(_buffer_limit == _buffer_size, "buffer must be fully usable");
 120       if (_queue_end + requested_size <= _buffer_size) {
 121         // code fits in at the end => nothing to do
 122         CodeStrings strings;
 123         stub_initialize(s, requested_size, strings);
 124         return s;
 125       } else {
 126         // stub doesn't fit in at the queue end
 127         // => reduce buffer limit & wrap around
 128         assert(!is_empty(), "just checkin'");
 129         _buffer_limit = _queue_end;
 130         _queue_end = 0;
 131       }
 132     }
 133   }
 134   if (requested_size <= available_space()) {
 135     assert(!is_contiguous(), "just checkin'");
 136     assert(_buffer_limit <= _buffer_size, "queue invariant broken");
 137     // Queue: |XXX|.......|XXXXXXX|.......|
 138     //        ^0  ^end    ^begin  ^limit  ^size
 139     s = current_stub();
 140     CodeStrings strings;
 141     stub_initialize(s, requested_size, strings);
 142     return s;
 143   }
 144   // Not enough space left
 145   if (_mutex != NULL) _mutex->unlock();
 146   return NULL;
 147 }
 148 
 149 
 150 void StubQueue::commit(int committed_code_size, CodeStrings& strings) {
 151   assert(committed_code_size > 0, "committed_code_size must be > 0");
 152   int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment);
 153   Stub* s = current_stub();
 154   assert(committed_size <= stub_size(s), "committed size must not exceed requested size");
 155   stub_initialize(s, committed_size, strings);
 156   _queue_end += committed_size;
 157   _number_of_stubs++;
 158   if (_mutex != NULL) _mutex->unlock();
 159   debug_only(stub_verify(s);)
 160 }
 161 
 162 
 163 void StubQueue::remove_first() {
 164   if (number_of_stubs() == 0) return;
 165   Stub* s = first();
 166   debug_only(stub_verify(s);)
 167   stub_finalize(s);
 168   _queue_begin += stub_size(s);
 169   assert(_queue_begin <= _buffer_limit, "sanity check");
 170   if (_queue_begin == _queue_end) {
 171     // buffer empty
 172     // => reset queue indices
 173     _queue_begin  = 0;
 174     _queue_end    = 0;
 175     _buffer_limit = _buffer_size;