169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// Redistribution and use in source and binary forms, with or without 369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// modification, are permitted provided that the following conditions are 469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// met: 569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Redistributions of source code must retain the above copyright 769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// notice, this list of conditions and the following disclaimer. 869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Redistributions in binary form must reproduce the above 969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// copyright notice, this list of conditions and the following 1069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// disclaimer in the documentation and/or other materials provided 1169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// with the distribution. 1269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// * Neither the name of Google Inc. nor the names of its 1369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// contributors may be used to endorse or promote products derived 1469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// from this software without specific prior written permission. 1569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// 1669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <utility> 2969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/snapshot.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h" 3569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochusing namespace v8::internal; 3769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Isolate* GetIsolateFrom(LocalContext* context) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reinterpret_cast<Isolate*>((*context)->GetIsolate()); 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Handle<JSWeakMap> AllocateJSWeakMap(Isolate* isolate) { 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = factory->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> weakmap_obj = factory->NewJSObjectFromMap(map); 4869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSWeakMap> weakmap(JSWeakMap::cast(*weakmap_obj)); 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do not leak handles for the hash table, it would make entries strong. 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 1); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch weakmap->set_table(*table); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 5569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return weakmap; 5669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 5769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochstatic void PutIntoWeakMap(Handle<JSWeakMap> weakmap, 5969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject> key, 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> value) { 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ObjectHashTable> table = ObjectHashTable::Put( 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<ObjectHashTable>(ObjectHashTable::cast(weakmap->table())), 6369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<JSObject>(JSObject::cast(*key)), 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch value); 6569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch weakmap->set_table(*table); 6669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 6769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochstatic int NumberOfWeakCalls = 0; 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void WeakPointerCallback( 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const v8::WeakCallbackData<v8::Value, void>& data) { 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::pair<v8::Persistent<v8::Value>*, int>* p = 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch data.GetParameter()); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(1234, p->second); 7569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch NumberOfWeakCalls++; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch p->first->Reset(); 7769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 7869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 7969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 8069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(Weakness) { 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_incremental_marking = false; 8269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext context; 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = GetIsolateFrom(&context); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = isolate->heap(); 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate); 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalHandles* global_handles = isolate->global_handles(); 8969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 9069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Keep global reference to the key. 9169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> key; 9269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> object = factory->NewJSObjectFromMap(map); 9669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch key = global_handles->Create(*object); 9769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 9869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(!global_handles->IsWeak(key.location())); 9969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Put entry into weak map. 10169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PutIntoWeakMap(weakmap, 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject>(JSObject::cast(*key)), 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Smi>(Smi::FromInt(23), isolate)); 10669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements()); 10869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 10969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Force a full GC. 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(false); 11169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(0, NumberOfWeakCalls); 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements()); 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ( 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements()); 11569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 11669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Make the global reference to the key weak. 11769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch std::pair<Handle<Object>*, int> handle_and_id(&key, 1234); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GlobalHandles::MakeWeak(key.location(), 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reinterpret_cast<void*>(&handle_and_id), 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &WeakPointerCallback); 12369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 12469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK(global_handles->IsWeak(key.location())); 12569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 12669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Force a full GC. 12769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Perform two consecutive GCs because the first one will only clear 12869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // weak references whereas the second one will also clear weak maps. 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(false); 13069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(1, NumberOfWeakCalls); 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements()); 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ( 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements()); 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(false); 13569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(1, NumberOfWeakCalls); 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, ObjectHashTable::cast(weakmap->table())->NumberOfElements()); 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ( 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements()); 13969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 14069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 14169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 14269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen MurdochTEST(Shrinking) { 14369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch LocalContext context; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = GetIsolateFrom(&context); 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = isolate->heap(); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate); 14969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 15069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Check initial capacity. 1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->Capacity()); 15269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 15369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Fill up weak map to trigger capacity change. 15469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch { 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 15769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < 32; i++) { 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> object = factory->NewJSObjectFromMap(map); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PutIntoWeakMap(weakmap, object, Handle<Smi>(Smi::FromInt(i), isolate)); 16069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 16169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 16269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 16369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Check increased capacity. 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(128, ObjectHashTable::cast(weakmap->table())->Capacity()); 16569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 16669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Force a full GC. 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->NumberOfElements()); 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ( 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements()); 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(false); 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(0, ObjectHashTable::cast(weakmap->table())->NumberOfElements()); 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ( 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 32, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements()); 17469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 17569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Check shrunk capacity. 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(32, ObjectHashTable::cast(weakmap->table())->Capacity()); 17769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test that weak map values on an evacuation candidate which are not reachable 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// by other paths are correctly recorded in the slots buffer. 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Regress2060a) { 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i::FLAG_never_compact) return; 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_always_compact = true; 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext context; 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = GetIsolateFrom(&context); 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = isolate->heap(); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> function = factory->NewFunction( 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->function_string()); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> key = factory->NewJSObject(function); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Start second old-space page so that values land on evacuation candidate. 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Page* first_page = heap->old_pointer_space()->anchor()->next_page(); 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewFixedArray(900 * KB / kPointerSize, TENURED); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fill up weak map with values on an evacuation candidate. 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < 32; i++) { 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> object = factory->NewJSObject(function, TENURED); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!heap->InNewSpace(object->address())); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!first_page->Contains(object->address())); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PutIntoWeakMap(weakmap, key, object); 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Force compacting garbage collection. 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(FLAG_always_compact); 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(Heap::kNoGCFlags); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Test that weak map keys on an evacuation candidate which are reachable by 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// other strong paths are correctly recorded in the slots buffer. 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Regress2060b) { 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i::FLAG_never_compact) return; 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_always_compact = true; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef VERIFY_HEAP 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FLAG_verify_heap = true; 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext context; 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = GetIsolateFrom(&context); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = isolate->heap(); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSFunction> function = factory->NewFunction( 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->function_string()); 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Start second old-space page so that keys land on evacuation candidate. 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Page* first_page = heap->old_pointer_space()->anchor()->next_page(); 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch factory->NewFixedArray(900 * KB / kPointerSize, TENURED); 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fill up weak map with keys on an evacuation candidate. 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> keys[32]; 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < 32; i++) { 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch keys[i] = factory->NewJSObject(function, TENURED); 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!heap->InNewSpace(keys[i]->address())); 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!first_page->Contains(keys[i]->address())); 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate); 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < 32; i++) { 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PutIntoWeakMap(weakmap, 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch keys[i], 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Smi>(Smi::FromInt(i), isolate)); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Force compacting garbage collection. The subsequent collections are used 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to verify that key references were actually updated. 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(FLAG_always_compact); 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(Heap::kNoGCFlags); 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(Heap::kNoGCFlags); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(Heap::kNoGCFlags); 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(Regress399527) { 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::InitializeVM(); 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(CcTest::isolate()); 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Heap* heap = isolate->heap(); 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HandleScope scope(isolate); 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateJSWeakMap(isolate); 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SimulateIncrementalMarking(heap); 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The weak map is marked black here but leaving the handle scope will make 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the object unreachable. Aborting incremental marking will clear all the 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // marking bits which makes the weak map garbage. 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 275