Bug 704848 - reduce space required by nsEffectiveTLDService with more preprocessing; r=jduell

This commit is contained in:
Nathan Froyd
2012-09-11 07:42:23 -04:00
parent 67b8caf2cc
commit 864ece3f81
5 changed files with 74 additions and 19 deletions

View File

@@ -70,6 +70,7 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../mime \
-I$(srcdir)/../cache \
-I$(srcdir)/../protocol/about \
-I../dns \
$(foreach d,$(filter-out about,$(NECKO_PROTOCOLS)), \
-I$(srcdir)/../protocol/$(d)) \
$(NULL)

View File

@@ -56,6 +56,7 @@ DEFINES += -DIMPL_NS_NET
# Generate the include file containing compact, static definitions
# for effective TLD data.
nsEffectiveTLDService.$(OBJ_SUFFIX): etld_data.inc
nsEffectiveTLDService.h: etld_data.inc
etld_data.inc: $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat
$(PYTHON) $(srcdir)/prepare_tlds.py $(srcdir)/effective_tld_names.dat > etld_data.inc

View File

@@ -22,9 +22,39 @@ NS_IMPL_ISUPPORTS1(nsEffectiveTLDService, nsIEffectiveTLDService)
// ----------------------------------------------------------------------
static const ETLDEntry gEntries[] =
#define ETLD_STR_NUM_1(line) str##line
#define ETLD_STR_NUM(line) ETLD_STR_NUM_1(line)
#define ETLD_ENTRY_OFFSET(name) offsetof(struct etld_string_list, ETLD_STR_NUM(__LINE__))
const ETLDEntry nsDomainEntry::entries[] = {
#define ETLD_ENTRY(name, ex, wild) { ETLD_ENTRY_OFFSET(name), ex, wild },
#include "etld_data.inc"
;
#undef ETLD_ENTRY
};
const union nsDomainEntry::etld_strings nsDomainEntry::strings = {
{
#define ETLD_ENTRY(name, ex, wild) name,
#include "etld_data.inc"
#undef ETLD_ENTRY
}
};
// Dummy function to statically ensure that our indices don't overflow
// the storage provided for them.
void
nsDomainEntry::FuncForStaticAsserts(void)
{
#define ETLD_ENTRY(name, ex, wild) \
MOZ_STATIC_ASSERT(ETLD_ENTRY_OFFSET(name) < (1 << ETLD_ENTRY_N_INDEX_BITS), \
"invalid strtab index");
#include "etld_data.inc"
#undef ETLD_ENTRY
}
#undef ETLD_ENTRY_OFFSET
#undef ETLD_STR_NUM
#undef ETLD_STR_NUM1
// ----------------------------------------------------------------------
@@ -33,28 +63,31 @@ nsEffectiveTLDService::Init()
{
NS_TIME_FUNCTION;
const ETLDEntry *entries = nsDomainEntry::entries;
// We'll probably have to rehash at least once, since nsTHashtable doesn't
// use a perfect hash, but at least we'll save a few rehashes along the way.
// Next optimization here is to precompute the hash using something like
// gperf, but one step at a time. :-)
mHash.Init(ArrayLength(gEntries) - 1);
mHash.Init(ArrayLength(nsDomainEntry::entries));
nsresult rv;
mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
// Initialize eTLD hash from static array
for (uint32_t i = 0; i < ArrayLength(gEntries) - 1; i++) {
for (uint32_t i = 0; i < ArrayLength(nsDomainEntry::entries); i++) {
const char *domain = nsDomainEntry::GetEffectiveTLDName(entries[i].strtab_index);
#ifdef DEBUG
nsDependentCString name(gEntries[i].domain);
nsAutoCString normalizedName(gEntries[i].domain);
nsDependentCString name(domain);
nsAutoCString normalizedName(domain);
NS_ASSERTION(NS_SUCCEEDED(NormalizeHostname(normalizedName)),
"normalization failure!");
NS_ASSERTION(name.Equals(normalizedName), "domain not normalized!");
#endif
nsDomainEntry *entry = mHash.PutEntry(gEntries[i].domain);
nsDomainEntry *entry = mHash.PutEntry(domain);
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
entry->SetData(&gEntries[i]);
entry->SetData(&entries[i]);
}
return NS_OK;
}

View File

@@ -12,17 +12,20 @@
class nsIIDNService;
#define ETLD_ENTRY_N_INDEX_BITS 30
// struct for static data generated from effective_tld_names.dat
struct ETLDEntry {
const char* domain;
bool exception;
bool wild;
uint32_t strtab_index : ETLD_ENTRY_N_INDEX_BITS;
uint32_t exception : 1;
uint32_t wild : 1;
};
// hash entry class
class nsDomainEntry : public PLDHashEntryHdr
{
friend class nsEffectiveTLDService;
public:
// Hash methods
typedef const char* KeyType;
@@ -45,12 +48,12 @@ public:
KeyType GetKey() const
{
return mData->domain;
return GetEffectiveTLDName(mData->strtab_index);
}
bool KeyEquals(KeyTypePointer aKey) const
{
return !strcmp(mData->domain, aKey);
return !strcmp(GetKey(), aKey);
}
static KeyTypePointer KeyToPointer(KeyType aKey)
@@ -73,8 +76,28 @@ public:
bool IsException() { return mData->exception; }
bool IsWild() { return mData->wild; }
static const char *GetEffectiveTLDName(size_t idx)
{
return strings.strtab + idx;
}
private:
const ETLDEntry* mData;
#define ETLD_STR_NUM_1(line) str##line
#define ETLD_STR_NUM(line) ETLD_STR_NUM_1(line)
struct etld_string_list {
#define ETLD_ENTRY(name, ex, wild) char ETLD_STR_NUM(__LINE__)[sizeof(name)];
#include "etld_data.inc"
#undef ETLD_ENTRY
};
static const union etld_strings {
struct etld_string_list list;
char strtab[1];
} strings;
static const ETLDEntry entries[];
void FuncForStaticAsserts(void);
#undef ETLD_STR_NUM
#undef ETLD_STR_NUM1
};
class nsEffectiveTLDService MOZ_FINAL : public nsIEffectiveTLDService

View File

@@ -104,16 +104,13 @@ def main():
def boolStr(b):
if b:
return "PR_TRUE"
return "PR_FALSE"
return "true"
return "false"
print "{"
for etld in getEffectiveTLDs(sys.argv[1]):
exception = boolStr(etld.exception())
wild = boolStr(etld.wild())
print ' { "%s", %s, %s },' % (etld.domain(), exception, wild)
print " { nullptr, PR_FALSE, PR_FALSE }"
print "}"
print 'ETLD_ENTRY("%s", %s, %s)' % (etld.domain(), exception, wild)
if __name__ == '__main__':
main()