8187091: ReturnBlobToWrongHeapTest fails because of problems in CodeHeap::contains_blob()
authorsimonis
Wed, 01 Nov 2017 12:56:48 -0700
changeset 47768 3d1d05c9b6cd
parent 47767 107622f2695c
child 47769 80ea7a4c6427
8187091: ReturnBlobToWrongHeapTest fails because of problems in CodeHeap::contains_blob() Reviewed-by: kvn
src/hotspot/share/code/codeBlob.hpp
src/hotspot/share/memory/heap.hpp
--- a/src/hotspot/share/code/codeBlob.hpp	Wed Nov 01 16:48:12 2017 +0300
+++ b/src/hotspot/share/code/codeBlob.hpp	Wed Nov 01 12:56:48 2017 -0700
@@ -49,21 +49,35 @@
 // CodeBlob - superclass for all entries in the CodeCache.
 //
 // Subtypes are:
-//   CompiledMethod       : Compiled Java methods (include method that calls to native code)
-//     nmethod            : JIT Compiled Java methods
-//   RuntimeBlob          : Non-compiled method code; generated glue code
-//     RuntimeStub        : Call to VM runtime methods
-//     DeoptimizationBlob : Used for deoptimization
-//     ExceptionBlob      : Used for stack unrolling
-//     SafepointBlob      : Used to handle illegal instruction exceptions
+//  CompiledMethod       : Compiled Java methods (include method that calls to native code)
+//   nmethod             : JIT Compiled Java methods
+//   AOTCompiledMethod   : AOT Compiled Java methods - Not in the CodeCache!
+//                         AOTCompiledMethod objects are allocated in the C-Heap, the code they
+//                         point to is allocated in the AOTCodeHeap which is in the C-Heap as
+//                         well (i.e. it's the memory where the shared library was loaded to)
+//  RuntimeBlob          : Non-compiled method code; generated glue code
+//   BufferBlob          : Used for non-relocatable code such as interpreter, stubroutines, etc.
+//    AdapterBlob        : Used to hold C2I/I2C adapters
+//    MethodHandlesAdapterBlob : Used to hold MethodHandles adapters
+//   RuntimeStub         : Call to VM runtime methods
+//   SingletonBlob       : Super-class for all blobs that exist in only one instance
+//    DeoptimizationBlob : Used for deoptimization
+//    ExceptionBlob      : Used for stack unrolling
+//    SafepointBlob      : Used to handle illegal instruction exceptions
+//    UncommonTrapBlob   : Used to handle uncommon traps
 //
 //
-// Layout:
+// Layout (all except AOTCompiledMethod) : continuous in the CodeCache
 //   - header
 //   - relocation
 //   - content space
 //     - instruction space
 //   - data space
+//
+// Layout (AOTCompiledMethod) : in the C-Heap
+//   - header -\
+//     ...     |
+//   - code  <-/
 
 
 class CodeBlobLayout;
--- a/src/hotspot/share/memory/heap.hpp	Wed Nov 01 16:48:12 2017 +0300
+++ b/src/hotspot/share/memory/heap.hpp	Wed Nov 01 12:56:48 2017 -0700
@@ -160,7 +160,18 @@
   char* high_boundary() const                    { return _memory.high_boundary(); }
 
   bool contains(const void* p) const             { return low_boundary() <= p && p < high(); }
-  bool contains_blob(const CodeBlob* blob) const { return contains(blob->code_begin()); }
+  bool contains_blob(const CodeBlob* blob) const {
+    // AOT CodeBlobs (i.e. AOTCompiledMethod) objects aren't allocated in the AOTCodeHeap but on the C-Heap.
+    // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated
+    // directly in their corresponding CodeHeap with their code appended to the actual C++ object.
+    // So all CodeBlobs except AOTCompiledMethod are continuous in memory with their data and code while
+    // AOTCompiledMethod and their code/data is distributed in the C-Heap. This means we can use the
+    // address of a CodeBlob object in order to locate it in its heap while we have to use the address
+    // of the actual code an AOTCompiledMethod object is pointing to in order to locate it.
+    // Notice that for an ordinary CodeBlob with code size zero, code_begin() may point beyond the object!
+    const void* start = AOT_ONLY( (code_blob_type() == CodeBlobType::AOT) ? blob->code_begin() : ) (void*)blob;
+    return contains(start);
+  }
 
   virtual void* find_start(void* p)     const;   // returns the block containing p or NULL
   virtual CodeBlob* find_blob_unsafe(void* start) const;