The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / test / cctest / test-dictionary.cc @ f230a1cf

History | View | Annotate | Download (7.98 KB)

1
// Copyright 2011 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#include "v8.h"
29

    
30
#include "api.h"
31
#include "debug.h"
32
#include "execution.h"
33
#include "factory.h"
34
#include "macro-assembler.h"
35
#include "objects.h"
36
#include "global-handles.h"
37
#include "cctest.h"
38

    
39
using namespace v8::internal;
40

    
41

    
42
TEST(ObjectHashTable) {
43
  LocalContext context;
44
  Isolate* isolate = CcTest::i_isolate();
45
  Factory* factory = isolate->factory();
46
  v8::HandleScope scope(context->GetIsolate());
47
  Handle<ObjectHashTable> table = factory->NewObjectHashTable(23);
48
  Handle<JSObject> a = factory->NewJSArray(7);
49
  Handle<JSObject> b = factory->NewJSArray(11);
50
  table = PutIntoObjectHashTable(table, a, b);
51
  CHECK_EQ(table->NumberOfElements(), 1);
52
  CHECK_EQ(table->Lookup(*a), *b);
53
  CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value());
54

    
55
  // Keys still have to be valid after objects were moved.
56
  CcTest::heap()->CollectGarbage(NEW_SPACE);
57
  CHECK_EQ(table->NumberOfElements(), 1);
58
  CHECK_EQ(table->Lookup(*a), *b);
59
  CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value());
60

    
61
  // Keys that are overwritten should not change number of elements.
62
  table = PutIntoObjectHashTable(table, a, factory->NewJSArray(13));
63
  CHECK_EQ(table->NumberOfElements(), 1);
64
  CHECK_NE(table->Lookup(*a), *b);
65

    
66
  // Keys mapped to the hole should be removed permanently.
67
  table = PutIntoObjectHashTable(table, a, factory->the_hole_value());
68
  CHECK_EQ(table->NumberOfElements(), 0);
69
  CHECK_EQ(table->NumberOfDeletedElements(), 1);
70
  CHECK_EQ(table->Lookup(*a), CcTest::heap()->the_hole_value());
71

    
72
  // Keys should map back to their respective values and also should get
73
  // an identity hash code generated.
74
  for (int i = 0; i < 100; i++) {
75
    Handle<JSReceiver> key = factory->NewJSArray(7);
76
    Handle<JSObject> value = factory->NewJSArray(11);
77
    table = PutIntoObjectHashTable(table, key, value);
78
    CHECK_EQ(table->NumberOfElements(), i + 1);
79
    CHECK_NE(table->FindEntry(*key), ObjectHashTable::kNotFound);
80
    CHECK_EQ(table->Lookup(*key), *value);
81
    CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
82
  }
83

    
84
  // Keys never added to the map which already have an identity hash
85
  // code should not be found.
86
  for (int i = 0; i < 100; i++) {
87
    Handle<JSReceiver> key = factory->NewJSArray(7);
88
    CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
89
    CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
90
    CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value());
91
    CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
92
  }
93

    
94
  // Keys that don't have an identity hash should not be found and also
95
  // should not get an identity hash code generated.
96
  for (int i = 0; i < 100; i++) {
97
    Handle<JSReceiver> key = factory->NewJSArray(7);
98
    CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value());
99
    CHECK_EQ(key->GetIdentityHash(OMIT_CREATION),
100
             CcTest::heap()->undefined_value());
101
  }
102
}
103

    
104

    
105
class ObjectHashTableTest: public ObjectHashTable {
106
 public:
107
  void insert(int entry, int key, int value) {
108
    set(EntryToIndex(entry), Smi::FromInt(key));
109
    set(EntryToIndex(entry) + 1, Smi::FromInt(value));
110
  }
111

    
112
  int lookup(int key) {
113
    return Smi::cast(Lookup(Smi::FromInt(key)))->value();
114
  }
115

    
116
  int capacity() {
117
    return Capacity();
118
  }
119
};
120

    
121

    
122
TEST(HashTableRehash) {
123
  LocalContext context;
124
  Isolate* isolate = CcTest::i_isolate();
125
  Factory* factory = isolate->factory();
126
  v8::HandleScope scope(context->GetIsolate());
127
  // Test almost filled table.
128
  {
129
    Handle<ObjectHashTable> table = factory->NewObjectHashTable(100);
130
    ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table);
131
    int capacity = t->capacity();
132
    for (int i = 0; i < capacity - 1; i++) {
133
      t->insert(i, i * i, i);
134
    }
135
    t->Rehash(Smi::FromInt(0));
136
    for (int i = 0; i < capacity - 1; i++) {
137
      CHECK_EQ(i, t->lookup(i * i));
138
    }
139
  }
140
  // Test half-filled table.
141
  {
142
    Handle<ObjectHashTable> table = factory->NewObjectHashTable(100);
143
    ObjectHashTableTest* t = reinterpret_cast<ObjectHashTableTest*>(*table);
144
    int capacity = t->capacity();
145
    for (int i = 0; i < capacity / 2; i++) {
146
      t->insert(i, i * i, i);
147
    }
148
    t->Rehash(Smi::FromInt(0));
149
    for (int i = 0; i < capacity / 2; i++) {
150
      CHECK_EQ(i, t->lookup(i * i));
151
    }
152
  }
153
}
154

    
155

    
156
#ifdef DEBUG
157
TEST(ObjectHashSetCausesGC) {
158
  i::FLAG_stress_compaction = false;
159
  LocalContext context;
160
  Isolate* isolate = CcTest::i_isolate();
161
  Factory* factory = isolate->factory();
162
  v8::HandleScope scope(context->GetIsolate());
163
  Handle<ObjectHashSet> table = factory->NewObjectHashSet(1);
164
  Handle<JSObject> key = factory->NewJSArray(0);
165
  v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key);
166

    
167
  // Force allocation of hash table backing store for hidden properties.
168
  key_obj->SetHiddenValue(v8_str("key 1"), v8_str("val 1"));
169
  key_obj->SetHiddenValue(v8_str("key 2"), v8_str("val 2"));
170
  key_obj->SetHiddenValue(v8_str("key 3"), v8_str("val 3"));
171

    
172
  // Simulate a full heap so that generating an identity hash code
173
  // in subsequent calls will request GC.
174
  SimulateFullSpace(CcTest::heap()->new_space());
175
  SimulateFullSpace(CcTest::heap()->old_pointer_space());
176

    
177
  // Calling Contains() should not cause GC ever.
178
  CHECK(!table->Contains(*key));
179

    
180
  // Calling Remove() should not cause GC ever.
181
  CHECK(!table->Remove(*key)->IsFailure());
182

    
183
  // Calling Add() should request GC by returning a failure.
184
  CHECK(table->Add(*key)->IsRetryAfterGC());
185
}
186
#endif
187

    
188

    
189
#ifdef DEBUG
190
TEST(ObjectHashTableCausesGC) {
191
  i::FLAG_stress_compaction = false;
192
  LocalContext context;
193
  Isolate* isolate = CcTest::i_isolate();
194
  Factory* factory = isolate->factory();
195
  v8::HandleScope scope(context->GetIsolate());
196
  Handle<ObjectHashTable> table = factory->NewObjectHashTable(1);
197
  Handle<JSObject> key = factory->NewJSArray(0);
198
  v8::Handle<v8::Object> key_obj = v8::Utils::ToLocal(key);
199

    
200
  // Force allocation of hash table backing store for hidden properties.
201
  key_obj->SetHiddenValue(v8_str("key 1"), v8_str("val 1"));
202
  key_obj->SetHiddenValue(v8_str("key 2"), v8_str("val 2"));
203
  key_obj->SetHiddenValue(v8_str("key 3"), v8_str("val 3"));
204

    
205
  // Simulate a full heap so that generating an identity hash code
206
  // in subsequent calls will request GC.
207
  SimulateFullSpace(CcTest::heap()->new_space());
208
  SimulateFullSpace(CcTest::heap()->old_pointer_space());
209

    
210
  // Calling Lookup() should not cause GC ever.
211
  CHECK(table->Lookup(*key)->IsTheHole());
212

    
213
  // Calling Put() should request GC by returning a failure.
214
  CHECK(table->Put(*key, *key)->IsRetryAfterGC());
215
}
216
#endif