Index: runtime/vm/symbols.cc |
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc |
index 03aa24174caa185b397155d73f4670e57133c092..a0b6c83718669bb525e9cb6b4cbc1e0d61b6bded 100644 |
--- a/runtime/vm/symbols.cc |
+++ b/runtime/vm/symbols.cc |
@@ -307,41 +307,6 @@ void Symbols::InitOnceFromSnapshot(Isolate* vm_isolate) { |
} |
-void Symbols::AddPredefinedSymbolsToIsolate() { |
- // Should only be run by regular Dart isolates. |
- Thread* thread = Thread::Current(); |
- Isolate* isolate = thread->isolate(); |
- Zone* zone = thread->zone(); |
- ASSERT(isolate != Dart::vm_isolate()); |
- String& str = String::Handle(zone); |
- |
- SymbolTable table(zone, isolate->object_store()->symbol_table()); |
- |
- // Set up all the predefined string symbols and create symbols for |
- // language keywords. |
- for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { |
- str = OneByteString::New(names[i], Heap::kOld); |
- str.Hash(); |
- str ^= table.InsertOrGet(str); |
- str.SetCanonical(); // Make canonical once entered. |
- } |
- |
- // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast. |
- for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { |
- intptr_t idx = (kNullCharId + c); |
- ASSERT(idx < kMaxPredefinedId); |
- ASSERT(Utf::IsLatin1(c)); |
- uint8_t ch = static_cast<uint8_t>(c); |
- str = OneByteString::New(&ch, 1, Heap::kOld); |
- str.Hash(); |
- str ^= table.InsertOrGet(str); |
- str.SetCanonical(); // Make canonical once entered. |
- } |
- |
- isolate->object_store()->set_symbol_table(table.Release()); |
-} |
- |
- |
void Symbols::SetupSymbolTable(Isolate* isolate) { |
ASSERT(isolate != NULL); |
@@ -354,48 +319,54 @@ void Symbols::SetupSymbolTable(Isolate* isolate) { |
} |
-intptr_t Symbols::Compact(Isolate* isolate) { |
- ASSERT(isolate != Dart::vm_isolate()); |
+RawArray* Symbols::UnifiedSymbolTable() { |
+ Thread* thread = Thread::Current(); |
+ Isolate* isolate = thread->isolate(); |
+ Zone* zone = thread->zone(); |
- Zone* zone = Thread::Current()->zone(); |
- intptr_t initial_size = -1; |
- intptr_t final_size = -1; |
+ ASSERT(thread->IsMutatorThread()); |
+ ASSERT(isolate->background_compiler() == NULL); |
- // 1. Build a collection of all the predefined symbols so they are |
- // strongly referenced (the read only handles are not traced). |
- { |
- SymbolTable table(zone, isolate->object_store()->symbol_table()); |
- initial_size = table.NumOccupied(); |
- |
- if (Object::vm_isolate_snapshot_object_table().Length() == 0) { |
- GrowableObjectArray& predefined_symbols = GrowableObjectArray::Handle( |
- GrowableObjectArray::New(kMaxPredefinedId)); |
- String& symbol = String::Handle(); |
- for (intptr_t i = 1; i < Symbols::kNullCharId; i++) { |
- const unsigned char* name = |
- reinterpret_cast<const unsigned char*>(names[i]); |
- symbol ^= table.GetOrNull(Latin1Array(name, strlen(names[i]))); |
- ASSERT(!symbol.IsNull()); |
- predefined_symbols.Add(symbol); |
- } |
- for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) { |
- intptr_t idx = (kNullCharId + c); |
- ASSERT(idx < kMaxPredefinedId); |
- ASSERT(Utf::IsLatin1(c)); |
- uint8_t ch = static_cast<uint8_t>(c); |
- symbol ^= table.GetOrNull(Latin1Array(&ch, 1)); |
- ASSERT(!symbol.IsNull()); |
- predefined_symbols.Add(symbol); |
- } |
- } |
- table.Release(); |
+ SymbolTable vm_table(zone, |
+ Dart::vm_isolate()->object_store()->symbol_table()); |
+ SymbolTable table(zone, isolate->object_store()->symbol_table()); |
+ intptr_t unified_size = vm_table.NumOccupied() + table.NumOccupied(); |
+ SymbolTable unified_table(zone, HashTables::New<SymbolTable>(unified_size, |
+ Heap::kOld)); |
+ String& symbol = String::Handle(zone); |
+ |
+ SymbolTable::Iterator vm_iter(&vm_table); |
+ while (vm_iter.MoveNext()) { |
+ symbol ^= vm_table.GetKey(vm_iter.Current()); |
+ ASSERT(!symbol.IsNull()); |
+ bool present = unified_table.Insert(symbol); |
+ ASSERT(!present); |
+ } |
+ vm_table.Release(); |
+ |
+ SymbolTable::Iterator iter(&table); |
+ while (iter.MoveNext()) { |
+ symbol ^= table.GetKey(iter.Current()); |
+ ASSERT(!symbol.IsNull()); |
+ bool present = unified_table.Insert(symbol); |
+ ASSERT(!present); |
} |
+ table.Release(); |
+ |
+ return unified_table.Release().raw(); |
+} |
- // 2. Knock out the symbol table and do a full garbage collection. |
+ |
+#if defined(DART_PRECOMPILER) |
+void Symbols::Compact(Isolate* isolate) { |
+ ASSERT(isolate != Dart::vm_isolate()); |
+ Zone* zone = Thread::Current()->zone(); |
+ |
+ // 1. Drop the symbol table and do a full garbage collection. |
isolate->object_store()->set_symbol_table(Object::empty_array()); |
isolate->heap()->CollectAllGarbage(); |
- // 3. Walk the heap and build a new table from surviving symbols. |
+ // 2. Walk the heap to find surviving symbols. |
GrowableArray<String*> symbols; |
class SymbolCollector : public ObjectVisitor { |
public: |
@@ -418,24 +389,21 @@ intptr_t Symbols::Compact(Isolate* isolate) { |
SymbolCollector visitor(Thread::Current(), &symbols); |
isolate->heap()->IterateObjects(&visitor); |
- { |
- Array& array = |
- Array::Handle(HashTables::New<SymbolTable>(symbols.length() * 4 / 3, |
- Heap::kOld)); |
- SymbolTable table(zone, array.raw()); |
- for (intptr_t i = 0; i < symbols.length(); i++) { |
- String& symbol = *symbols[i]; |
- ASSERT(symbol.IsString()); |
- ASSERT(symbol.IsCanonical()); |
- bool present = table.Insert(symbol); |
- ASSERT(!present); |
- } |
- final_size = table.NumOccupied(); |
- isolate->object_store()->set_symbol_table(table.Release()); |
+ // 3. Build a new table from the surviving symbols. |
+ Array& array = |
+ Array::Handle(zone, HashTables::New<SymbolTable>(symbols.length() * 4 / 3, |
+ Heap::kOld)); |
+ SymbolTable table(zone, array.raw()); |
+ for (intptr_t i = 0; i < symbols.length(); i++) { |
+ String& symbol = *symbols[i]; |
+ ASSERT(symbol.IsString()); |
+ ASSERT(symbol.IsCanonical()); |
+ bool present = table.Insert(symbol); |
+ ASSERT(!present); |
} |
- |
- return initial_size - final_size; |
+ isolate->object_store()->set_symbol_table(table.Release()); |
} |
+#endif // DART_PRECOMPILER |
void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) { |
@@ -655,7 +623,6 @@ RawString* Symbols::Lookup(Thread* thread, const StringType& str) { |
symbol ^= table.GetOrNull(str); |
table.Release(); |
} |
- |
ASSERT(symbol.IsNull() || symbol.IsSymbol()); |
ASSERT(symbol.IsNull() || symbol.HasHash()); |
return symbol.raw(); |
@@ -758,7 +725,7 @@ void Symbols::DumpStats() { |
} |
-intptr_t Symbols::LookupVMSymbol(RawObject* obj) { |
+intptr_t Symbols::LookupPredefinedSymbol(RawObject* obj) { |
for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) { |
if (symbol_handles_[i]->raw() == obj) { |
return (i + kMaxPredefinedObjectIds); |
@@ -768,8 +735,8 @@ intptr_t Symbols::LookupVMSymbol(RawObject* obj) { |
} |
-RawObject* Symbols::GetVMSymbol(intptr_t object_id) { |
- ASSERT(IsVMSymbolId(object_id)); |
+RawObject* Symbols::GetPredefinedSymbol(intptr_t object_id) { |
+ ASSERT(IsPredefinedSymbolId(object_id)); |
intptr_t i = (object_id - kMaxPredefinedObjectIds); |
if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) { |
return symbol_handles_[i]->raw(); |