src/share/vm/code/nmethod.hpp

Print this page
rev 6728 : 8050972: Concurrency problem in PcDesc cache
Summary: The entries of the PcDesc cache in nmethods are not declared as volatile, but they are accessed and modified by several threads concurrently.
Reviewed-by: kvn, dholmes


  52  public:
  53 
  54   ExceptionCache(Handle exception, address pc, address handler);
  55 
  56   Klass*    exception_type()                { return _exception_type; }
  57   ExceptionCache* next()                    { return _next; }
  58   void      set_next(ExceptionCache *ec)    { _next = ec; }
  59 
  60   address match(Handle exception, address pc);
  61   bool    match_exception_with_space(Handle exception) ;
  62   address test_address(address addr);
  63   bool    add_address_and_handler(address addr, address handler) ;
  64 };
  65 
  66 
  67 // cache pc descs found in earlier inquiries
  68 class PcDescCache VALUE_OBJ_CLASS_SPEC {
  69   friend class VMStructs;
  70  private:
  71   enum { cache_size = 4 };
  72   PcDesc* _pc_descs[cache_size]; // last cache_size pc_descs found





  73  public:
  74   PcDescCache() { debug_only(_pc_descs[0] = NULL); }
  75   void    reset_to(PcDesc* initial_pc_desc);
  76   PcDesc* find_pc_desc(int pc_offset, bool approximate);
  77   void    add_pc_desc(PcDesc* pc_desc);
  78   PcDesc* last_pc_desc() { return _pc_descs[0]; }
  79 };
  80 
  81 
  82 // nmethods (native methods) are the compiled code versions of Java methods.
  83 //
  84 // An nmethod contains:
  85 //  - header                 (the nmethod structure)
  86 //  [Relocation]
  87 //  - relocation information
  88 //  - constant part          (doubles, longs and floats used in nmethod)
  89 //  - oop table
  90 //  [Code]
  91 //  - code body
  92 //  - exception handler




  52  public:
  53 
  54   ExceptionCache(Handle exception, address pc, address handler);
  55 
  56   Klass*    exception_type()                { return _exception_type; }
  57   ExceptionCache* next()                    { return _next; }
  58   void      set_next(ExceptionCache *ec)    { _next = ec; }
  59 
  60   address match(Handle exception, address pc);
  61   bool    match_exception_with_space(Handle exception) ;
  62   address test_address(address addr);
  63   bool    add_address_and_handler(address addr, address handler) ;
  64 };
  65 
  66 
  67 // cache pc descs found in earlier inquiries
  68 class PcDescCache VALUE_OBJ_CLASS_SPEC {
  69   friend class VMStructs;
  70  private:
  71   enum { cache_size = 4 };
  72   // The array elements MUST be volatile! Several threads may modify
  73   // and read from the cache concurrently. find_pc_desc_internal has
  74   // returned wrong results. C++ compiler (namely xlC12) may duplicate
  75   // C++ field accesses if the elements are not volatile.
  76   typedef PcDesc* PcDescPtr;
  77   volatile PcDescPtr _pc_descs[cache_size]; // last cache_size pc_descs found
  78  public:
  79   PcDescCache() { debug_only(_pc_descs[0] = NULL); }
  80   void    reset_to(PcDesc* initial_pc_desc);
  81   PcDesc* find_pc_desc(int pc_offset, bool approximate);
  82   void    add_pc_desc(PcDesc* pc_desc);
  83   PcDesc* last_pc_desc() { return _pc_descs[0]; }
  84 };
  85 
  86 
  87 // nmethods (native methods) are the compiled code versions of Java methods.
  88 //
  89 // An nmethod contains:
  90 //  - header                 (the nmethod structure)
  91 //  [Relocation]
  92 //  - relocation information
  93 //  - constant part          (doubles, longs and floats used in nmethod)
  94 //  - oop table
  95 //  [Code]
  96 //  - code body
  97 //  - exception handler