<commit_before>// Copyright 2011 Google Inc. All Rights Reserved.

#include "intern_table.h"

#include "UniquePtr.h"
#include "utf.h"

namespace art {

InternTable::InternTable() : intern_table_lock_("InternTable lock") {
}

size_t InternTable::Size() const {
  MutexLock mu(intern_table_lock_);
  return strong_interns_.size() + weak_interns_.size();
}

void InternTable::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
  MutexLock mu(intern_table_lock_);
  typedef Table::const_iterator It; // TODO: C++0x auto
  for (It it = strong_interns_.begin(), end = strong_interns_.end(); it != end; ++it) {
    visitor(it->second, arg);
  }
  // Note: we deliberately don't visit the weak_interns_ table.
}

String* InternTable::Lookup(Table& table, String* s, uint32_t hash_code) {
  intern_table_lock_.AssertHeld();
  typedef Table::const_iterator It; // TODO: C++0x auto
  for (It it = table.find(hash_code), end = table.end(); it != end; ++it) {
    String* existing_string = it->second;
    if (existing_string->Equals(s)) {
      return existing_string;
    }
  }
  return NULL;
}

String* InternTable::Insert(Table& table, String* s, uint32_t hash_code) {
  intern_table_lock_.AssertHeld();
  table.insert(std::make_pair(hash_code, s));
  return s;
}

void InternTable::RegisterStrong(String* s) {
  MutexLock mu(intern_table_lock_);
  Insert(strong_interns_, s, s->GetHashCode());
}

void InternTable::Remove(Table& table, const String* s, uint32_t hash_code) {
  intern_table_lock_.AssertHeld();
  typedef Table::const_iterator It; // TODO: C++0x auto
  for (It it = table.find(hash_code), end = table.end(); it != end; ++it) {
    if (it->second == s) {
      table.erase(it);
      return;
    }
  }
}

String* InternTable::Insert(String* s, bool is_strong) {
  MutexLock mu(intern_table_lock_);

  DCHECK(s != NULL);
  uint32_t hash_code = s->GetHashCode();

  if (is_strong) {
    // Check the strong table for a match.
    String* strong = Lookup(strong_interns_, s, hash_code);
    if (strong != NULL) {
      return strong;
    }

    // There is no match in the strong table, check the weak table.
    String* weak = Lookup(weak_interns_, s, hash_code);
    if (weak != NULL) {
      // A match was found in the weak table. Promote to the strong table.
      Remove(weak_interns_, weak, hash_code);
      return Insert(strong_interns_, weak, hash_code);
    }

    // No match in the strong table or the weak table. Insert into the strong table.
    return Insert(strong_interns_, s, hash_code);
  }

  // Check the strong table for a match.
  String* strong = Lookup(strong_interns_, s, hash_code);
  if (strong != NULL) {
    return strong;
  }
  // Check the weak table for a match.
  String* weak = Lookup(weak_interns_, s, hash_code);
  if (weak != NULL) {
    return weak;
  }
  // Insert into the weak table.
  return Insert(weak_interns_, s, hash_code);
}

String* InternTable::InternStrong(int32_t utf16_length, const char* utf8_data) {
  return Insert(String::AllocFromModifiedUtf8(utf16_length, utf8_data), true);
}

String* InternTable::InternStrong(const char* utf8_data) {
  return Insert(String::AllocFromModifiedUtf8(utf8_data), true);
}

String* InternTable::InternStrong(String* s) {
  return Insert(s, true);
}

String* InternTable::InternWeak(String* s) {
  return Insert(s, false);
}

bool InternTable::ContainsWeak(String* s) {
  MutexLock mu(intern_table_lock_);
  const String* found = Lookup(weak_interns_, s, s->GetHashCode());<commit_msg>Be careful of failed allocations in the intern table.<commit_after>// Copyright 2011 Google Inc. All Rights Reserved.

#include "intern_table.h"

#include "UniquePtr.h"
#include "utf.h"

namespace art {

InternTable::InternTable() : intern_table_lock_("InternTable lock") {
}

size_t InternTable::Size() const {
  MutexLock mu(intern_table_lock_);
  return strong_interns_.size() + weak_interns_.size();
}

void InternTable::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
  MutexLock mu(intern_table_lock_);
  typedef Table::const_iterator It; // TODO: C++0x auto
  for (It it = strong_interns_.begin(), end = strong_interns_.end(); it != end; ++it) {
    visitor(it->second, arg);
  }
  // Note: we deliberately don't visit the weak_interns_ table.
}

String* InternTable::Lookup(Table& table, String* s, uint32_t hash_code) {
  intern_table_lock_.AssertHeld();
  typedef Table::const_iterator It; // TODO: C++0x auto
  for (It it = table.find(hash_code), end = table.end(); it != end; ++it) {
    String* existing_string = it->second;
    if (existing_string->Equals(s)) {
      return existing_string;
    }
  }
  return NULL;
}

String* InternTable::Insert(Table& table, String* s, uint32_t hash_code) {
  intern_table_lock_.AssertHeld();
  table.insert(std::make_pair(hash_code, s));
  return s;
}

void InternTable::RegisterStrong(String* s) {
  MutexLock mu(intern_table_lock_);
  Insert(strong_interns_, s, s->GetHashCode());
}

void InternTable::Remove(Table& table, const String* s, uint32_t hash_code) {
  intern_table_lock_.AssertHeld();
  typedef Table::const_iterator It; // TODO: C++0x auto
  for (It it = table.find(hash_code), end = table.end(); it != end; ++it) {
    if (it->second == s) {
      table.erase(it);
      return;
    }
  }
}

String* InternTable::Insert(String* s, bool is_strong) {
  MutexLock mu(intern_table_lock_);

  DCHECK(s != NULL);
  uint32_t hash_code = s->GetHashCode();

  if (is_strong) {
    // Check the strong table for a match.
    String* strong = Lookup(strong_interns_, s, hash_code);
    if (strong != NULL) {
      return strong;
    }

    // There is no match in the strong table, check the weak table.
    String* weak = Lookup(weak_interns_, s, hash_code);
    if (weak != NULL) {
      // A match was found in the weak table. Promote to the strong table.
      Remove(weak_interns_, weak, hash_code);
      return Insert(strong_interns_, weak, hash_code);
    }

    // No match in the strong table or the weak table. Insert into the strong table.
    return Insert(strong_interns_, s, hash_code);
  }

  // Check the strong table for a match.
  String* strong = Lookup(strong_interns_, s, hash_code);
  if (strong != NULL) {
    return strong;
  }
  // Check the weak table for a match.
  String* weak = Lookup(weak_interns_, s, hash_code);
  if (weak != NULL) {
    return weak;
  }
  // Insert into the weak table.
  return Insert(weak_interns_, s, hash_code);
}

String* InternTable::InternStrong(int32_t utf16_length, const char* utf8_data) {
  return InternStrong(String::AllocFromModifiedUtf8(utf16_length, utf8_data));
}

String* InternTable::InternStrong(const char* utf8_data) {
  return InternStrong(String::AllocFromModifiedUtf8(utf8_data));
}

String* InternTable::InternStrong(String* s) {
  if (s == NULL) {
    return NULL;
  }
  return Insert(s, true);
}

String* InternTable::InternWeak(String* s) {
  if (s == NULL) {
    return NULL;
  }
  return Insert(s, false);
}

bool InternTable::ContainsWeak(String* s) {
  MutexLock mu(intern_table_lock_);
  const String* found = Lookup(weak_interns_, s, s->GetHashCode());
{'fraction_non_alphanumeric': 0.13127467569091936, 'fraction_numerical': 0.007614213197969543, 'mean_word_length': 4.125, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '468625', 'n_tokens_mistral': 2426, 'n_tokens_neox': 2383, 'n_words': 643}