Print this page
rev 6898 : 8062870: src/share/vm/services/mallocTracker.hpp:64 assert(_count > 0) failed: Negative counter
Summary: Signed bitfield size y can only have (1 << y)-1 values.
Reviewed-by: shade, dholmes, jrose, ctornqvi, gtriantafill

Split Split Close
Expand all
Collapse all
          --- old/hotspot/src/share/vm/services/mallocTracker.hpp
          +++ new/hotspot/src/share/vm/services/mallocTracker.hpp
↓ open down ↓ 231 lines elided ↑ open up ↑
 232  232  
 233  233  
 234  234  /*
 235  235   * Malloc tracking header.
 236  236   * To satisfy malloc alignment requirement, NMT uses 2 machine words for tracking purpose,
 237  237   * which ensures 8-bytes alignment on 32-bit systems and 16-bytes on 64-bit systems (Product build).
 238  238   */
 239  239  
 240  240  class MallocHeader VALUE_OBJ_CLASS_SPEC {
 241  241  #ifdef _LP64
 242      -  size_t           _size      : 62;
 243      -  size_t           _level     : 2;
      242 +  size_t           _size      : 64;
 244  243    size_t           _flags     : 8;
 245  244    size_t           _pos_idx   : 16;
 246  245    size_t           _bucket_idx: 40;
 247      -#define MAX_MALLOCSITE_TABLE_SIZE ((size_t)1 << 40)
 248      -#define MAX_BUCKET_LENGTH         ((size_t)(1 << 16))
 249      -#define MAX_MALLOC_SIZE           (((size_t)1 << 62) - 1)
      246 +#define MAX_MALLOCSITE_TABLE_SIZE right_n_bits(40)
      247 +#define MAX_BUCKET_LENGTH         right_n_bits(16)
 250  248  #else
 251      -  size_t           _size      : 30;
 252      -  size_t           _level     : 2;
      249 +  size_t           _size      : 32;
 253  250    size_t           _flags     : 8;
 254  251    size_t           _pos_idx   : 8;
 255  252    size_t           _bucket_idx: 16;
 256      -#define MAX_MALLOCSITE_TABLE_SIZE  ((size_t)(1 << 16))
 257      -#define MAX_BUCKET_LENGTH          ((size_t)(1 << 8))
 258      -// Max malloc size = 1GB - 1 on 32 bit system, such has total 4GB memory
 259      -#define MAX_MALLOC_SIZE            ((size_t)(1 << 30) - 1)
      253 +#define MAX_MALLOCSITE_TABLE_SIZE  right_n_bits(16)
      254 +#define MAX_BUCKET_LENGTH          right_n_bits(8)
 260  255  #endif  // _LP64
 261  256  
 262  257   public:
 263      -  // Summary tracking header
 264      -  MallocHeader(size_t size, MEMFLAGS flags) {
      258 +  MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack, NMT_TrackingLevel level) {
 265  259      assert(sizeof(MallocHeader) == sizeof(void*) * 2,
 266  260        "Wrong header size");
 267  261  
 268      -    _level = NMT_summary;
 269      -    _flags = flags;
 270      -    set_size(size);
 271      -    MallocMemorySummary::record_malloc(size, flags);
 272      -    MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
 273      -  }
 274      -  // Detail tracking header
 275      -  MallocHeader(size_t size, MEMFLAGS flags, const NativeCallStack& stack) {
 276      -    assert(sizeof(MallocHeader) == sizeof(void*) * 2,
 277      -      "Wrong header size");
      262 +    if (level == NMT_minimal) {
      263 +      return;
      264 +    }
 278  265  
 279      -    _level = NMT_detail;
 280  266      _flags = flags;
 281  267      set_size(size);
 282      -    size_t bucket_idx;
 283      -    size_t pos_idx;
 284      -    if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
 285      -      assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
 286      -      assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
 287      -      _bucket_idx = bucket_idx;
 288      -      _pos_idx = pos_idx;
      268 +    if (level == NMT_detail) {
      269 +      size_t bucket_idx;
      270 +      size_t pos_idx;
      271 +      if (record_malloc_site(stack, size, &bucket_idx, &pos_idx)) {
      272 +        assert(bucket_idx <= MAX_MALLOCSITE_TABLE_SIZE, "Overflow bucket index");
      273 +        assert(pos_idx <= MAX_BUCKET_LENGTH, "Overflow bucket position index");
      274 +        _bucket_idx = bucket_idx;
      275 +        _pos_idx = pos_idx;
      276 +      }
 289  277      }
      278 +
 290  279      MallocMemorySummary::record_malloc(size, flags);
 291  280      MallocMemorySummary::record_new_malloc_header(sizeof(MallocHeader));
 292  281    }
 293      -  // Minimal tracking header
 294      -  MallocHeader() {
 295      -    assert(sizeof(MallocHeader) == sizeof(void*) * 2,
 296      -      "Wrong header size");
 297      -
 298      -    _level = (unsigned short)NMT_minimal;
 299      -  }
 300      -
 301      -  inline NMT_TrackingLevel tracking_level() const {
 302      -    return (NMT_TrackingLevel)_level;
 303      -  }
 304  282  
 305  283    inline size_t   size()  const { return _size; }
 306  284    inline MEMFLAGS flags() const { return (MEMFLAGS)_flags; }
 307  285    bool get_stack(NativeCallStack& stack) const;
 308  286  
 309  287    // Cleanup tracking information before the memory is released.
 310  288    void release() const;
 311  289  
 312  290   private:
 313  291    inline void set_size(size_t size) {
 314      -    assert(size <= MAX_MALLOC_SIZE, "Malloc size too large, should use virtual memory?");
 315  292      _size = size;
 316  293    }
 317  294    bool record_malloc_site(const NativeCallStack& stack, size_t size,
 318  295      size_t* bucket_idx, size_t* pos_idx) const;
 319  296  };
 320  297  
 321  298  
 322  299  // Main class called from MemTracker to track malloc activities
 323  300  class MallocTracker : AllStatic {
 324  301   public:
↓ open down ↓ 15 lines elided ↑ open up ↑
 340  317    // memblock = (char*)malloc_base + sizeof(nmt header)
 341  318    //
 342  319  
 343  320    // Record  malloc on specified memory block
 344  321    static void* record_malloc(void* malloc_base, size_t size, MEMFLAGS flags,
 345  322      const NativeCallStack& stack, NMT_TrackingLevel level);
 346  323  
 347  324    // Record free on specified memory block
 348  325    static void* record_free(void* memblock);
 349  326  
 350      -  // Get tracking level of specified memory block
 351      -  static inline NMT_TrackingLevel get_memory_tracking_level(void* memblock);
 352      -
 353      -
 354  327    // Offset memory address to header address
 355  328    static inline void* get_base(void* memblock);
 356  329    static inline void* get_base(void* memblock, NMT_TrackingLevel level) {
 357  330      if (memblock == NULL || level == NMT_off) return memblock;
 358  331      return (char*)memblock - malloc_header_size(level);
 359  332    }
 360  333  
 361  334    // Get memory size
 362  335    static inline size_t get_size(void* memblock) {
 363  336      MallocHeader* header = malloc_header(memblock);
 364      -    assert(header->tracking_level() >= NMT_summary,
 365      -      "Wrong tracking level");
 366  337      return header->size();
 367  338    }
 368  339  
 369  340    // Get memory type
 370  341    static inline MEMFLAGS get_flags(void* memblock) {
 371  342      MallocHeader* header = malloc_header(memblock);
 372      -    assert(header->tracking_level() >= NMT_summary,
 373      -      "Wrong tracking level");
 374  343      return header->flags();
 375  344    }
 376  345  
 377  346    // Get header size
 378  347    static inline size_t get_header_size(void* memblock) {
 379  348      return (memblock == NULL) ? 0 : sizeof(MallocHeader);
 380  349    }
 381  350  
 382  351    static inline void record_new_arena(MEMFLAGS flags) {
 383  352      MallocMemorySummary::record_new_arena(flags);
↓ open down ↓ 3 lines elided ↑ open up ↑
 387  356      MallocMemorySummary::record_arena_free(flags);
 388  357    }
 389  358  
 390  359    static inline void record_arena_size_change(int size, MEMFLAGS flags) {
 391  360      MallocMemorySummary::record_arena_size_change(size, flags);
 392  361    }
 393  362   private:
 394  363    static inline MallocHeader* malloc_header(void *memblock) {
 395  364      assert(memblock != NULL, "NULL pointer");
 396  365      MallocHeader* header = (MallocHeader*)((char*)memblock - sizeof(MallocHeader));
 397      -    assert(header->tracking_level() >= NMT_minimal, "Bad header");
 398  366      return header;
 399  367    }
 400  368  };
 401  369  
 402  370  #endif // INCLUDE_NMT
 403  371  
 404  372  
 405  373  #endif //SHARE_VM_SERVICES_MALLOC_TRACKER_HPP
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX