| 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 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 FLAG_retain_maps_for_n_gc = 0; | 1552 FLAG_retain_maps_for_n_gc = 0; |
| 1553 | 1553 |
| 1554 static const int kNumTestContexts = 10; | 1554 static const int kNumTestContexts = 10; |
| 1555 | 1555 |
| 1556 Isolate* isolate = CcTest::i_isolate(); | 1556 Isolate* isolate = CcTest::i_isolate(); |
| 1557 Heap* heap = isolate->heap(); | 1557 Heap* heap = isolate->heap(); |
| 1558 HandleScope scope(isolate); | 1558 HandleScope scope(isolate); |
| 1559 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1559 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
| 1560 if (!isolate->use_crankshaft()) return; | 1560 if (!isolate->use_crankshaft()) return; |
| 1561 | 1561 |
| 1562 CHECK_EQ(0, CountNativeContexts()); | 1562 CHECK_EQ(1, CountNativeContexts()); |
| 1563 | 1563 |
| 1564 // Create a number of global contests which gets linked together. | 1564 // Create a number of global contests which gets linked together. |
| 1565 for (int i = 0; i < kNumTestContexts; i++) { | 1565 for (int i = 0; i < kNumTestContexts; i++) { |
| 1566 ctx[i] = v8::Context::New(CcTest::isolate()); | 1566 ctx[i] = v8::Context::New(CcTest::isolate()); |
| 1567 | 1567 |
| 1568 // Collect garbage that might have been created by one of the | 1568 // Collect garbage that might have been created by one of the |
| 1569 // installed extensions. | 1569 // installed extensions. |
| 1570 isolate->compilation_cache()->Clear(); | 1570 isolate->compilation_cache()->Clear(); |
| 1571 heap->CollectAllGarbage(); | 1571 heap->CollectAllGarbage(); |
| 1572 | 1572 |
| 1573 CHECK_EQ(i + 1, CountNativeContexts()); | 1573 CHECK_EQ(i + 2, CountNativeContexts()); |
| 1574 | 1574 |
| 1575 ctx[i]->Enter(); | 1575 ctx[i]->Enter(); |
| 1576 | 1576 |
| 1577 // Create a handle scope so no function objects get stuck in the outer | 1577 // Create a handle scope so no function objects get stuck in the outer |
| 1578 // handle scope. | 1578 // handle scope. |
| 1579 HandleScope scope(isolate); | 1579 HandleScope scope(isolate); |
| 1580 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); | 1580 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[i])); |
| 1581 OptimizeEmptyFunction("f1"); | 1581 OptimizeEmptyFunction("f1"); |
| 1582 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[i])); | 1582 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[i])); |
| 1583 OptimizeEmptyFunction("f2"); | 1583 OptimizeEmptyFunction("f2"); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1629 // Dispose the native contexts one by one. | 1629 // Dispose the native contexts one by one. |
| 1630 for (int i = 0; i < kNumTestContexts; i++) { | 1630 for (int i = 0; i < kNumTestContexts; i++) { |
| 1631 // TODO(dcarney): is there a better way to do this? | 1631 // TODO(dcarney): is there a better way to do this? |
| 1632 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); | 1632 i::Object** unsafe = reinterpret_cast<i::Object**>(*ctx[i]); |
| 1633 *unsafe = CcTest::heap()->undefined_value(); | 1633 *unsafe = CcTest::heap()->undefined_value(); |
| 1634 ctx[i].Clear(); | 1634 ctx[i].Clear(); |
| 1635 | 1635 |
| 1636 // Scavenge treats these references as strong. | 1636 // Scavenge treats these references as strong. |
| 1637 for (int j = 0; j < 10; j++) { | 1637 for (int j = 0; j < 10; j++) { |
| 1638 CcTest::heap()->CollectGarbage(i::NEW_SPACE); | 1638 CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
| 1639 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); | 1639 CHECK_EQ(kNumTestContexts - i + 1, CountNativeContexts()); |
| 1640 } | 1640 } |
| 1641 | 1641 |
| 1642 // Mark compact handles the weak references. | 1642 // Mark compact handles the weak references. |
| 1643 CcTest::heap()->CollectAllGarbage(); | 1643 CcTest::heap()->CollectAllGarbage(); |
| 1644 CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts()); | 1644 CHECK_EQ(kNumTestContexts - i, CountNativeContexts()); |
| 1645 } | 1645 } |
| 1646 | 1646 |
| 1647 CHECK_EQ(0, CountNativeContexts()); | 1647 CHECK_EQ(1, CountNativeContexts()); |
| 1648 } | 1648 } |
| 1649 | 1649 |
| 1650 | 1650 |
| 1651 // Count the number of native contexts in the weak list of native contexts | 1651 // Count the number of native contexts in the weak list of native contexts |
| 1652 // causing a GC after the specified number of elements. | 1652 // causing a GC after the specified number of elements. |
| 1653 static int CountNativeContextsWithGC(Isolate* isolate, int n) { | 1653 static int CountNativeContextsWithGC(Isolate* isolate, int n) { |
| 1654 Heap* heap = isolate->heap(); | 1654 Heap* heap = isolate->heap(); |
| 1655 int count = 0; | 1655 int count = 0; |
| 1656 Handle<Object> object(heap->native_contexts_list(), isolate); | 1656 Handle<Object> object(heap->native_contexts_list(), isolate); |
| 1657 while (!object->IsUndefined()) { | 1657 while (!object->IsUndefined()) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1692 FLAG_allow_natives_syntax = true; | 1692 FLAG_allow_natives_syntax = true; |
| 1693 v8::V8::Initialize(); | 1693 v8::V8::Initialize(); |
| 1694 | 1694 |
| 1695 static const int kNumTestContexts = 10; | 1695 static const int kNumTestContexts = 10; |
| 1696 | 1696 |
| 1697 Isolate* isolate = CcTest::i_isolate(); | 1697 Isolate* isolate = CcTest::i_isolate(); |
| 1698 HandleScope scope(isolate); | 1698 HandleScope scope(isolate); |
| 1699 v8::Handle<v8::Context> ctx[kNumTestContexts]; | 1699 v8::Handle<v8::Context> ctx[kNumTestContexts]; |
| 1700 if (!isolate->use_crankshaft()) return; | 1700 if (!isolate->use_crankshaft()) return; |
| 1701 | 1701 |
| 1702 CHECK_EQ(0, CountNativeContexts()); | 1702 CHECK_EQ(1, CountNativeContexts()); |
| 1703 | 1703 |
| 1704 // Create an number of contexts and check the length of the weak list both | 1704 // Create an number of contexts and check the length of the weak list both |
| 1705 // with and without GCs while iterating the list. | 1705 // with and without GCs while iterating the list. |
| 1706 for (int i = 0; i < kNumTestContexts; i++) { | 1706 for (int i = 0; i < kNumTestContexts; i++) { |
| 1707 ctx[i] = v8::Context::New(CcTest::isolate()); | 1707 ctx[i] = v8::Context::New(CcTest::isolate()); |
| 1708 CHECK_EQ(i + 1, CountNativeContexts()); | 1708 CHECK_EQ(i + 2, CountNativeContexts()); |
| 1709 CHECK_EQ(i + 1, CountNativeContextsWithGC(isolate, i / 2 + 1)); | 1709 CHECK_EQ(i + 2, CountNativeContextsWithGC(isolate, i / 2 + 1)); |
| 1710 } | 1710 } |
| 1711 | 1711 |
| 1712 ctx[0]->Enter(); | 1712 ctx[0]->Enter(); |
| 1713 | 1713 |
| 1714 // Compile a number of functions the length of the weak list of optimized | 1714 // Compile a number of functions the length of the weak list of optimized |
| 1715 // functions both with and without GCs while iterating the list. | 1715 // functions both with and without GCs while iterating the list. |
| 1716 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); | 1716 CHECK_EQ(0, CountOptimizedUserFunctions(ctx[0])); |
| 1717 OptimizeEmptyFunction("f1"); | 1717 OptimizeEmptyFunction("f1"); |
| 1718 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[0])); | 1718 CHECK_EQ(1, CountOptimizedUserFunctions(ctx[0])); |
| 1719 CHECK_EQ(1, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); | 1719 CHECK_EQ(1, CountOptimizedUserFunctionsWithGC(ctx[0], 1)); |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2243 | 2243 |
| 2244 | 2244 |
| 2245 // Test that we don't embed maps from foreign contexts into | 2245 // Test that we don't embed maps from foreign contexts into |
| 2246 // optimized code. | 2246 // optimized code. |
| 2247 TEST(LeakNativeContextViaMap) { | 2247 TEST(LeakNativeContextViaMap) { |
| 2248 i::FLAG_allow_natives_syntax = true; | 2248 i::FLAG_allow_natives_syntax = true; |
| 2249 v8::Isolate* isolate = CcTest::isolate(); | 2249 v8::Isolate* isolate = CcTest::isolate(); |
| 2250 v8::HandleScope outer_scope(isolate); | 2250 v8::HandleScope outer_scope(isolate); |
| 2251 v8::Persistent<v8::Context> ctx1p; | 2251 v8::Persistent<v8::Context> ctx1p; |
| 2252 v8::Persistent<v8::Context> ctx2p; | 2252 v8::Persistent<v8::Context> ctx2p; |
| 2253 |
| 2254 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2255 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2256 |
| 2253 { | 2257 { |
| 2254 v8::HandleScope scope(isolate); | 2258 v8::HandleScope scope(isolate); |
| 2255 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 2259 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 2256 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 2260 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 2257 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 2261 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 2258 } | 2262 } |
| 2259 | 2263 |
| 2260 CcTest::heap()->CollectAllAvailableGarbage(); | 2264 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2261 CHECK_EQ(4, NumberOfGlobalObjects()); | 2265 CHECK_EQ(6, NumberOfGlobalObjects()); |
| 2262 | 2266 |
| 2263 { | 2267 { |
| 2264 v8::HandleScope inner_scope(isolate); | 2268 v8::HandleScope inner_scope(isolate); |
| 2265 CompileRun("var v = {x: 42}"); | 2269 CompileRun("var v = {x: 42}"); |
| 2266 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2270 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2267 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2271 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2268 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2272 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 2269 ctx2->Enter(); | 2273 ctx2->Enter(); |
| 2270 ctx2->Global()->Set(v8_str("o"), v); | 2274 ctx2->Global()->Set(v8_str("o"), v); |
| 2271 v8::Local<v8::Value> res = CompileRun( | 2275 v8::Local<v8::Value> res = CompileRun( |
| 2272 "function f() { return o.x; }" | 2276 "function f() { return o.x; }" |
| 2273 "for (var i = 0; i < 10; ++i) f();" | 2277 "for (var i = 0; i < 10; ++i) f();" |
| 2274 "%OptimizeFunctionOnNextCall(f);" | 2278 "%OptimizeFunctionOnNextCall(f);" |
| 2275 "f();"); | 2279 "f();"); |
| 2276 CHECK_EQ(42, res->Int32Value()); | 2280 CHECK_EQ(42, res->Int32Value()); |
| 2277 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2281 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); |
| 2278 ctx2->Exit(); | 2282 ctx2->Exit(); |
| 2279 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); | 2283 v8::Local<v8::Context>::New(isolate, ctx1)->Exit(); |
| 2280 ctx1p.Reset(); | 2284 ctx1p.Reset(); |
| 2281 isolate->ContextDisposedNotification(); | 2285 isolate->ContextDisposedNotification(); |
| 2282 } | 2286 } |
| 2283 CcTest::heap()->CollectAllAvailableGarbage(); | 2287 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2284 CHECK_EQ(2, NumberOfGlobalObjects()); | 2288 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2285 ctx2p.Reset(); | 2289 ctx2p.Reset(); |
| 2286 CcTest::heap()->CollectAllAvailableGarbage(); | 2290 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2287 CHECK_EQ(0, NumberOfGlobalObjects()); | 2291 // Code stub context is still left over |
| 2292 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2288 } | 2293 } |
| 2289 | 2294 |
| 2290 | 2295 |
| 2291 // Test that we don't embed functions from foreign contexts into | 2296 // Test that we don't embed functions from foreign contexts into |
| 2292 // optimized code. | 2297 // optimized code. |
| 2293 TEST(LeakNativeContextViaFunction) { | 2298 TEST(LeakNativeContextViaFunction) { |
| 2294 i::FLAG_allow_natives_syntax = true; | 2299 i::FLAG_allow_natives_syntax = true; |
| 2295 v8::Isolate* isolate = CcTest::isolate(); | 2300 v8::Isolate* isolate = CcTest::isolate(); |
| 2296 v8::HandleScope outer_scope(isolate); | 2301 v8::HandleScope outer_scope(isolate); |
| 2297 v8::Persistent<v8::Context> ctx1p; | 2302 v8::Persistent<v8::Context> ctx1p; |
| 2298 v8::Persistent<v8::Context> ctx2p; | 2303 v8::Persistent<v8::Context> ctx2p; |
| 2299 { | 2304 { |
| 2300 v8::HandleScope scope(isolate); | 2305 v8::HandleScope scope(isolate); |
| 2301 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 2306 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 2302 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 2307 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 2303 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 2308 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 2304 } | 2309 } |
| 2305 | 2310 |
| 2306 CcTest::heap()->CollectAllAvailableGarbage(); | 2311 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2307 CHECK_EQ(4, NumberOfGlobalObjects()); | 2312 CHECK_EQ(6, NumberOfGlobalObjects()); |
| 2308 | 2313 |
| 2309 { | 2314 { |
| 2310 v8::HandleScope inner_scope(isolate); | 2315 v8::HandleScope inner_scope(isolate); |
| 2311 CompileRun("var v = function() { return 42; }"); | 2316 CompileRun("var v = function() { return 42; }"); |
| 2312 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2317 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2313 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2318 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2314 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2319 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 2315 ctx2->Enter(); | 2320 ctx2->Enter(); |
| 2316 ctx2->Global()->Set(v8_str("o"), v); | 2321 ctx2->Global()->Set(v8_str("o"), v); |
| 2317 v8::Local<v8::Value> res = CompileRun( | 2322 v8::Local<v8::Value> res = CompileRun( |
| 2318 "function f(x) { return x(); }" | 2323 "function f(x) { return x(); }" |
| 2319 "for (var i = 0; i < 10; ++i) f(o);" | 2324 "for (var i = 0; i < 10; ++i) f(o);" |
| 2320 "%OptimizeFunctionOnNextCall(f);" | 2325 "%OptimizeFunctionOnNextCall(f);" |
| 2321 "f(o);"); | 2326 "f(o);"); |
| 2322 CHECK_EQ(42, res->Int32Value()); | 2327 CHECK_EQ(42, res->Int32Value()); |
| 2323 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2328 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); |
| 2324 ctx2->Exit(); | 2329 ctx2->Exit(); |
| 2325 ctx1->Exit(); | 2330 ctx1->Exit(); |
| 2326 ctx1p.Reset(); | 2331 ctx1p.Reset(); |
| 2327 isolate->ContextDisposedNotification(); | 2332 isolate->ContextDisposedNotification(); |
| 2328 } | 2333 } |
| 2329 CcTest::heap()->CollectAllAvailableGarbage(); | 2334 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2330 CHECK_EQ(2, NumberOfGlobalObjects()); | 2335 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2331 ctx2p.Reset(); | 2336 ctx2p.Reset(); |
| 2332 CcTest::heap()->CollectAllAvailableGarbage(); | 2337 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2333 CHECK_EQ(0, NumberOfGlobalObjects()); | 2338 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2334 } | 2339 } |
| 2335 | 2340 |
| 2336 | 2341 |
| 2337 TEST(LeakNativeContextViaMapKeyed) { | 2342 TEST(LeakNativeContextViaMapKeyed) { |
| 2338 i::FLAG_allow_natives_syntax = true; | 2343 i::FLAG_allow_natives_syntax = true; |
| 2339 v8::Isolate* isolate = CcTest::isolate(); | 2344 v8::Isolate* isolate = CcTest::isolate(); |
| 2340 v8::HandleScope outer_scope(isolate); | 2345 v8::HandleScope outer_scope(isolate); |
| 2341 v8::Persistent<v8::Context> ctx1p; | 2346 v8::Persistent<v8::Context> ctx1p; |
| 2342 v8::Persistent<v8::Context> ctx2p; | 2347 v8::Persistent<v8::Context> ctx2p; |
| 2343 { | 2348 { |
| 2344 v8::HandleScope scope(isolate); | 2349 v8::HandleScope scope(isolate); |
| 2345 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 2350 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 2346 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 2351 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 2347 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 2352 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 2348 } | 2353 } |
| 2349 | 2354 |
| 2350 CcTest::heap()->CollectAllAvailableGarbage(); | 2355 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2351 CHECK_EQ(4, NumberOfGlobalObjects()); | 2356 CHECK_EQ(6, NumberOfGlobalObjects()); |
| 2352 | 2357 |
| 2353 { | 2358 { |
| 2354 v8::HandleScope inner_scope(isolate); | 2359 v8::HandleScope inner_scope(isolate); |
| 2355 CompileRun("var v = [42, 43]"); | 2360 CompileRun("var v = [42, 43]"); |
| 2356 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2361 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2357 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2362 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2358 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2363 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 2359 ctx2->Enter(); | 2364 ctx2->Enter(); |
| 2360 ctx2->Global()->Set(v8_str("o"), v); | 2365 ctx2->Global()->Set(v8_str("o"), v); |
| 2361 v8::Local<v8::Value> res = CompileRun( | 2366 v8::Local<v8::Value> res = CompileRun( |
| 2362 "function f() { return o[0]; }" | 2367 "function f() { return o[0]; }" |
| 2363 "for (var i = 0; i < 10; ++i) f();" | 2368 "for (var i = 0; i < 10; ++i) f();" |
| 2364 "%OptimizeFunctionOnNextCall(f);" | 2369 "%OptimizeFunctionOnNextCall(f);" |
| 2365 "f();"); | 2370 "f();"); |
| 2366 CHECK_EQ(42, res->Int32Value()); | 2371 CHECK_EQ(42, res->Int32Value()); |
| 2367 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2372 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); |
| 2368 ctx2->Exit(); | 2373 ctx2->Exit(); |
| 2369 ctx1->Exit(); | 2374 ctx1->Exit(); |
| 2370 ctx1p.Reset(); | 2375 ctx1p.Reset(); |
| 2371 isolate->ContextDisposedNotification(); | 2376 isolate->ContextDisposedNotification(); |
| 2372 } | 2377 } |
| 2373 CcTest::heap()->CollectAllAvailableGarbage(); | 2378 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2374 CHECK_EQ(2, NumberOfGlobalObjects()); | 2379 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2375 ctx2p.Reset(); | 2380 ctx2p.Reset(); |
| 2376 CcTest::heap()->CollectAllAvailableGarbage(); | 2381 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2377 CHECK_EQ(0, NumberOfGlobalObjects()); | 2382 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2378 } | 2383 } |
| 2379 | 2384 |
| 2380 | 2385 |
| 2381 TEST(LeakNativeContextViaMapProto) { | 2386 TEST(LeakNativeContextViaMapProto) { |
| 2382 i::FLAG_allow_natives_syntax = true; | 2387 i::FLAG_allow_natives_syntax = true; |
| 2383 v8::Isolate* isolate = CcTest::isolate(); | 2388 v8::Isolate* isolate = CcTest::isolate(); |
| 2384 v8::HandleScope outer_scope(isolate); | 2389 v8::HandleScope outer_scope(isolate); |
| 2385 v8::Persistent<v8::Context> ctx1p; | 2390 v8::Persistent<v8::Context> ctx1p; |
| 2386 v8::Persistent<v8::Context> ctx2p; | 2391 v8::Persistent<v8::Context> ctx2p; |
| 2387 { | 2392 { |
| 2388 v8::HandleScope scope(isolate); | 2393 v8::HandleScope scope(isolate); |
| 2389 ctx1p.Reset(isolate, v8::Context::New(isolate)); | 2394 ctx1p.Reset(isolate, v8::Context::New(isolate)); |
| 2390 ctx2p.Reset(isolate, v8::Context::New(isolate)); | 2395 ctx2p.Reset(isolate, v8::Context::New(isolate)); |
| 2391 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); | 2396 v8::Local<v8::Context>::New(isolate, ctx1p)->Enter(); |
| 2392 } | 2397 } |
| 2393 | 2398 |
| 2394 CcTest::heap()->CollectAllAvailableGarbage(); | 2399 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2395 CHECK_EQ(4, NumberOfGlobalObjects()); | 2400 CHECK_EQ(6, NumberOfGlobalObjects()); |
| 2396 | 2401 |
| 2397 { | 2402 { |
| 2398 v8::HandleScope inner_scope(isolate); | 2403 v8::HandleScope inner_scope(isolate); |
| 2399 CompileRun("var v = { y: 42}"); | 2404 CompileRun("var v = { y: 42}"); |
| 2400 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); | 2405 v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p); |
| 2401 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); | 2406 v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p); |
| 2402 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); | 2407 v8::Local<v8::Value> v = ctx1->Global()->Get(v8_str("v")); |
| 2403 ctx2->Enter(); | 2408 ctx2->Enter(); |
| 2404 ctx2->Global()->Set(v8_str("o"), v); | 2409 ctx2->Global()->Set(v8_str("o"), v); |
| 2405 v8::Local<v8::Value> res = CompileRun( | 2410 v8::Local<v8::Value> res = CompileRun( |
| 2406 "function f() {" | 2411 "function f() {" |
| 2407 " var p = {x: 42};" | 2412 " var p = {x: 42};" |
| 2408 " p.__proto__ = o;" | 2413 " p.__proto__ = o;" |
| 2409 " return p.x;" | 2414 " return p.x;" |
| 2410 "}" | 2415 "}" |
| 2411 "for (var i = 0; i < 10; ++i) f();" | 2416 "for (var i = 0; i < 10; ++i) f();" |
| 2412 "%OptimizeFunctionOnNextCall(f);" | 2417 "%OptimizeFunctionOnNextCall(f);" |
| 2413 "f();"); | 2418 "f();"); |
| 2414 CHECK_EQ(42, res->Int32Value()); | 2419 CHECK_EQ(42, res->Int32Value()); |
| 2415 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); | 2420 ctx2->Global()->Set(v8_str("o"), v8::Int32::New(isolate, 0)); |
| 2416 ctx2->Exit(); | 2421 ctx2->Exit(); |
| 2417 ctx1->Exit(); | 2422 ctx1->Exit(); |
| 2418 ctx1p.Reset(); | 2423 ctx1p.Reset(); |
| 2419 isolate->ContextDisposedNotification(); | 2424 isolate->ContextDisposedNotification(); |
| 2420 } | 2425 } |
| 2421 CcTest::heap()->CollectAllAvailableGarbage(); | 2426 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2422 CHECK_EQ(2, NumberOfGlobalObjects()); | 2427 CHECK_EQ(4, NumberOfGlobalObjects()); |
| 2423 ctx2p.Reset(); | 2428 ctx2p.Reset(); |
| 2424 CcTest::heap()->CollectAllAvailableGarbage(); | 2429 CcTest::heap()->CollectAllAvailableGarbage(); |
| 2425 CHECK_EQ(0, NumberOfGlobalObjects()); | 2430 CHECK_EQ(2, NumberOfGlobalObjects()); |
| 2426 } | 2431 } |
| 2427 | 2432 |
| 2428 | 2433 |
| 2429 TEST(InstanceOfStubWriteBarrier) { | 2434 TEST(InstanceOfStubWriteBarrier) { |
| 2430 i::FLAG_allow_natives_syntax = true; | 2435 i::FLAG_allow_natives_syntax = true; |
| 2431 #ifdef VERIFY_HEAP | 2436 #ifdef VERIFY_HEAP |
| 2432 i::FLAG_verify_heap = true; | 2437 i::FLAG_verify_heap = true; |
| 2433 #endif | 2438 #endif |
| 2434 | 2439 |
| 2435 CcTest::InitializeVM(); | 2440 CcTest::InitializeVM(); |
| (...skipping 3612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6048 array->address(), | 6053 array->address(), |
| 6049 array->address() + array->Size()); | 6054 array->address() + array->Size()); |
| 6050 DCHECK(reinterpret_cast<void*>(buffer->Get(1)) == | 6055 DCHECK(reinterpret_cast<void*>(buffer->Get(1)) == |
| 6051 HeapObject::RawField(heap->empty_fixed_array(), | 6056 HeapObject::RawField(heap->empty_fixed_array(), |
| 6052 FixedArrayBase::kLengthOffset)); | 6057 FixedArrayBase::kLengthOffset)); |
| 6053 DCHECK(reinterpret_cast<void*>(buffer->Get(2)) == | 6058 DCHECK(reinterpret_cast<void*>(buffer->Get(2)) == |
| 6054 HeapObject::RawField(heap->empty_fixed_array(), | 6059 HeapObject::RawField(heap->empty_fixed_array(), |
| 6055 FixedArrayBase::kLengthOffset)); | 6060 FixedArrayBase::kLengthOffset)); |
| 6056 delete buffer; | 6061 delete buffer; |
| 6057 } | 6062 } |
| OLD | NEW |