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 "src/v8.h" 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "test/cctest/cctest.h" 3069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h" 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/debug.h" 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/execution.h" 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/factory.h" 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/macro-assembler.h" 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/objects.h" 3869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 3969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochusing namespace v8::internal; 4069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace { 423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename HashMap> 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void TestHashMap(Handle<HashMap> table) { 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> a = factory->NewJSArray(7); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> b = factory->NewJSArray(11); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table = HashMap::Put(table, a, b); 5269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(table->NumberOfElements(), 1); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(a), *b); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // When the key does not exist in the map, Lookup returns the hole. 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(b), CcTest::heap()->the_hole_value()); 5669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Keys still have to be valid after objects were moved. 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CcTest::heap()->CollectGarbage(NEW_SPACE); 5969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(table->NumberOfElements(), 1); 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(a), *b); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(b), CcTest::heap()->the_hole_value()); 6269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 6369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch // Keys that are overwritten should not change number of elements. 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table = HashMap::Put(table, a, factory->NewJSArray(13)); 6569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(table->NumberOfElements(), 1); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(table->Lookup(a), *b); 6769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keys that have been removed are mapped to the hole. 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool was_present = false; 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table = HashMap::Remove(table, a, &was_present); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(was_present); 7269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(table->NumberOfElements(), 0); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(a), CcTest::heap()->the_hole_value()); 7469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Keys should map back to their respective values and also should get 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // an identity hash code generated. 7769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch for (int i = 0; i < 100; i++) { 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSReceiver> key = factory->NewJSArray(7); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> value = factory->NewJSArray(11); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table = HashMap::Put(table, key, value); 8169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CHECK_EQ(table->NumberOfElements(), i + 1); 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_NE(table->FindEntry(key), HashMap::kNotFound); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(key), *value); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(key->GetIdentityHash()->IsSmi()); 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Keys never added to the map which already have an identity hash 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // code should not be found. 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < 100; i++) { 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSReceiver> key = factory->NewJSArray(7); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(JSReceiver::GetOrCreateIdentityHash(key)->IsSmi()); 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->FindEntry(key), HashMap::kNotFound); 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(key), CcTest::heap()->the_hole_value()); 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(key->GetIdentityHash()->IsSmi()); 9569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 9669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Keys that don't have an identity hash should not be found and also 983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // should not get an identity hash code generated. 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < 100; i++) { 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSReceiver> key = factory->NewJSArray(7); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(table->Lookup(key), CcTest::heap()->the_hole_value()); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* identity_hash = key->GetIdentityHash(); 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(identity_hash, CcTest::heap()->undefined_value()); 10469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch } 10569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HashMap) { 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext context; 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(context->GetIsolate()); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestHashMap(ObjectHashTable::New(isolate, 23)); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestHashMap(isolate->factory()->NewOrderedHashMap()); 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ObjectHashTableTest: public ObjectHashTable { 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void insert(int entry, int key, int value) { 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set(EntryToIndex(entry), Smi::FromInt(key)); 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set(EntryToIndex(entry) + 1, Smi::FromInt(value)); 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int lookup(int key) { 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> key_obj(Smi::FromInt(key), GetIsolate()); 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Smi::cast(Lookup(key_obj))->value(); 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int capacity() { 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Capacity(); 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(HashTableRehash) { 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LocalContext context; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(context->GetIsolate()); 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test almost filled table. 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 100); 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int capacity = t->capacity(); 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < capacity - 1; i++) { 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t->insert(i, i * i, i); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t->Rehash(handle(Smi::FromInt(0), isolate)); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < capacity - 1; i++) { 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(i, t->lookup(i * i)); 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Test half-filled table. 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 100); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int capacity = t->capacity(); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < capacity / 2; i++) { 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t->insert(i, i * i, i); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch t->Rehash(handle(Smi::FromInt(0), isolate)); 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < capacity / 2; i++) { 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK_EQ(i, t->lookup(i * i)); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class HashSet> 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void TestHashSetCausesGC(Handle<HashSet> table) { 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> key = factory->NewJSArray(0); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key); 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Force allocation of hash table backing store for hidden properties. 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_obj->SetHiddenValue(v8_str("key 1"), v8_str("val 1")); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_obj->SetHiddenValue(v8_str("key 2"), v8_str("val 2")); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_obj->SetHiddenValue(v8_str("key 3"), v8_str("val 3")); 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Simulate a full heap so that generating an identity hash code 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // in subsequent calls will request GC. 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SimulateFullSpace(CcTest::heap()->new_space()); 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SimulateFullSpace(CcTest::heap()->old_pointer_space()); 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Calling Contains() should not cause GC ever. 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int gc_count = isolate->heap()->gc_count(); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!table->Contains(key)); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(gc_count == isolate->heap()->gc_count()); 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calling Remove() will not cause GC in this case. 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool was_present = false; 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table = HashSet::Remove(table, key, &was_present); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(!was_present); 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(gc_count == isolate->heap()->gc_count()); 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calling Add() should cause GC. 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch table = HashSet::Add(table, key); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(gc_count < isolate->heap()->gc_count()); 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ObjectHashSetCausesGC) { 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::FLAG_stress_compaction = false; 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext context; 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(context->GetIsolate()); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestHashSetCausesGC(isolate->factory()->NewOrderedHashSet()); 2103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef DEBUG 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<class HashMap> 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void TestHashMapCausesGC(Handle<HashMap> table) { 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Factory* factory = isolate->factory(); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> key = factory->NewJSArray(0); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key); 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Force allocation of hash table backing store for hidden properties. 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_obj->SetHiddenValue(v8_str("key 1"), v8_str("val 1")); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_obj->SetHiddenValue(v8_str("key 2"), v8_str("val 2")); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch key_obj->SetHiddenValue(v8_str("key 3"), v8_str("val 3")); 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Simulate a full heap so that generating an identity hash code 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // in subsequent calls will request GC. 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SimulateFullSpace(CcTest::heap()->new_space()); 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SimulateFullSpace(CcTest::heap()->old_pointer_space()); 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Calling Lookup() should not cause GC ever. 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(table->Lookup(key)->IsTheHole()); 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Calling Put() should request GC by returning a failure. 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int gc_count = isolate->heap()->gc_count(); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch HashMap::Put(table, key, key); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(gc_count < isolate->heap()->gc_count()); 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTEST(ObjectHashTableCausesGC) { 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch i::FLAG_stress_compaction = false; 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LocalContext context; 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch v8::HandleScope scope(context->GetIsolate()); 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = CcTest::i_isolate(); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestHashMapCausesGC(ObjectHashTable::New(isolate, 1)); 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TestHashMapCausesGC(isolate->factory()->NewOrderedHashMap()); 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 255