| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 { | 1875 { |
| 1876 v8::HandleScope scope; | 1876 v8::HandleScope scope; |
| 1877 Local<String> str = v8_str("str"); | 1877 Local<String> str = v8_str("str"); |
| 1878 global = v8::Persistent<String>::New(str); | 1878 global = v8::Persistent<String>::New(str); |
| 1879 } | 1879 } |
| 1880 CHECK_EQ(global->Length(), 3); | 1880 CHECK_EQ(global->Length(), 3); |
| 1881 global.Dispose(); | 1881 global.Dispose(); |
| 1882 } | 1882 } |
| 1883 | 1883 |
| 1884 | 1884 |
| 1885 static int NumberOfWeakCalls = 0; | 1885 class WeakCallCounter { |
| 1886 public: |
| 1887 explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } |
| 1888 int id() { return id_; } |
| 1889 void increment() { number_of_weak_calls_++; } |
| 1890 int NumberOfWeakCalls() { return number_of_weak_calls_; } |
| 1891 private: |
| 1892 int id_; |
| 1893 int number_of_weak_calls_; |
| 1894 }; |
| 1895 |
| 1896 |
| 1886 static void WeakPointerCallback(Persistent<Value> handle, void* id) { | 1897 static void WeakPointerCallback(Persistent<Value> handle, void* id) { |
| 1887 CHECK_EQ(reinterpret_cast<void*>(1234), id); | 1898 WeakCallCounter* counter = reinterpret_cast<WeakCallCounter*>(id); |
| 1888 NumberOfWeakCalls++; | 1899 CHECK_EQ(1234, counter->id()); |
| 1900 counter->increment(); |
| 1889 handle.Dispose(); | 1901 handle.Dispose(); |
| 1890 } | 1902 } |
| 1891 | 1903 |
| 1904 |
| 1892 THREADED_TEST(ApiObjectGroups) { | 1905 THREADED_TEST(ApiObjectGroups) { |
| 1893 HandleScope scope; | 1906 HandleScope scope; |
| 1894 LocalContext env; | 1907 LocalContext env; |
| 1895 | 1908 |
| 1896 NumberOfWeakCalls = 0; | |
| 1897 | |
| 1898 Persistent<Object> g1s1; | 1909 Persistent<Object> g1s1; |
| 1899 Persistent<Object> g1s2; | 1910 Persistent<Object> g1s2; |
| 1900 Persistent<Object> g1c1; | 1911 Persistent<Object> g1c1; |
| 1901 Persistent<Object> g2s1; | 1912 Persistent<Object> g2s1; |
| 1902 Persistent<Object> g2s2; | 1913 Persistent<Object> g2s2; |
| 1903 Persistent<Object> g2c1; | 1914 Persistent<Object> g2c1; |
| 1904 | 1915 |
| 1916 WeakCallCounter counter(1234); |
| 1917 |
| 1905 { | 1918 { |
| 1906 HandleScope scope; | 1919 HandleScope scope; |
| 1907 g1s1 = Persistent<Object>::New(Object::New()); | 1920 g1s1 = Persistent<Object>::New(Object::New()); |
| 1908 g1s2 = Persistent<Object>::New(Object::New()); | 1921 g1s2 = Persistent<Object>::New(Object::New()); |
| 1909 g1c1 = Persistent<Object>::New(Object::New()); | 1922 g1c1 = Persistent<Object>::New(Object::New()); |
| 1910 g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1923 g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1911 g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1924 g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1912 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1925 g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1913 | 1926 |
| 1914 g2s1 = Persistent<Object>::New(Object::New()); | 1927 g2s1 = Persistent<Object>::New(Object::New()); |
| 1915 g2s2 = Persistent<Object>::New(Object::New()); | 1928 g2s2 = Persistent<Object>::New(Object::New()); |
| 1916 g2c1 = Persistent<Object>::New(Object::New()); | 1929 g2c1 = Persistent<Object>::New(Object::New()); |
| 1917 g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1930 g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1918 g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1931 g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1919 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1932 g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1920 } | 1933 } |
| 1921 | 1934 |
| 1922 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. | 1935 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. |
| 1923 | 1936 |
| 1924 // Connect group 1 and 2, make a cycle. | 1937 // Connect group 1 and 2, make a cycle. |
| 1925 CHECK(g1s2->Set(0, g2s2)); | 1938 CHECK(g1s2->Set(0, g2s2)); |
| 1926 CHECK(g2s1->Set(0, g1s1)); | 1939 CHECK(g2s1->Set(0, g1s1)); |
| 1927 | 1940 |
| 1928 { | 1941 { |
| 1929 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1942 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 1930 Persistent<Value> g1_children[] = { g1c1 }; | 1943 Persistent<Value> g1_children[] = { g1c1 }; |
| 1931 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1944 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 1932 Persistent<Value> g2_children[] = { g2c1 }; | 1945 Persistent<Value> g2_children[] = { g2c1 }; |
| 1933 V8::AddObjectGroup(g1_objects, 2); | 1946 V8::AddObjectGroup(g1_objects, 2); |
| 1934 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1947 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1935 V8::AddObjectGroup(g2_objects, 2); | 1948 V8::AddObjectGroup(g2_objects, 2); |
| 1936 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1949 V8::AddImplicitReferences(g2s2, g2_children, 1); |
| 1937 } | 1950 } |
| 1938 // Do a full GC | 1951 // Do a single full GC. Use kMakeHeapIterableMask to ensure that |
| 1939 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 1952 // incremental garbage collection is stopped. |
| 1953 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 1940 | 1954 |
| 1941 // All object should be alive. | 1955 // All object should be alive. |
| 1942 CHECK_EQ(0, NumberOfWeakCalls); | 1956 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 1943 | 1957 |
| 1944 // Weaken the root. | 1958 // Weaken the root. |
| 1945 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1959 root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1946 // But make children strong roots---all the objects (except for children) | 1960 // But make children strong roots---all the objects (except for children) |
| 1947 // should be collectable now. | 1961 // should be collectable now. |
| 1948 g1c1.ClearWeak(); | 1962 g1c1.ClearWeak(); |
| 1949 g2c1.ClearWeak(); | 1963 g2c1.ClearWeak(); |
| 1950 | 1964 |
| 1951 // Groups are deleted, rebuild groups. | 1965 // Groups are deleted, rebuild groups. |
| 1952 { | 1966 { |
| 1953 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 1967 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 1954 Persistent<Value> g1_children[] = { g1c1 }; | 1968 Persistent<Value> g1_children[] = { g1c1 }; |
| 1955 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 1969 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 1956 Persistent<Value> g2_children[] = { g2c1 }; | 1970 Persistent<Value> g2_children[] = { g2c1 }; |
| 1957 V8::AddObjectGroup(g1_objects, 2); | 1971 V8::AddObjectGroup(g1_objects, 2); |
| 1958 V8::AddImplicitReferences(g1s1, g1_children, 1); | 1972 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 1959 V8::AddObjectGroup(g2_objects, 2); | 1973 V8::AddObjectGroup(g2_objects, 2); |
| 1960 V8::AddImplicitReferences(g2s2, g2_children, 1); | 1974 V8::AddImplicitReferences(g2s2, g2_children, 1); |
| 1961 } | 1975 } |
| 1962 | 1976 |
| 1963 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 1977 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 1964 | 1978 |
| 1965 // All objects should be gone. 5 global handles in total. | 1979 // All objects should be gone. 5 global handles in total. |
| 1966 CHECK_EQ(5, NumberOfWeakCalls); | 1980 CHECK_EQ(5, counter.NumberOfWeakCalls()); |
| 1967 | 1981 |
| 1968 // And now make children weak again and collect them. | 1982 // And now make children weak again and collect them. |
| 1969 g1c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1983 g1c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1970 g2c1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 1984 g2c1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1971 | 1985 |
| 1972 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 1986 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 1973 CHECK_EQ(7, NumberOfWeakCalls); | 1987 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
| 1974 } | 1988 } |
| 1975 | 1989 |
| 1976 | 1990 |
| 1977 THREADED_TEST(ApiObjectGroupsCycle) { | 1991 THREADED_TEST(ApiObjectGroupsCycle) { |
| 1978 HandleScope scope; | 1992 HandleScope scope; |
| 1979 LocalContext env; | 1993 LocalContext env; |
| 1980 | 1994 |
| 1981 NumberOfWeakCalls = 0; | 1995 WeakCallCounter counter(1234); |
| 1982 | 1996 |
| 1983 Persistent<Object> g1s1; | 1997 Persistent<Object> g1s1; |
| 1984 Persistent<Object> g1s2; | 1998 Persistent<Object> g1s2; |
| 1985 Persistent<Object> g2s1; | 1999 Persistent<Object> g2s1; |
| 1986 Persistent<Object> g2s2; | 2000 Persistent<Object> g2s2; |
| 1987 Persistent<Object> g3s1; | 2001 Persistent<Object> g3s1; |
| 1988 Persistent<Object> g3s2; | 2002 Persistent<Object> g3s2; |
| 1989 | 2003 |
| 1990 { | 2004 { |
| 1991 HandleScope scope; | 2005 HandleScope scope; |
| 1992 g1s1 = Persistent<Object>::New(Object::New()); | 2006 g1s1 = Persistent<Object>::New(Object::New()); |
| 1993 g1s2 = Persistent<Object>::New(Object::New()); | 2007 g1s2 = Persistent<Object>::New(Object::New()); |
| 1994 g1s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2008 g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1995 g1s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2009 g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 1996 | 2010 |
| 1997 g2s1 = Persistent<Object>::New(Object::New()); | 2011 g2s1 = Persistent<Object>::New(Object::New()); |
| 1998 g2s2 = Persistent<Object>::New(Object::New()); | 2012 g2s2 = Persistent<Object>::New(Object::New()); |
| 1999 g2s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2013 g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2000 g2s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2014 g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2001 | 2015 |
| 2002 g3s1 = Persistent<Object>::New(Object::New()); | 2016 g3s1 = Persistent<Object>::New(Object::New()); |
| 2003 g3s2 = Persistent<Object>::New(Object::New()); | 2017 g3s2 = Persistent<Object>::New(Object::New()); |
| 2004 g3s1.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2018 g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2005 g3s2.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2019 g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2006 } | 2020 } |
| 2007 | 2021 |
| 2008 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. | 2022 Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root. |
| 2009 | 2023 |
| 2010 // Connect groups. We're building the following cycle: | 2024 // Connect groups. We're building the following cycle: |
| 2011 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other | 2025 // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other |
| 2012 // groups. | 2026 // groups. |
| 2013 { | 2027 { |
| 2014 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2028 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 2015 Persistent<Value> g1_children[] = { g2s1 }; | 2029 Persistent<Value> g1_children[] = { g2s1 }; |
| 2016 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2030 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 2017 Persistent<Value> g2_children[] = { g3s1 }; | 2031 Persistent<Value> g2_children[] = { g3s1 }; |
| 2018 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 2032 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
| 2019 Persistent<Value> g3_children[] = { g1s1 }; | 2033 Persistent<Value> g3_children[] = { g1s1 }; |
| 2020 V8::AddObjectGroup(g1_objects, 2); | 2034 V8::AddObjectGroup(g1_objects, 2); |
| 2021 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2035 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 2022 V8::AddObjectGroup(g2_objects, 2); | 2036 V8::AddObjectGroup(g2_objects, 2); |
| 2023 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2037 V8::AddImplicitReferences(g2s1, g2_children, 1); |
| 2024 V8::AddObjectGroup(g3_objects, 2); | 2038 V8::AddObjectGroup(g3_objects, 2); |
| 2025 V8::AddImplicitReferences(g3s1, g3_children, 1); | 2039 V8::AddImplicitReferences(g3s1, g3_children, 1); |
| 2026 } | 2040 } |
| 2027 // Do a full GC | 2041 // Do a single full GC |
| 2028 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2042 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 2029 | 2043 |
| 2030 // All object should be alive. | 2044 // All object should be alive. |
| 2031 CHECK_EQ(0, NumberOfWeakCalls); | 2045 CHECK_EQ(0, counter.NumberOfWeakCalls()); |
| 2032 | 2046 |
| 2033 // Weaken the root. | 2047 // Weaken the root. |
| 2034 root.MakeWeak(reinterpret_cast<void*>(1234), &WeakPointerCallback); | 2048 root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback); |
| 2035 | 2049 |
| 2036 // Groups are deleted, rebuild groups. | 2050 // Groups are deleted, rebuild groups. |
| 2037 { | 2051 { |
| 2038 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; | 2052 Persistent<Value> g1_objects[] = { g1s1, g1s2 }; |
| 2039 Persistent<Value> g1_children[] = { g2s1 }; | 2053 Persistent<Value> g1_children[] = { g2s1 }; |
| 2040 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; | 2054 Persistent<Value> g2_objects[] = { g2s1, g2s2 }; |
| 2041 Persistent<Value> g2_children[] = { g3s1 }; | 2055 Persistent<Value> g2_children[] = { g3s1 }; |
| 2042 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; | 2056 Persistent<Value> g3_objects[] = { g3s1, g3s2 }; |
| 2043 Persistent<Value> g3_children[] = { g1s1 }; | 2057 Persistent<Value> g3_children[] = { g1s1 }; |
| 2044 V8::AddObjectGroup(g1_objects, 2); | 2058 V8::AddObjectGroup(g1_objects, 2); |
| 2045 V8::AddImplicitReferences(g1s1, g1_children, 1); | 2059 V8::AddImplicitReferences(g1s1, g1_children, 1); |
| 2046 V8::AddObjectGroup(g2_objects, 2); | 2060 V8::AddObjectGroup(g2_objects, 2); |
| 2047 V8::AddImplicitReferences(g2s1, g2_children, 1); | 2061 V8::AddImplicitReferences(g2s1, g2_children, 1); |
| 2048 V8::AddObjectGroup(g3_objects, 2); | 2062 V8::AddObjectGroup(g3_objects, 2); |
| 2049 V8::AddImplicitReferences(g3s1, g3_children, 1); | 2063 V8::AddImplicitReferences(g3s1, g3_children, 1); |
| 2050 } | 2064 } |
| 2051 | 2065 |
| 2052 HEAP->CollectGarbage(i::OLD_POINTER_SPACE); | 2066 HEAP->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 2053 | 2067 |
| 2054 // All objects should be gone. 7 global handles in total. | 2068 // All objects should be gone. 7 global handles in total. |
| 2055 CHECK_EQ(7, NumberOfWeakCalls); | 2069 CHECK_EQ(7, counter.NumberOfWeakCalls()); |
| 2056 } | 2070 } |
| 2057 | 2071 |
| 2058 | 2072 |
| 2059 THREADED_TEST(ScriptException) { | 2073 THREADED_TEST(ScriptException) { |
| 2060 v8::HandleScope scope; | 2074 v8::HandleScope scope; |
| 2061 LocalContext env; | 2075 LocalContext env; |
| 2062 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); | 2076 Local<Script> script = Script::Compile(v8_str("throw 'panama!';")); |
| 2063 v8::TryCatch try_catch; | 2077 v8::TryCatch try_catch; |
| 2064 Local<Value> result = script->Run(); | 2078 Local<Value> result = script->Run(); |
| 2065 CHECK(result.IsEmpty()); | 2079 CHECK(result.IsEmpty()); |
| (...skipping 12766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14832 } | 14846 } |
| 14833 | 14847 |
| 14834 i::Isolate::Current()->heap()->CollectAllGarbage(true); | 14848 i::Isolate::Current()->heap()->CollectAllGarbage(true); |
| 14835 { i::Object* raw_map_cache = i::Isolate::Current()->context()->map_cache(); | 14849 { i::Object* raw_map_cache = i::Isolate::Current()->context()->map_cache(); |
| 14836 if (raw_map_cache != i::Isolate::Current()->heap()->undefined_value()) { | 14850 if (raw_map_cache != i::Isolate::Current()->heap()->undefined_value()) { |
| 14837 i::MapCache* map_cache = i::MapCache::cast(raw_map_cache); | 14851 i::MapCache* map_cache = i::MapCache::cast(raw_map_cache); |
| 14838 CHECK_GT(elements, map_cache->NumberOfElements()); | 14852 CHECK_GT(elements, map_cache->NumberOfElements()); |
| 14839 } | 14853 } |
| 14840 } | 14854 } |
| 14841 } | 14855 } |
| OLD | NEW |