OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |