1ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 2ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// Redistribution and use in source and binary forms, with or without 3ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// modification, are permitted provided that the following conditions are 4ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// met: 5ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// 6ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// * Redistributions of source code must retain the above copyright 7ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// notice, this list of conditions and the following disclaimer. 8ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// * Redistributions in binary form must reproduce the above 9ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// copyright notice, this list of conditions and the following 10ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// disclaimer in the documentation and/or other materials provided 11ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// with the distribution. 12ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// * Neither the name of Google Inc. nor the names of its 13ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// contributors may be used to endorse or promote products derived 14ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// from this software without specific prior written permission. 15ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// 16ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 284f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org#include <utility> 294f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org 30196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 31ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 32196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/global-handles.h" 33196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/snapshot.h" 34196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "test/cctest/cctest.h" 35ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 36ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgusing namespace v8::internal; 37ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 38ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 39ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic Isolate* GetIsolateFrom(LocalContext* context) { 40ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org return reinterpret_cast<Isolate*>((*context)->GetIsolate()); 41ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 42ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 43ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 44ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic Handle<JSWeakSet> AllocateJSWeakSet(Isolate* isolate) { 45ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Factory* factory = isolate->factory(); 46ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Map> map = factory->NewMap(JS_WEAK_SET_TYPE, JSWeakSet::kSize); 47ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject> weakset_obj = factory->NewJSObjectFromMap(map); 48ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSWeakSet> weakset(JSWeakSet::cast(*weakset_obj)); 49e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // Do not leak handles for the hash table, it would make entries strong. 50e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org { 51e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org HandleScope scope(isolate); 52e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 1); 53e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org weakset->set_table(*table); 54e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org } 55ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org return weakset; 56ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 57ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 58ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic void PutIntoWeakSet(Handle<JSWeakSet> weakset, 59ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject> key, 60ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> value) { 61057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<ObjectHashTable> table = ObjectHashTable::Put( 62ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<ObjectHashTable>(ObjectHashTable::cast(weakset->table())), 63ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject>(JSObject::cast(*key)), 64ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org value); 65ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org weakset->set_table(*table); 66ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 67ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 68ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgstatic int NumberOfWeakCalls = 0; 694f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.orgstatic void WeakPointerCallback( 704f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org const v8::WeakCallbackData<v8::Value, void>& data) { 714f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org std::pair<v8::Persistent<v8::Value>*, int>* p = 724f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>( 734f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org data.GetParameter()); 74e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(1234, p->second); 75ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org NumberOfWeakCalls++; 764f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org p->first->Reset(); 77ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 78ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 79ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 80ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgTEST(WeakSet_Weakness) { 81ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org FLAG_incremental_marking = false; 82ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org LocalContext context; 83ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Isolate* isolate = GetIsolateFrom(&context); 84ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Factory* factory = isolate->factory(); 85ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Heap* heap = isolate->heap(); 86ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 87ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSWeakSet> weakset = AllocateJSWeakSet(isolate); 88ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org GlobalHandles* global_handles = isolate->global_handles(); 89ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 90ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Keep global reference to the key. 91ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> key; 92ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org { 93ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 94ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 95ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject> object = factory->NewJSObjectFromMap(map); 96ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org key = global_handles->Create(*object); 97ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 98ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(!global_handles->IsWeak(key.location())); 99ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 100ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Put entry into weak set. 101ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org { 102ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 103ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org PutIntoWeakSet(weakset, 104ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject>(JSObject::cast(*key)), 105ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Smi>(Smi::FromInt(23), isolate)); 106ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 107ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(1, ObjectHashTable::cast(weakset->table())->NumberOfElements()); 108ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 109ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Force a full GC. 110ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(false); 111ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(0, NumberOfWeakCalls); 112ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(1, ObjectHashTable::cast(weakset->table())->NumberOfElements()); 113ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ( 114ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 0, ObjectHashTable::cast(weakset->table())->NumberOfDeletedElements()); 115ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 116ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Make the global reference to the key weak. 117ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org { 118ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 1194f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org std::pair<Handle<Object>*, int> handle_and_id(&key, 1234); 1204f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org GlobalHandles::MakeWeak(key.location(), 1214f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org reinterpret_cast<void*>(&handle_and_id), 1224f99be9ff2091451687891a05d99cc31990de709hpayer@chromium.org &WeakPointerCallback); 123ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 124ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(global_handles->IsWeak(key.location())); 125ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 126ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Force a full GC. 127ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Perform two consecutive GCs because the first one will only clear 128ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // weak references whereas the second one will also clear weak sets. 129ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(false); 130ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(1, NumberOfWeakCalls); 131ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(1, ObjectHashTable::cast(weakset->table())->NumberOfElements()); 132ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ( 133ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 0, ObjectHashTable::cast(weakset->table())->NumberOfDeletedElements()); 134ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(false); 135ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(1, NumberOfWeakCalls); 136ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(0, ObjectHashTable::cast(weakset->table())->NumberOfElements()); 137ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ( 138ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1, ObjectHashTable::cast(weakset->table())->NumberOfDeletedElements()); 139ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 140ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 141ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 142ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgTEST(WeakSet_Shrinking) { 143ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org LocalContext context; 144ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Isolate* isolate = GetIsolateFrom(&context); 145ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Factory* factory = isolate->factory(); 146ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Heap* heap = isolate->heap(); 147ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 148ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSWeakSet> weakset = AllocateJSWeakSet(isolate); 149ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 150ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Check initial capacity. 151ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(32, ObjectHashTable::cast(weakset->table())->Capacity()); 152ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 153ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Fill up weak set to trigger capacity change. 154ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org { 155ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 156ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 157ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org for (int i = 0; i < 32; i++) { 158ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject> object = factory->NewJSObjectFromMap(map); 159ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org PutIntoWeakSet(weakset, object, Handle<Smi>(Smi::FromInt(i), isolate)); 160ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 161ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 162ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 163ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Check increased capacity. 164ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(128, ObjectHashTable::cast(weakset->table())->Capacity()); 165ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 166ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Force a full GC. 167ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(32, ObjectHashTable::cast(weakset->table())->NumberOfElements()); 168ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ( 169ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 0, ObjectHashTable::cast(weakset->table())->NumberOfDeletedElements()); 170ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(false); 171ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(0, ObjectHashTable::cast(weakset->table())->NumberOfElements()); 172ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ( 173ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 32, ObjectHashTable::cast(weakset->table())->NumberOfDeletedElements()); 174ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 175ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Check shrunk capacity. 176ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK_EQ(32, ObjectHashTable::cast(weakset->table())->Capacity()); 177ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 178ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 179ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 180ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// Test that weak set values on an evacuation candidate which are not reachable 181ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// by other paths are correctly recorded in the slots buffer. 182ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgTEST(WeakSet_Regress2060a) { 183c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org if (i::FLAG_never_compact) return; 184ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org FLAG_always_compact = true; 185ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org LocalContext context; 186ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Isolate* isolate = GetIsolateFrom(&context); 187ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Factory* factory = isolate->factory(); 188ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Heap* heap = isolate->heap(); 189ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 1903c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Handle<JSFunction> function = factory->NewFunction( 1913c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org factory->function_string()); 192ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject> key = factory->NewJSObject(function); 193ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSWeakSet> weakset = AllocateJSWeakSet(isolate); 194ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 195ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Start second old-space page so that values land on evacuation candidate. 196ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Page* first_page = heap->old_pointer_space()->anchor()->next_page(); 197ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org factory->NewFixedArray(900 * KB / kPointerSize, TENURED); 198ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 199ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Fill up weak set with values on an evacuation candidate. 200ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org { 201ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 202ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org for (int i = 0; i < 32; i++) { 203ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject> object = factory->NewJSObject(function, TENURED); 204ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(!heap->InNewSpace(object->address())); 205ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(!first_page->Contains(object->address())); 206ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org PutIntoWeakSet(weakset, key, object); 207ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 208ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 209ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 210ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Force compacting garbage collection. 211ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(FLAG_always_compact); 212ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(Heap::kNoGCFlags); 213ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 214ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 215ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 216ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// Test that weak set keys on an evacuation candidate which are reachable by 217ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org// other strong paths are correctly recorded in the slots buffer. 218ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgTEST(WeakSet_Regress2060b) { 219c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org if (i::FLAG_never_compact) return; 220ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org FLAG_always_compact = true; 221ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#ifdef VERIFY_HEAP 222ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org FLAG_verify_heap = true; 223ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org#endif 224ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 225ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org LocalContext context; 226ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Isolate* isolate = GetIsolateFrom(&context); 227ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Factory* factory = isolate->factory(); 228ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Heap* heap = isolate->heap(); 229ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org HandleScope scope(isolate); 2303c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Handle<JSFunction> function = factory->NewFunction( 2313c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org factory->function_string()); 232ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 233ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Start second old-space page so that keys land on evacuation candidate. 234ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Page* first_page = heap->old_pointer_space()->anchor()->next_page(); 235ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org factory->NewFixedArray(900 * KB / kPointerSize, TENURED); 236ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 237ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Fill up weak set with keys on an evacuation candidate. 238ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSObject> keys[32]; 239ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org for (int i = 0; i < 32; i++) { 240ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org keys[i] = factory->NewJSObject(function, TENURED); 241ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(!heap->InNewSpace(keys[i]->address())); 242ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(!first_page->Contains(keys[i]->address())); 243ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 244ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<JSWeakSet> weakset = AllocateJSWeakSet(isolate); 245ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org for (int i = 0; i < 32; i++) { 246ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org PutIntoWeakSet(weakset, 247ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org keys[i], 248ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Smi>(Smi::FromInt(i), isolate)); 249ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 250ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 251ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Force compacting garbage collection. The subsequent collections are used 252ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // to verify that key references were actually updated. 253ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org CHECK(FLAG_always_compact); 254ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(Heap::kNoGCFlags); 255ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(Heap::kNoGCFlags); 256ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org heap->CollectAllGarbage(Heap::kNoGCFlags); 257ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 258