From c53fa9677312c1c61d31e7ecd444f42d2a78d3d3 Mon Sep 17 00:00:00 2001 From: "jarin@chromium.org" Date: Mon, 10 Nov 2014 05:50:11 +0000 Subject: [PATCH] Resolve race condition with GC in CompilationCacheTable::Put. The trouble is that the AsHandle method can allocate and thus invoke GC, which could empty the table while we are updating it. BUG=chromium:430880 LOG=N R=verwaest@chromium.org Review URL: https://codereview.chromium.org/700913003 Cr-Commit-Position: refs/heads/master@{#25229} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25229 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects.cc | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/objects.cc b/src/objects.cc index 63b7312c51..2b5b567112 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -15014,16 +15014,19 @@ Handle CompilationCacheTable::Put( Handle shared(context->closure()->shared()); StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY, RelocInfo::kNoPosition); - int entry = cache->FindEntry(&key); - if (entry != kNotFound) { + { Handle k = key.AsHandle(isolate); - cache->set(EntryToIndex(entry), *k); - cache->set(EntryToIndex(entry) + 1, *value); - return cache; + DisallowHeapAllocation no_allocation_scope; + int entry = cache->FindEntry(&key); + if (entry != kNotFound) { + cache->set(EntryToIndex(entry), *k); + cache->set(EntryToIndex(entry) + 1, *value); + return cache; + } } cache = EnsureCapacity(cache, 1, &key); - entry = cache->FindInsertionEntry(key.Hash()); + int entry = cache->FindInsertionEntry(key.Hash()); Handle k = isolate->factory()->NewNumber(static_cast(key.Hash())); cache->set(EntryToIndex(entry), *k); @@ -15039,16 +15042,19 @@ Handle CompilationCacheTable::PutEval( int scope_position) { Isolate* isolate = cache->GetIsolate(); StringSharedKey key(src, outer_info, value->strict_mode(), scope_position); - int entry = cache->FindEntry(&key); - if (entry != kNotFound) { + { Handle k = key.AsHandle(isolate); - cache->set(EntryToIndex(entry), *k); - cache->set(EntryToIndex(entry) + 1, *value); - return cache; + DisallowHeapAllocation no_allocation_scope; + int entry = cache->FindEntry(&key); + if (entry != kNotFound) { + cache->set(EntryToIndex(entry), *k); + cache->set(EntryToIndex(entry) + 1, *value); + return cache; + } } cache = EnsureCapacity(cache, 1, &key); - entry = cache->FindInsertionEntry(key.Hash()); + int entry = cache->FindInsertionEntry(key.Hash()); Handle k = isolate->factory()->NewNumber(static_cast(key.Hash())); cache->set(EntryToIndex(entry), *k);