Exemple #1
0
bool SimpleCompactHashtable::exists(u4 value) {
  assert(!DumpSharedSpaces, "run-time only");

  if (_entry_count == 0) {
    return false;
  }

  unsigned int hash = (unsigned int)value;
  int index = hash % _bucket_count;
  u4 bucket_info = _buckets[index];
  u4 bucket_offset = BUCKET_OFFSET(bucket_info);
  int bucket_type = BUCKET_TYPE(bucket_info);
  u4* entry = _entries + bucket_offset;

  if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
    return (entry[0] == value);
  } else {
    u4*entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]);
    while (entry <entry_max) {
      if (entry[1] == value) {
        return true;
      }
      entry += 2;
    }
    return false;
  }
}
// Write the compact table's entries
juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p,
                                            NumberSeq* summary) {
  uintx base_address = 0;
  uintx max_delta = 0;
  int num_compact_buckets = 0;
  if (_type == CompactHashtable<Symbol*, char>::_symbol_table) {
    base_address = uintx(MetaspaceShared::shared_rs()->base());
    max_delta    = uintx(MetaspaceShared::shared_rs()->size());
    assert(max_delta <= 0x7fffffff, "range check");
  } else {
    assert((_type == CompactHashtable<oop, char>::_string_table), "unknown table");
    assert(UseCompressedOops, "UseCompressedOops is required");
  }

  assert(p != NULL, "sanity");
  for (int index = 0; index < _num_buckets; index++) {
    juint count = 0;
    int bucket_size = _bucket_sizes[index];
    int bucket_type = BUCKET_TYPE(compact_table[index]);

    if (bucket_size == 1) {
      assert(bucket_type == COMPACT_BUCKET_TYPE, "Bad bucket type");
      num_compact_buckets ++;
    }
    for (Entry* tent = _buckets[index]; tent;
         tent = tent->next()) {
      if (bucket_type == REGULAR_BUCKET_TYPE) {
        *p++ = juint(tent->hash()); // write entry hash
      }
      if (_type == CompactHashtable<Symbol*, char>::_symbol_table) {
        uintx deltax = uintx(tent->value()) - base_address;
        assert(deltax < max_delta, "range check");
        juint delta = juint(deltax);
        *p++ = delta; // write entry offset
      } else {
        *p++ = oopDesc::encode_heap_oop(tent->string());
      }
      count ++;
    }
    assert(count == _bucket_sizes[index], "sanity");
  }

  // Adjust the hashentry_bytes in CompactHashtableStats. Each compact
  // bucket saves 4-byte.
  _stats->hashentry_bytes -= num_compact_buckets * 4;

  return p;
}
Exemple #3
0
inline void SimpleCompactHashtable::iterate(const I& iterator) {
  assert(!DumpSharedSpaces, "run-time only");
  for (u4 i = 0; i < _bucket_count; i++) {
    u4 bucket_info = _buckets[i];
    u4 bucket_offset = BUCKET_OFFSET(bucket_info);
    int bucket_type = BUCKET_TYPE(bucket_info);
    u4* entry = _entries + bucket_offset;

    if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
      iterator.do_value(_base_address, entry[0]);
    } else {
      u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
      while (entry < entry_max) {
        iterator.do_value(_base_address, entry[1]);
        entry += 2;
      }
    }
  }
}
template <class T, class N> void CompactHashtable<T, N>::symbols_do(SymbolClosure *cl) {
  assert(!DumpSharedSpaces, "run-time only");
  for (juint i = 0; i < _bucket_count; i ++) {
    juint bucket_info = _buckets[i];
    juint bucket_offset = BUCKET_OFFSET(bucket_info);
    int   bucket_type = BUCKET_TYPE(bucket_info);
    juint* bucket = _buckets + bucket_offset;
    juint* bucket_end = _buckets;

    Symbol* sym;
    if (bucket_type == COMPACT_BUCKET_TYPE) {
      sym = (Symbol*)((void*)(_base_address + bucket[0]));
      cl->do_symbol(&sym);
    } else {
      bucket_end += BUCKET_OFFSET(_buckets[i + 1]);
      while (bucket < bucket_end) {
        sym = (Symbol*)((void*)(_base_address + bucket[1]));
        cl->do_symbol(&sym);
        bucket += 2;
      }
    }
  }
}
// Write the compact table's entries
juint* CompactHashtableWriter::dump_buckets(juint* compact_table, juint* p,
                                            NumberSeq* summary) {
  uintx base_address = uintx(MetaspaceShared::shared_rs()->base());
  uintx max_delta    = uintx(MetaspaceShared::shared_rs()->size());
  assert(max_delta <= 0x7fffffff, "range check");
  int num_compact_buckets = 0;

  assert(p != NULL, "sanity");
  for (int index = 0; index < _num_buckets; index++) {
    juint count = 0;
    int bucket_size = _bucket_sizes[index];
    int bucket_type = BUCKET_TYPE(compact_table[index]);

    if (bucket_size == 1) {
      assert(bucket_type == COMPACT_BUCKET_TYPE, "Bad bucket type");
      num_compact_buckets ++;
    }
    for (Entry* tent = _buckets[index]; tent;
         tent = tent->next()) {
      if (bucket_type == REGULAR_BUCKET_TYPE) {
        *p++ = juint(tent->hash()); // write symbol hash
      }
      uintx deltax = uintx(tent->value()) - base_address;
      assert(deltax < max_delta, "range check");
      juint delta = juint(deltax);
      *p++ = delta; // write symbol offset
      count ++;
    }
    assert(count == _bucket_sizes[index], "sanity");
  }

  // Adjust the hashentry_bytes in CompactHashtableStats. Each compact
  // bucket saves 4-byte.
  _stats->hashentry_bytes -= num_compact_buckets * 4;

  return p;
}
template <class T, class N> void CompactHashtable<T, N>::oops_do(OopClosure* f) {
  assert(!DumpSharedSpaces, "run-time only");
  assert(_type == _string_table || _bucket_count == 0, "sanity");
  for (juint i = 0; i < _bucket_count; i ++) {
    juint bucket_info = _buckets[i];
    juint bucket_offset = BUCKET_OFFSET(bucket_info);
    int   bucket_type = BUCKET_TYPE(bucket_info);
    juint* bucket = _buckets + bucket_offset;
    juint* bucket_end = _buckets;

    narrowOop o;
    if (bucket_type == COMPACT_BUCKET_TYPE) {
      o = (narrowOop)bucket[0];
      f->do_oop(&o);
    } else {
      bucket_end += BUCKET_OFFSET(_buckets[i + 1]);
      while (bucket < bucket_end) {
        o = (narrowOop)bucket[1];
        f->do_oop(&o);
        bucket += 2;
      }
    }
  }
}