namespace v8 {
namespace internal {
-
// The number of sub caches covering the different types to cache.
static const int kSubCacheCount = 4;
// Initial size of each compilation cache table allocated.
static const int kInitialCacheSize = 64;
+// Index for the first generation in the cache.
+static const int kFirstGeneration = 0;
+
// The compilation cache consists of several generational sub-caches which uses
// this class as a base class. A sub-cache contains a compilation cache tables
// for each generation of the sub-cache. Since the same source code string has
// Get the compilation cache tables for a specific generation.
Handle<CompilationCacheTable> GetTable(int generation);
+ // Accessors for first generation.
+ Handle<CompilationCacheTable> GetFirstTable() {
+ return GetTable(kFirstGeneration);
+ }
+ void SetFirstTable(Handle<CompilationCacheTable> value) {
+ ASSERT(kFirstGeneration < generations_);
+ tables_[kFirstGeneration] = *value;
+ }
+
// Age the sub-cache by evicting the oldest generation and creating a new
// young generation.
void Age();
void Put(Handle<String> source, Handle<JSFunction> boilerplate);
private:
+ // Note: Returns a new hash table if operation results in expansion.
+ Handle<CompilationCacheTable> TablePut(Handle<String> source,
+ Handle<JSFunction> boilerplate);
+
bool HasOrigin(Handle<JSFunction> boilerplate,
Handle<Object> name,
int line_offset,
Handle<Context> context,
Handle<JSFunction> boilerplate);
+ private:
+ // Note: Returns a new hash table if operation results in expansion.
+ Handle<CompilationCacheTable> TablePut(Handle<String> source,
+ Handle<Context> context,
+ Handle<JSFunction> boilerplate);
+
DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
};
void Put(Handle<String> source,
JSRegExp::Flags flags,
Handle<FixedArray> data);
+ private:
+ // Note: Returns a new hash table if operation results in expansion.
+ Handle<CompilationCacheTable> TablePut(Handle<String> source,
+ JSRegExp::Flags flags,
+ Handle<FixedArray> data);
DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
};
}
+Handle<CompilationCacheTable> CompilationCacheScript::TablePut(
+ Handle<String> source,
+ Handle<JSFunction> boilerplate) {
+ CALL_HEAP_FUNCTION(GetFirstTable()->Put(*source, *boilerplate),
+ CompilationCacheTable);
+}
+
+
void CompilationCacheScript::Put(Handle<String> source,
Handle<JSFunction> boilerplate) {
HandleScope scope;
ASSERT(boilerplate->IsBoilerplate());
- Handle<CompilationCacheTable> table = GetTable(0);
- CALL_HEAP_FUNCTION_VOID(table->Put(*source, *boilerplate));
+ SetFirstTable(TablePut(source, boilerplate));
}
}
+Handle<CompilationCacheTable> CompilationCacheEval::TablePut(
+ Handle<String> source,
+ Handle<Context> context,
+ Handle<JSFunction> boilerplate) {
+ CALL_HEAP_FUNCTION(GetFirstTable()->PutEval(*source, *context, *boilerplate),
+ CompilationCacheTable);
+}
+
+
void CompilationCacheEval::Put(Handle<String> source,
Handle<Context> context,
Handle<JSFunction> boilerplate) {
HandleScope scope;
ASSERT(boilerplate->IsBoilerplate());
- Handle<CompilationCacheTable> table = GetTable(0);
- CALL_HEAP_FUNCTION_VOID(table->PutEval(*source, *context, *boilerplate));
+ SetFirstTable(TablePut(source, context, boilerplate));
}
}
+Handle<CompilationCacheTable> CompilationCacheRegExp::TablePut(
+ Handle<String> source,
+ JSRegExp::Flags flags,
+ Handle<FixedArray> data) {
+ CALL_HEAP_FUNCTION(GetFirstTable()->PutRegExp(*source, flags, *data),
+ CompilationCacheTable);
+}
+
+
void CompilationCacheRegExp::Put(Handle<String> source,
JSRegExp::Flags flags,
Handle<FixedArray> data) {
HandleScope scope;
- Handle<CompilationCacheTable> table = GetTable(0);
- CALL_HEAP_FUNCTION_VOID(table->PutRegExp(*source, flags, *data));
+ SetFirstTable(TablePut(source, flags, data));
}
property_count += 2; // Make space for two more properties.
}
Object* obj =
- StringDictionary::Allocate(property_count * 2);
+ StringDictionary::Allocate(property_count);
if (obj->IsFailure()) return obj;
StringDictionary* dictionary = StringDictionary::cast(obj);
template<typename Shape, typename Key>
Object* HashTable<Shape, Key>::Allocate(int at_least_space_for,
PretenureFlag pretenure) {
+ const int kMinCapacity = 32;
int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
- if (capacity < 32) {
- capacity = 32; // Guarantee min capacity.
+ if (capacity < kMinCapacity) {
+ capacity = kMinCapacity; // Guarantee min capacity.
} else if (capacity > HashTable::kMaxCapacity) {
return Failure::OutOfMemoryException();
}
result_double = HeapNumber::cast(new_double);
}
- int capacity = dict->Capacity();
- Object* obj = NumberDictionary::Allocate(dict->Capacity());
+ Object* obj = NumberDictionary::Allocate(dict->NumberOfElements());
if (obj->IsFailure()) return obj;
NumberDictionary* new_dict = NumberDictionary::cast(obj);
uint32_t pos = 0;
uint32_t undefs = 0;
+ int capacity = dict->Capacity();
for (int i = 0; i < capacity; i++) {
Object* k = dict->KeyAt(i);
if (dict->IsKey(k)) {