| 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 |