Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(449)

Side by Side Diff: src/debug.cc

Issue 1145183004: Debugger: use weak cells to implement ScriptCache. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/debug.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/arguments.h" 8 #include "src/arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 486 MemCopy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
487 return storage + ArchiveSpacePerThread(); 487 return storage + ArchiveSpacePerThread();
488 } 488 }
489 489
490 490
491 int Debug::ArchiveSpacePerThread() { 491 int Debug::ArchiveSpacePerThread() {
492 return sizeof(ThreadLocal); 492 return sizeof(ThreadLocal);
493 } 493 }
494 494
495 495
496 ScriptCache::ScriptCache(Isolate* isolate) : HashMap(HashMap::PointersMatch), 496 ScriptCache::ScriptCache(Isolate* isolate) : isolate_(isolate) {
497 isolate_(isolate) {
498 Heap* heap = isolate_->heap(); 497 Heap* heap = isolate_->heap();
499 HandleScope scope(isolate_); 498 HandleScope scope(isolate_);
500 499
501 // Perform a GC to get rid of all unreferenced scripts. 500 // Perform a GC to get rid of all unreferenced scripts.
502 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache"); 501 heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
503 502
504 // Scan heap for Script objects. 503 // Scan heap for Script objects.
505 HeapIterator iterator(heap); 504 List<Handle<Script> > scripts;
506 DisallowHeapAllocation no_allocation; 505 {
507 506 HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
508 for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) { 507 DisallowHeapAllocation no_allocation;
509 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) { 508 for (HeapObject* obj = iterator.next(); obj != NULL;
510 Add(Handle<Script>(Script::cast(obj))); 509 obj = iterator.next()) {
510 if (obj->IsScript() && Script::cast(obj)->HasValidSource()) {
511 scripts.Add(Handle<Script>(Script::cast(obj)));
512 }
511 } 513 }
512 } 514 }
515
516 GlobalHandles* global_handles = isolate_->global_handles();
517 table_ = Handle<WeakValueHashTable>::cast(global_handles->Create(
518 Object::cast(*WeakValueHashTable::New(isolate_, scripts.length()))));
519 for (int i = 0; i < scripts.length(); i++) Add(scripts[i]);
513 } 520 }
514 521
515 522
516 void ScriptCache::Add(Handle<Script> script) { 523 void ScriptCache::Add(Handle<Script> script) {
517 GlobalHandles* global_handles = isolate_->global_handles(); 524 HandleScope scope(isolate_);
518 // Create an entry in the hash map for the script. 525 Handle<Smi> id(script->id(), isolate_);
519 int id = script->id()->value(); 526
520 HashMap::Entry* entry =
521 HashMap::LookupOrInsert(reinterpret_cast<void*>(id), Hash(id));
522 if (entry->value != NULL) {
523 #ifdef DEBUG 527 #ifdef DEBUG
524 // The code deserializer may introduce duplicate Script objects. 528 Handle<Object> lookup(table_->LookupWeak(id), isolate_);
525 // Assert that the Script objects with the same id have the same name. 529 if (!lookup->IsTheHole()) {
526 Handle<Script> found(reinterpret_cast<Script**>(entry->value)); 530 Handle<Script> found = Handle<Script>::cast(lookup);
527 DCHECK(script->id() == found->id()); 531 DCHECK(script->id() == found->id());
528 DCHECK(!script->name()->IsString() || 532 DCHECK(!script->name()->IsString() ||
529 String::cast(script->name())->Equals(String::cast(found->name()))); 533 String::cast(script->name())->Equals(String::cast(found->name())));
534 }
530 #endif 535 #endif
531 return; 536
532 } 537 Handle<WeakValueHashTable> new_table =
533 // Globalize the script object, make it weak and use the location of the 538 WeakValueHashTable::PutWeak(table_, id, script);
534 // global handle as the value in the hash map. 539
535 Handle<Script> script_ = 540 if (new_table.is_identical_to(table_)) return;
536 Handle<Script>::cast(global_handles->Create(*script)); 541 GlobalHandles* global_handles = isolate_->global_handles();
537 GlobalHandles::MakeWeak(reinterpret_cast<Object**>(script_.location()), 542 global_handles->Destroy(Handle<Object>::cast(table_).location());
538 this, 543 table_ = Handle<WeakValueHashTable>::cast(
539 ScriptCache::HandleWeakScript); 544 global_handles->Create(Object::cast(*new_table)));
540 entry->value = script_.location();
541 } 545 }
542 546
543 547
544 Handle<FixedArray> ScriptCache::GetScripts() { 548 ScriptCache::~ScriptCache() {
545 Factory* factory = isolate_->factory(); 549 isolate_->global_handles()->Destroy(Handle<Object>::cast(table_).location());
546 Handle<FixedArray> instances = factory->NewFixedArray(occupancy()); 550 table_ = Handle<WeakValueHashTable>();
547 int count = 0;
548 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
549 DCHECK(entry->value != NULL);
550 if (entry->value != NULL) {
551 instances->set(count, *reinterpret_cast<Script**>(entry->value));
552 count++;
553 }
554 }
555 return instances;
556 } 551 }
557 552
558 553
559 void ScriptCache::Clear() {
560 // Iterate the script cache to get rid of all the weak handles.
561 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) {
562 DCHECK(entry != NULL);
563 Object** location = reinterpret_cast<Object**>(entry->value);
564 DCHECK((*location)->IsScript());
565 GlobalHandles::ClearWeakness(location);
566 GlobalHandles::Destroy(location);
567 }
568 // Clear the content of the hash map.
569 HashMap::Clear();
570 }
571
572
573 void ScriptCache::HandleWeakScript(
574 const v8::WeakCallbackData<v8::Value, void>& data) {
575 // Retrieve the script identifier.
576 Handle<Object> object = Utils::OpenHandle(*data.GetValue());
577 int id = Handle<Script>::cast(object)->id()->value();
578 void* key = reinterpret_cast<void*>(id);
579 uint32_t hash = Hash(id);
580
581 // Remove the corresponding entry from the cache.
582 ScriptCache* script_cache =
583 reinterpret_cast<ScriptCache*>(data.GetParameter());
584 HashMap::Entry* entry = script_cache->Lookup(key, hash);
585 DCHECK_NOT_NULL(entry);
586 Object** location = reinterpret_cast<Object**>(entry->value);
587 script_cache->Remove(key, hash);
588
589 // Clear the weak handle.
590 GlobalHandles::Destroy(location);
591 }
592
593
594 void Debug::HandlePhantomDebugInfo( 554 void Debug::HandlePhantomDebugInfo(
595 const v8::WeakCallbackInfo<DebugInfoListNode>& data) { 555 const v8::WeakCallbackInfo<DebugInfoListNode>& data) {
596 DebugInfoListNode* node = data.GetParameter(); 556 DebugInfoListNode* node = data.GetParameter();
597 node->ClearInfo(); 557 node->ClearInfo();
598 Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug(); 558 Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
599 debug->RemoveDebugInfo(node); 559 debug->RemoveDebugInfo(node);
600 #ifdef DEBUG 560 #ifdef DEBUG
601 for (DebugInfoListNode* n = debug->debug_info_list_; 561 for (DebugInfoListNode* n = debug->debug_info_list_;
602 n != NULL; 562 n != NULL;
603 n = n->next()) { 563 n = n->next()) {
(...skipping 2797 matching lines...) Expand 10 before | Expand all | Expand 10 after
3401 logger_->DebugEvent("Put", message.text()); 3361 logger_->DebugEvent("Put", message.text());
3402 } 3362 }
3403 3363
3404 3364
3405 void LockingCommandMessageQueue::Clear() { 3365 void LockingCommandMessageQueue::Clear() {
3406 base::LockGuard<base::Mutex> lock_guard(&mutex_); 3366 base::LockGuard<base::Mutex> lock_guard(&mutex_);
3407 queue_.Clear(); 3367 queue_.Clear();
3408 } 3368 }
3409 3369
3410 } } // namespace v8::internal 3370 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698