in_debug_event_listener_(false),
break_on_exception_(false),
break_on_uncaught_exception_(false),
- script_cache_(NULL),
debug_info_list_(NULL),
isolate_(isolate) {
ThreadInit();
}
-ScriptCache::ScriptCache(Isolate* isolate) : isolate_(isolate) {
- Heap* heap = isolate_->heap();
- HandleScope scope(isolate_);
-
- DCHECK(isolate_->debug()->is_active());
-
- // Perform a GC to get rid of all unreferenced scripts.
- heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
-
- // Scan heap for Script objects.
- List<Handle<Script> > scripts;
- {
- HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
- DisallowHeapAllocation no_allocation;
- for (HeapObject* obj = iterator.next(); obj != NULL;
- obj = iterator.next()) {
- if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
- scripts.Add(Handle<Script>(Script::cast(obj)));
- }
- }
- }
-
- GlobalHandles* global_handles = isolate_->global_handles();
- table_ = Handle<WeakValueHashTable>::cast(global_handles->Create(
- Object::cast(*WeakValueHashTable::New(isolate_, scripts.length()))));
- for (int i = 0; i < scripts.length(); i++) Add(scripts[i]);
-}
-
-
-void ScriptCache::Add(Handle<Script> script) {
- HandleScope scope(isolate_);
- Handle<Smi> id(script->id(), isolate_);
-
-#ifdef DEBUG
- Handle<Object> lookup(table_->LookupWeak(id), isolate_);
- if (!lookup->IsTheHole()) {
- Handle<Script> found = Handle<Script>::cast(lookup);
- DCHECK(script->id() == found->id());
- DCHECK(!script->name()->IsString() ||
- String::cast(script->name())->Equals(String::cast(found->name())));
- }
-#endif
-
- Handle<WeakValueHashTable> new_table =
- WeakValueHashTable::PutWeak(table_, id, script);
-
- if (new_table.is_identical_to(table_)) return;
- GlobalHandles* global_handles = isolate_->global_handles();
- global_handles->Destroy(Handle<Object>::cast(table_).location());
- table_ = Handle<WeakValueHashTable>::cast(
- global_handles->Create(Object::cast(*new_table)));
-}
-
-
-ScriptCache::~ScriptCache() {
- isolate_->global_handles()->Destroy(Handle<Object>::cast(table_).location());
- table_ = Handle<WeakValueHashTable>();
-}
-
-
DebugInfoListNode::DebugInfoListNode(DebugInfo* debug_info): next_(NULL) {
// Globalize the request debug info object and make it weak.
GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
// Return debugger is not loaded.
if (!is_loaded()) return;
- // Clear the script cache.
- if (script_cache_ != NULL) {
- delete script_cache_;
- script_cache_ = NULL;
- }
-
// Clear debugger context global handle.
GlobalHandles::Destroy(Handle<Object>::cast(debug_context_).location());
debug_context_ = Handle<Context>();
Handle<FixedArray> Debug::GetLoadedScripts() {
- // Create and fill the script cache when the loaded scripts is requested for
- // the first time.
- if (script_cache_ == NULL) script_cache_ = new ScriptCache(isolate_);
-
- // Perform GC to get unreferenced scripts evicted from the cache before
- // returning the content.
isolate_->heap()->CollectAllGarbage(Heap::kNoGCFlags,
"Debug::GetLoadedScripts");
-
- // Get the scripts from the cache.
- return script_cache_->GetScripts();
+ Factory* factory = isolate_->factory();
+ if (!factory->script_list()->IsWeakFixedArray()) {
+ return factory->empty_fixed_array();
+ }
+ Handle<WeakFixedArray> array =
+ Handle<WeakFixedArray>::cast(factory->script_list());
+ Handle<FixedArray> results = factory->NewFixedArray(array->Length());
+ int length = 0;
+ for (int i = 0; i < array->Length(); ++i) {
+ Object* item = array->Get(i);
+ if (item->IsScript() && Script::cast(item)->HasValidSource()) {
+ results->set(length++, item);
+ }
+ }
+ results->Shrink(length);
+ return results;
}
// Handle debugger actions when a new script is compiled.
void Debug::OnAfterCompile(Handle<Script> script) {
- // Add the newly compiled script to the script cache.
- if (script_cache_ != NULL) script_cache_->Add(script);
-
if (ignore_events()) return;
if (in_debug_scope()) {
};
-// Cache of all script objects in the heap. When a script is added a weak handle
-// to it is created and that weak handle is stored in the cache. The weak handle
-// callback takes care of removing the script from the cache. The key used in
-// the cache is the script id.
-class ScriptCache {
- public:
- explicit ScriptCache(Isolate* isolate);
- ~ScriptCache();
-
- // Add script to the cache.
- void Add(Handle<Script> script);
-
- // Return the scripts in the cache.
- Handle<FixedArray> GetScripts() {
- return WeakValueHashTable::GetWeakValues(table_);
- }
-
- private:
- Isolate* isolate_;
- Handle<WeakValueHashTable> table_;
-};
-
-
// Linked list holding debug info objects. The debug info objects are kept as
// weak handles to avoid a debug info object to keep a function alive.
class DebugInfoListNode {
bool break_on_exception_;
bool break_on_uncaught_exception_;
- ScriptCache* script_cache_; // Cache of all scripts in the heap.
DebugInfoListNode* debug_info_list_; // List of active debug info objects.
// Storage location for jump when exiting debug break calls.
script->set_shared_function_infos(Smi::FromInt(0));
script->set_flags(Smi::FromInt(0));
+ heap->set_script_list(*WeakFixedArray::Add(script_list(), script));
return script;
}
*WeakHashTable::New(isolate(), 16, USE_DEFAULT_MINIMUM_CAPACITY,
TENURED));
+ set_script_list(Smi::FromInt(0));
+
Handle<SeededNumberDictionary> slow_element_dictionary =
SeededNumberDictionary::New(isolate(), 0, TENURED);
slow_element_dictionary->set_requires_slow_elements();
case kPolymorphicCodeCacheRootIndex:
case kEmptyScriptRootIndex:
case kSymbolRegistryRootIndex:
+ case kScriptListRootIndex:
case kMaterializedObjectsRootIndex:
case kAllocationSitesScratchpadRootIndex:
case kMicrotaskQueueRootIndex:
V(Cell, undefined_cell, UndefinedCell) \
V(JSObject, observation_state, ObservationState) \
V(Object, symbol_registry, SymbolRegistry) \
+ V(Object, script_list, ScriptList) \
V(SeededNumberDictionary, empty_slow_element_dictionary, \
EmptySlowElementDictionary) \
V(FixedArray, materialized_objects, MaterializedObjects) \
}
-bool Object::IsWeakValueHashTable() const { return IsHashTable(); }
-
-
bool Object::IsDictionary() const {
return IsHashTable() &&
this != HeapObject::cast(this)->GetHeap()->string_table();
CAST_ACCESSOR(WeakCell)
CAST_ACCESSOR(WeakFixedArray)
CAST_ACCESSOR(WeakHashTable)
-CAST_ACCESSOR(WeakValueHashTable)
// static
}
-#ifdef DEBUG
-Object* WeakValueHashTable::LookupWeak(Handle<Object> key) {
- Object* value = Lookup(key);
- if (value->IsWeakCell() && !WeakCell::cast(value)->cleared()) {
- value = WeakCell::cast(value)->value();
- }
- return value;
-}
-#endif // DEBUG
-
-
-Handle<WeakValueHashTable> WeakValueHashTable::PutWeak(
- Handle<WeakValueHashTable> table, Handle<Object> key,
- Handle<HeapObject> value) {
- Handle<WeakCell> cell = value->GetIsolate()->factory()->NewWeakCell(value);
- return Handle<WeakValueHashTable>::cast(
- Put(Handle<ObjectHashTable>::cast(table), key, cell));
-}
-
-
-Handle<FixedArray> WeakValueHashTable::GetWeakValues(
- Handle<WeakValueHashTable> table) {
- Isolate* isolate = table->GetIsolate();
- uint32_t capacity = table->Capacity();
- Handle<FixedArray> results = isolate->factory()->NewFixedArray(capacity);
- int length = 0;
- for (uint32_t i = 0; i < capacity; i++) {
- uint32_t key_index = table->EntryToIndex(i);
- Object* key = table->get(key_index);
- if (!table->IsKey(key)) continue;
- uint32_t value_index = table->EntryToValueIndex(i);
- WeakCell* value_cell = WeakCell::cast(table->get(value_index));
- if (value_cell->cleared()) {
- table->RemoveEntry(i);
- } else {
- results->set(length++, value_cell->value());
- }
- }
- results->Shrink(length);
- return results;
-}
-
-
template<class Derived, class Iterator, int entrysize>
Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Allocate(
Isolate* isolate, int capacity, PretenureFlag pretenure) {
V(WeakCell) \
V(ObjectHashTable) \
V(WeakHashTable) \
- V(WeakValueHashTable) \
V(OrderedHashTable)
// Object is the abstract superclass for all classes in the
};
-class WeakValueHashTable : public ObjectHashTable {
- public:
- DECLARE_CAST(WeakValueHashTable)
-
-#ifdef DEBUG
- // Looks up the value associated with the given key. The hole value is
- // returned in case the key is not present.
- Object* LookupWeak(Handle<Object> key);
-#endif // DEBUG
-
- // Adds (or overwrites) the value associated with the given key. Mapping a
- // key to the hole value causes removal of the whole entry.
- MUST_USE_RESULT static Handle<WeakValueHashTable> PutWeak(
- Handle<WeakValueHashTable> table, Handle<Object> key,
- Handle<HeapObject> value);
-
- static Handle<FixedArray> GetWeakValues(Handle<WeakValueHashTable> table);
-};
-
-
// ScopeInfo represents information about different scopes of a source
// program and the allocation of the scope's variables. Scope information
// is stored in a compressed form in ScopeInfo objects and is used