| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 Isolate* GetIsolate() const { return isolate_; } | 50 Isolate* GetIsolate() const { return isolate_; } |
| 51 | 51 |
| 52 private: | 52 private: |
| 53 Isolate* isolate_; | 53 Isolate* isolate_; |
| 54 }; | 54 }; |
| 55 } | 55 } |
| 56 | 56 |
| 57 TEST(PerIsolateState) { | 57 TEST(PerIsolateState) { |
| 58 HarmonyIsolate isolate; | 58 HarmonyIsolate isolate; |
| 59 HandleScope scope(isolate.GetIsolate()); | 59 HandleScope scope(isolate.GetIsolate()); |
| 60 LocalContext context1; | 60 v8::LocalContext context1; |
| 61 CompileRun( | 61 CompileRun( |
| 62 "var count = 0;" | 62 "var count = 0;" |
| 63 "var calls = 0;" | 63 "var calls = 0;" |
| 64 "var observer = function(records) { count = records.length; calls++ };" | 64 "var observer = function(records) { count = records.length; calls++ };" |
| 65 "var obj = {};" | 65 "var obj = {};" |
| 66 "Object.observe(obj, observer);"); | 66 "Object.observe(obj, observer);"); |
| 67 Handle<Value> observer = CompileRun("observer"); | 67 Handle<Value> observer = CompileRun("observer"); |
| 68 Handle<Value> obj = CompileRun("obj"); | 68 Handle<Value> obj = CompileRun("obj"); |
| 69 Handle<Value> notify_fun1 = CompileRun( | 69 Handle<Value> notify_fun1 = CompileRun( |
| 70 "(function() { obj.foo = 'bar'; })"); | 70 "(function() { obj.foo = 'bar'; })"); |
| 71 Handle<Value> notify_fun2; | 71 Handle<Value> notify_fun2; |
| 72 { | 72 { |
| 73 LocalContext context2; | 73 v8::LocalContext context2; |
| 74 context2->Global()->Set(String::New("obj"), obj); | 74 context2->Global()->Set(String::New("obj"), obj); |
| 75 notify_fun2 = CompileRun( | 75 notify_fun2 = CompileRun( |
| 76 "(function() { obj.foo = 'baz'; })"); | 76 "(function() { obj.foo = 'baz'; })"); |
| 77 } | 77 } |
| 78 Handle<Value> notify_fun3; | 78 Handle<Value> notify_fun3; |
| 79 { | 79 { |
| 80 LocalContext context3; | 80 v8::LocalContext context3; |
| 81 context3->Global()->Set(String::New("obj"), obj); | 81 context3->Global()->Set(String::New("obj"), obj); |
| 82 notify_fun3 = CompileRun( | 82 notify_fun3 = CompileRun( |
| 83 "(function() { obj.foo = 'bat'; })"); | 83 "(function() { obj.foo = 'bat'; })"); |
| 84 } | 84 } |
| 85 { | 85 { |
| 86 LocalContext context4; | 86 v8::LocalContext context4; |
| 87 context4->Global()->Set(String::New("observer"), observer); | 87 context4->Global()->Set(String::New("observer"), observer); |
| 88 context4->Global()->Set(String::New("fun1"), notify_fun1); | 88 context4->Global()->Set(String::New("fun1"), notify_fun1); |
| 89 context4->Global()->Set(String::New("fun2"), notify_fun2); | 89 context4->Global()->Set(String::New("fun2"), notify_fun2); |
| 90 context4->Global()->Set(String::New("fun3"), notify_fun3); | 90 context4->Global()->Set(String::New("fun3"), notify_fun3); |
| 91 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); | 91 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); |
| 92 } | 92 } |
| 93 CHECK_EQ(1, CompileRun("calls")->Int32Value()); | 93 CHECK_EQ(1, CompileRun("calls")->Int32Value()); |
| 94 CHECK_EQ(3, CompileRun("count")->Int32Value()); | 94 CHECK_EQ(3, CompileRun("count")->Int32Value()); |
| 95 } | 95 } |
| 96 | 96 |
| 97 TEST(EndOfMicrotaskDelivery) { | 97 TEST(EndOfMicrotaskDelivery) { |
| 98 HarmonyIsolate isolate; | 98 HarmonyIsolate isolate; |
| 99 HandleScope scope(isolate.GetIsolate()); | 99 HandleScope scope(isolate.GetIsolate()); |
| 100 LocalContext context; | 100 v8::LocalContext context; |
| 101 CompileRun( | 101 CompileRun( |
| 102 "var obj = {};" | 102 "var obj = {};" |
| 103 "var count = 0;" | 103 "var count = 0;" |
| 104 "var observer = function(records) { count = records.length };" | 104 "var observer = function(records) { count = records.length };" |
| 105 "Object.observe(obj, observer);" | 105 "Object.observe(obj, observer);" |
| 106 "obj.foo = 'bar';"); | 106 "obj.foo = 'bar';"); |
| 107 CHECK_EQ(1, CompileRun("count")->Int32Value()); | 107 CHECK_EQ(1, CompileRun("count")->Int32Value()); |
| 108 } | 108 } |
| 109 | 109 |
| 110 TEST(DeliveryOrdering) { | 110 TEST(DeliveryOrdering) { |
| 111 HarmonyIsolate isolate; | 111 HarmonyIsolate isolate; |
| 112 HandleScope scope(isolate.GetIsolate()); | 112 HandleScope scope(isolate.GetIsolate()); |
| 113 LocalContext context; | 113 v8::LocalContext context; |
| 114 CompileRun( | 114 CompileRun( |
| 115 "var obj1 = {};" | 115 "var obj1 = {};" |
| 116 "var obj2 = {};" | 116 "var obj2 = {};" |
| 117 "var ordering = [];" | 117 "var ordering = [];" |
| 118 "function observer2() { ordering.push(2); };" | 118 "function observer2() { ordering.push(2); };" |
| 119 "function observer1() { ordering.push(1); };" | 119 "function observer1() { ordering.push(1); };" |
| 120 "function observer3() { ordering.push(3); };" | 120 "function observer3() { ordering.push(3); };" |
| 121 "Object.observe(obj1, observer1);" | 121 "Object.observe(obj1, observer1);" |
| 122 "Object.observe(obj1, observer2);" | 122 "Object.observe(obj1, observer2);" |
| 123 "Object.observe(obj1, observer3);" | 123 "Object.observe(obj1, observer3);" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 134 "obj2.foo = 'baz'"); | 134 "obj2.foo = 'baz'"); |
| 135 CHECK_EQ(3, CompileRun("ordering.length")->Int32Value()); | 135 CHECK_EQ(3, CompileRun("ordering.length")->Int32Value()); |
| 136 CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); | 136 CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); |
| 137 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); | 137 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
| 138 CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); | 138 CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); |
| 139 } | 139 } |
| 140 | 140 |
| 141 TEST(DeliveryOrderingReentrant) { | 141 TEST(DeliveryOrderingReentrant) { |
| 142 HarmonyIsolate isolate; | 142 HarmonyIsolate isolate; |
| 143 HandleScope scope(isolate.GetIsolate()); | 143 HandleScope scope(isolate.GetIsolate()); |
| 144 LocalContext context; | 144 v8::LocalContext context; |
| 145 CompileRun( | 145 CompileRun( |
| 146 "var obj = {};" | 146 "var obj = {};" |
| 147 "var reentered = false;" | 147 "var reentered = false;" |
| 148 "var ordering = [];" | 148 "var ordering = [];" |
| 149 "function observer1() { ordering.push(1); };" | 149 "function observer1() { ordering.push(1); };" |
| 150 "function observer2() {" | 150 "function observer2() {" |
| 151 " if (!reentered) {" | 151 " if (!reentered) {" |
| 152 " obj.foo = 'baz';" | 152 " obj.foo = 'baz';" |
| 153 " reentered = true;" | 153 " reentered = true;" |
| 154 " }" | 154 " }" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 165 CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); | 165 CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); |
| 166 // Note that we re-deliver to observers 1 and 2, while observer3 | 166 // Note that we re-deliver to observers 1 and 2, while observer3 |
| 167 // already received the second record during the first round. | 167 // already received the second record during the first round. |
| 168 CHECK_EQ(1, CompileRun("ordering[3]")->Int32Value()); | 168 CHECK_EQ(1, CompileRun("ordering[3]")->Int32Value()); |
| 169 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); | 169 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
| 170 } | 170 } |
| 171 | 171 |
| 172 TEST(DeliveryOrderingDeliverChangeRecords) { | 172 TEST(DeliveryOrderingDeliverChangeRecords) { |
| 173 HarmonyIsolate isolate; | 173 HarmonyIsolate isolate; |
| 174 HandleScope scope(isolate.GetIsolate()); | 174 HandleScope scope(isolate.GetIsolate()); |
| 175 LocalContext context; | 175 v8::LocalContext context; |
| 176 CompileRun( | 176 CompileRun( |
| 177 "var obj = {};" | 177 "var obj = {};" |
| 178 "var ordering = [];" | 178 "var ordering = [];" |
| 179 "function observer1() { ordering.push(1); if (!obj.b) obj.b = true };" | 179 "function observer1() { ordering.push(1); if (!obj.b) obj.b = true };" |
| 180 "function observer2() { ordering.push(2); };" | 180 "function observer2() { ordering.push(2); };" |
| 181 "Object.observe(obj, observer1);" | 181 "Object.observe(obj, observer1);" |
| 182 "Object.observe(obj, observer2);" | 182 "Object.observe(obj, observer2);" |
| 183 "obj.a = 1;" | 183 "obj.a = 1;" |
| 184 "Object.deliverChangeRecords(observer2);"); | 184 "Object.deliverChangeRecords(observer2);"); |
| 185 CHECK_EQ(4, CompileRun("ordering.length")->Int32Value()); | 185 CHECK_EQ(4, CompileRun("ordering.length")->Int32Value()); |
| 186 // First, observer2 is called due to deliverChangeRecords | 186 // First, observer2 is called due to deliverChangeRecords |
| 187 CHECK_EQ(2, CompileRun("ordering[0]")->Int32Value()); | 187 CHECK_EQ(2, CompileRun("ordering[0]")->Int32Value()); |
| 188 // Then, observer1 is called when the stack unwinds | 188 // Then, observer1 is called when the stack unwinds |
| 189 CHECK_EQ(1, CompileRun("ordering[1]")->Int32Value()); | 189 CHECK_EQ(1, CompileRun("ordering[1]")->Int32Value()); |
| 190 // observer1's mutation causes both 1 and 2 to be reactivated, | 190 // observer1's mutation causes both 1 and 2 to be reactivated, |
| 191 // with 1 having priority. | 191 // with 1 having priority. |
| 192 CHECK_EQ(1, CompileRun("ordering[2]")->Int32Value()); | 192 CHECK_EQ(1, CompileRun("ordering[2]")->Int32Value()); |
| 193 CHECK_EQ(2, CompileRun("ordering[3]")->Int32Value()); | 193 CHECK_EQ(2, CompileRun("ordering[3]")->Int32Value()); |
| 194 } | 194 } |
| 195 | 195 |
| 196 TEST(ObjectHashTableGrowth) { | 196 TEST(ObjectHashTableGrowth) { |
| 197 HarmonyIsolate isolate; | 197 HarmonyIsolate isolate; |
| 198 HandleScope scope(isolate.GetIsolate()); | 198 HandleScope scope(isolate.GetIsolate()); |
| 199 // Initializing this context sets up initial hash tables. | 199 // Initializing this context sets up initial hash tables. |
| 200 LocalContext context; | 200 v8::LocalContext context; |
| 201 Handle<Value> obj = CompileRun("obj = {};"); | 201 Handle<Value> obj = CompileRun("obj = {};"); |
| 202 Handle<Value> observer = CompileRun( | 202 Handle<Value> observer = CompileRun( |
| 203 "var ran = false;" | 203 "var ran = false;" |
| 204 "(function() { ran = true })"); | 204 "(function() { ran = true })"); |
| 205 { | 205 { |
| 206 // As does initializing this context. | 206 // As does initializing this context. |
| 207 LocalContext context2; | 207 v8::LocalContext context2; |
| 208 context2->Global()->Set(String::New("obj"), obj); | 208 context2->Global()->Set(String::New("obj"), obj); |
| 209 context2->Global()->Set(String::New("observer"), observer); | 209 context2->Global()->Set(String::New("observer"), observer); |
| 210 CompileRun( | 210 CompileRun( |
| 211 "var objArr = [];" | 211 "var objArr = [];" |
| 212 // 100 objects should be enough to make the hash table grow | 212 // 100 objects should be enough to make the hash table grow |
| 213 // (and thus relocate). | 213 // (and thus relocate). |
| 214 "for (var i = 0; i < 100; ++i) {" | 214 "for (var i = 0; i < 100; ++i) {" |
| 215 " objArr.push({});" | 215 " objArr.push({});" |
| 216 " Object.observe(objArr[objArr.length-1], function(){});" | 216 " Object.observe(objArr[objArr.length-1], function(){});" |
| 217 "}" | 217 "}" |
| 218 "Object.observe(obj, observer);"); | 218 "Object.observe(obj, observer);"); |
| 219 } | 219 } |
| 220 // obj is now marked "is_observed", but our map has moved. | 220 // obj is now marked "is_observed", but our map has moved. |
| 221 CompileRun("obj.foo = 'bar'"); | 221 CompileRun("obj.foo = 'bar'"); |
| 222 CHECK(CompileRun("ran")->BooleanValue()); | 222 CHECK(CompileRun("ran")->BooleanValue()); |
| 223 } | 223 } |
| 224 | 224 |
| 225 TEST(GlobalObjectObservation) { | 225 TEST(GlobalObjectObservation) { |
| 226 HarmonyIsolate isolate; | 226 HarmonyIsolate isolate; |
| 227 LocalContext context; | 227 v8::LocalContext context; |
| 228 HandleScope scope(isolate.GetIsolate()); | 228 HandleScope scope(isolate.GetIsolate()); |
| 229 Handle<Object> global_proxy = context->Global(); | 229 Handle<Object> global_proxy = context->Global(); |
| 230 Handle<Object> inner_global = global_proxy->GetPrototype().As<Object>(); | 230 Handle<Object> inner_global = global_proxy->GetPrototype().As<Object>(); |
| 231 CompileRun( | 231 CompileRun( |
| 232 "var records = [];" | 232 "var records = [];" |
| 233 "var global = this;" | 233 "var global = this;" |
| 234 "Object.observe(global, function(r) { [].push.apply(records, r) });" | 234 "Object.observe(global, function(r) { [].push.apply(records, r) });" |
| 235 "global.foo = 'hello';"); | 235 "global.foo = 'hello';"); |
| 236 CHECK_EQ(1, CompileRun("records.length")->Int32Value()); | 236 CHECK_EQ(1, CompileRun("records.length")->Int32Value()); |
| 237 CHECK(global_proxy->StrictEquals(CompileRun("records[0].object"))); | 237 CHECK(global_proxy->StrictEquals(CompileRun("records[0].object"))); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 249 // Reattached, back to global proxy. | 249 // Reattached, back to global proxy. |
| 250 context->ReattachGlobal(global_proxy); | 250 context->ReattachGlobal(global_proxy); |
| 251 CompileRun("global.baz = 'again';"); | 251 CompileRun("global.baz = 'again';"); |
| 252 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); | 252 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); |
| 253 CHECK(global_proxy->StrictEquals(CompileRun("records[2].object"))); | 253 CHECK(global_proxy->StrictEquals(CompileRun("records[2].object"))); |
| 254 | 254 |
| 255 // Attached to a different context, should not leak mutations | 255 // Attached to a different context, should not leak mutations |
| 256 // to the old context. | 256 // to the old context. |
| 257 context->DetachGlobal(); | 257 context->DetachGlobal(); |
| 258 { | 258 { |
| 259 LocalContext context2; | 259 v8::LocalContext context2; |
| 260 context2->DetachGlobal(); | 260 context2->DetachGlobal(); |
| 261 context2->ReattachGlobal(global_proxy); | 261 context2->ReattachGlobal(global_proxy); |
| 262 CompileRun( | 262 CompileRun( |
| 263 "var records2 = [];" | 263 "var records2 = [];" |
| 264 "Object.observe(this, function(r) { [].push.apply(records2, r) });" | 264 "Object.observe(this, function(r) { [].push.apply(records2, r) });" |
| 265 "this.bat = 'context2';"); | 265 "this.bat = 'context2';"); |
| 266 CHECK_EQ(1, CompileRun("records2.length")->Int32Value()); | 266 CHECK_EQ(1, CompileRun("records2.length")->Int32Value()); |
| 267 CHECK(global_proxy->StrictEquals(CompileRun("records2[0].object"))); | 267 CHECK(global_proxy->StrictEquals(CompileRun("records2[0].object"))); |
| 268 } | 268 } |
| 269 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); | 269 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); |
| 270 | 270 |
| 271 // Attaching by passing to Context::New | 271 // Attaching by passing to Context::New |
| 272 { | 272 { |
| 273 // Delegates to Context::New | 273 // Delegates to Context::New |
| 274 LocalContext context3(NULL, Handle<ObjectTemplate>(), global_proxy); | 274 v8::LocalContext context3(NULL, Handle<ObjectTemplate>(), global_proxy); |
| 275 CompileRun( | 275 CompileRun( |
| 276 "var records3 = [];" | 276 "var records3 = [];" |
| 277 "Object.observe(this, function(r) { [].push.apply(records3, r) });" | 277 "Object.observe(this, function(r) { [].push.apply(records3, r) });" |
| 278 "this.qux = 'context3';"); | 278 "this.qux = 'context3';"); |
| 279 CHECK_EQ(1, CompileRun("records3.length")->Int32Value()); | 279 CHECK_EQ(1, CompileRun("records3.length")->Int32Value()); |
| 280 CHECK(global_proxy->StrictEquals(CompileRun("records3[0].object"))); | 280 CHECK(global_proxy->StrictEquals(CompileRun("records3[0].object"))); |
| 281 } | 281 } |
| 282 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); | 282 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); |
| 283 } | 283 } |
| 284 | 284 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 313 } | 313 } |
| 314 } | 314 } |
| 315 } | 315 } |
| 316 | 316 |
| 317 #define EXPECT_RECORDS(records, expectations) \ | 317 #define EXPECT_RECORDS(records, expectations) \ |
| 318 ExpectRecords(records, expectations, ARRAY_SIZE(expectations)) | 318 ExpectRecords(records, expectations, ARRAY_SIZE(expectations)) |
| 319 | 319 |
| 320 TEST(APITestBasicMutation) { | 320 TEST(APITestBasicMutation) { |
| 321 HarmonyIsolate isolate; | 321 HarmonyIsolate isolate; |
| 322 HandleScope scope(isolate.GetIsolate()); | 322 HandleScope scope(isolate.GetIsolate()); |
| 323 LocalContext context; | 323 v8::LocalContext context; |
| 324 Handle<Object> obj = Handle<Object>::Cast(CompileRun( | 324 Handle<Object> obj = Handle<Object>::Cast(CompileRun( |
| 325 "var records = [];" | 325 "var records = [];" |
| 326 "var obj = {};" | 326 "var obj = {};" |
| 327 "function observer(r) { [].push.apply(records, r); };" | 327 "function observer(r) { [].push.apply(records, r); };" |
| 328 "Object.observe(obj, observer);" | 328 "Object.observe(obj, observer);" |
| 329 "obj")); | 329 "obj")); |
| 330 obj->Set(String::New("foo"), Number::New(7)); | 330 obj->Set(String::New("foo"), Number::New(7)); |
| 331 obj->Set(1, Number::New(2)); | 331 obj->Set(1, Number::New(2)); |
| 332 // ForceSet should work just as well as Set | 332 // ForceSet should work just as well as Set |
| 333 obj->ForceSet(String::New("foo"), Number::New(3)); | 333 obj->ForceSet(String::New("foo"), Number::New(3)); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 356 { obj, "deleted", "foo", Number::New(3) }, | 356 { obj, "deleted", "foo", Number::New(3) }, |
| 357 { obj, "deleted", "1", Number::New(5) }, | 357 { obj, "deleted", "1", Number::New(5) }, |
| 358 { obj, "deleted", "1.1", Number::New(6) } | 358 { obj, "deleted", "1.1", Number::New(6) } |
| 359 }; | 359 }; |
| 360 EXPECT_RECORDS(CompileRun("records"), expected_records); | 360 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 361 } | 361 } |
| 362 | 362 |
| 363 TEST(HiddenPrototypeObservation) { | 363 TEST(HiddenPrototypeObservation) { |
| 364 HarmonyIsolate isolate; | 364 HarmonyIsolate isolate; |
| 365 HandleScope scope(isolate.GetIsolate()); | 365 HandleScope scope(isolate.GetIsolate()); |
| 366 LocalContext context; | 366 v8::LocalContext context; |
| 367 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); | 367 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); |
| 368 tmpl->SetHiddenPrototype(true); | 368 tmpl->SetHiddenPrototype(true); |
| 369 tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); | 369 tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); |
| 370 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); | 370 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); |
| 371 Handle<Object> obj = Object::New(); | 371 Handle<Object> obj = Object::New(); |
| 372 obj->SetPrototype(proto); | 372 obj->SetPrototype(proto); |
| 373 context->Global()->Set(String::New("obj"), obj); | 373 context->Global()->Set(String::New("obj"), obj); |
| 374 context->Global()->Set(String::New("proto"), proto); | 374 context->Global()->Set(String::New("proto"), proto); |
| 375 CompileRun( | 375 CompileRun( |
| 376 "var records;" | 376 "var records;" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 405 | 405 |
| 406 | 406 |
| 407 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { | 407 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { |
| 408 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); | 408 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); |
| 409 } | 409 } |
| 410 | 410 |
| 411 | 411 |
| 412 TEST(ObservationWeakMap) { | 412 TEST(ObservationWeakMap) { |
| 413 HarmonyIsolate isolate; | 413 HarmonyIsolate isolate; |
| 414 HandleScope scope(isolate.GetIsolate()); | 414 HandleScope scope(isolate.GetIsolate()); |
| 415 LocalContext context; | 415 v8::LocalContext context; |
| 416 CompileRun( | 416 CompileRun( |
| 417 "var obj = {};" | 417 "var obj = {};" |
| 418 "Object.observe(obj, function(){});" | 418 "Object.observe(obj, function(){});" |
| 419 "Object.getNotifier(obj);" | 419 "Object.getNotifier(obj);" |
| 420 "obj = null;"); | 420 "obj = null;"); |
| 421 i::Handle<i::JSObject> observation_state = FACTORY->observation_state(); | 421 i::Handle<i::JSObject> observation_state = FACTORY->observation_state(); |
| 422 i::Handle<i::JSWeakMap> observerInfoMap = | 422 i::Handle<i::JSWeakMap> observerInfoMap = |
| 423 i::Handle<i::JSWeakMap>::cast( | 423 i::Handle<i::JSWeakMap>::cast( |
| 424 i::GetProperty(observation_state, "observerInfoMap")); | 424 i::GetProperty(observation_state, "observerInfoMap")); |
| 425 i::Handle<i::JSWeakMap> objectInfoMap = | 425 i::Handle<i::JSWeakMap> objectInfoMap = |
| 426 i::Handle<i::JSWeakMap>::cast( | 426 i::Handle<i::JSWeakMap>::cast( |
| 427 i::GetProperty(observation_state, "objectInfoMap")); | 427 i::GetProperty(observation_state, "objectInfoMap")); |
| 428 i::Handle<i::JSWeakMap> notifierTargetMap = | 428 i::Handle<i::JSWeakMap> notifierTargetMap = |
| 429 i::Handle<i::JSWeakMap>::cast( | 429 i::Handle<i::JSWeakMap>::cast( |
| 430 i::GetProperty(observation_state, "notifierTargetMap")); | 430 i::GetProperty(observation_state, "notifierTargetMap")); |
| 431 CHECK_EQ(1, NumberOfElements(observerInfoMap)); | 431 CHECK_EQ(1, NumberOfElements(observerInfoMap)); |
| 432 CHECK_EQ(1, NumberOfElements(objectInfoMap)); | 432 CHECK_EQ(1, NumberOfElements(objectInfoMap)); |
| 433 CHECK_EQ(1, NumberOfElements(notifierTargetMap)); | 433 CHECK_EQ(1, NumberOfElements(notifierTargetMap)); |
| 434 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); | 434 HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
| 435 CHECK_EQ(0, NumberOfElements(observerInfoMap)); | 435 CHECK_EQ(0, NumberOfElements(observerInfoMap)); |
| 436 CHECK_EQ(0, NumberOfElements(objectInfoMap)); | 436 CHECK_EQ(0, NumberOfElements(objectInfoMap)); |
| 437 CHECK_EQ(0, NumberOfElements(notifierTargetMap)); | 437 CHECK_EQ(0, NumberOfElements(notifierTargetMap)); |
| 438 } | 438 } |
| OLD | NEW |