69 |
69 |
70 // Lookup that does not fail if you lookup a zombie method (if you call this, be sure to know |
70 // Lookup that does not fail if you lookup a zombie method (if you call this, be sure to know |
71 // what you are doing) |
71 // what you are doing) |
72 static CodeBlob* find_blob_unsafe(void* start) { |
72 static CodeBlob* find_blob_unsafe(void* start) { |
73 CodeBlob* result = (CodeBlob*)_heap->find_start(start); |
73 CodeBlob* result = (CodeBlob*)_heap->find_start(start); |
74 assert(result == NULL || result->blob_contains((address)start), "found wrong CodeBlob"); |
74 // this assert is too strong because the heap code will return the |
|
75 // heapblock containing start. That block can often be larger than |
|
76 // the codeBlob itself. If you look up an address that is within |
|
77 // the heapblock but not in the codeBlob you will assert. |
|
78 // |
|
79 // Most things will not lookup such bad addresses. However |
|
80 // AsyncGetCallTrace can see intermediate frames and get that kind |
|
81 // of invalid address and so can a developer using hsfind. |
|
82 // |
|
83 // The more correct answer is to return NULL if blob_contains() returns |
|
84 // false. |
|
85 // assert(result == NULL || result->blob_contains((address)start), "found wrong CodeBlob"); |
|
86 |
|
87 if (result != NULL && !result->blob_contains((address)start)) { |
|
88 result = NULL; |
|
89 } |
75 return result; |
90 return result; |
76 } |
91 } |
77 |
92 |
78 // Iteration |
93 // Iteration |
79 static CodeBlob* first(); |
94 static CodeBlob* first(); |