Beispiel #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;
  }
}
Beispiel #2
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;
      }
    }
  }
}
/////////////////////////////////////////////////////////////
//
// The CompactHashtable implementation
//
template <class T, class N> const char* CompactHashtable<T, N>::init(const char* buffer) {
  assert(!DumpSharedSpaces, "run-time only");
  juint*p = (juint*)buffer;
  juint upper = *p++;
  juint lower = *p++;
  _base_address = uintx(jlong_from(upper, lower));
  _entry_count = *p++;
  _bucket_count = *p++;
  _buckets = p;
  _table_end_offset = BUCKET_OFFSET(p[_bucket_count]); // located at the end of the bucket_info table

  juint *end = _buckets + _table_end_offset;
  return (const char*)end;
}
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;
      }
    }
  }
}