| 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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 GetProperty(global, v8::HeapGraphEdge::kProperty, "x"); | 227 GetProperty(global, v8::HeapGraphEdge::kProperty, "x"); |
| 228 CHECK_NE(NULL, x); | 228 CHECK_NE(NULL, x); |
| 229 const v8::HeapGraphNode* x1 = | 229 const v8::HeapGraphNode* x1 = |
| 230 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); | 230 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); |
| 231 CHECK_NE(NULL, x1); | 231 CHECK_NE(NULL, x1); |
| 232 const v8::HeapGraphNode* x2 = | 232 const v8::HeapGraphNode* x2 = |
| 233 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); | 233 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); |
| 234 CHECK_NE(NULL, x2); | 234 CHECK_NE(NULL, x2); |
| 235 | 235 |
| 236 // Test sizes. | 236 // Test sizes. |
| 237 CHECK_NE(0, x->GetSelfSize()); | 237 CHECK_NE(0, static_cast<int>(x->GetShallowSize())); |
| 238 CHECK_NE(0, x1->GetSelfSize()); | 238 CHECK_NE(0, static_cast<int>(x1->GetShallowSize())); |
| 239 CHECK_NE(0, x2->GetSelfSize()); | 239 CHECK_NE(0, static_cast<int>(x2->GetShallowSize())); |
| 240 } | 240 } |
| 241 | 241 |
| 242 | 242 |
| 243 TEST(BoundFunctionInSnapshot) { | 243 TEST(BoundFunctionInSnapshot) { |
| 244 LocalContext env; | 244 LocalContext env; |
| 245 v8::HandleScope scope(env->GetIsolate()); | 245 v8::HandleScope scope(env->GetIsolate()); |
| 246 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); | 246 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 247 CompileRun( | 247 CompileRun( |
| 248 "function myFunction(a, b) { this.a = a; this.b = b; }\n" | 248 "function myFunction(a, b) { this.a = a; this.b = b; }\n" |
| 249 "function AAAAA() {}\n" | 249 "function AAAAA() {}\n" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 CHECK_EQ("", *anonymous_name); | 337 CHECK_EQ("", *anonymous_name); |
| 338 | 338 |
| 339 // Find references to code. | 339 // Find references to code. |
| 340 const v8::HeapGraphNode* compiled_code = | 340 const v8::HeapGraphNode* compiled_code = |
| 341 GetProperty(compiled, v8::HeapGraphEdge::kInternal, "shared"); | 341 GetProperty(compiled, v8::HeapGraphEdge::kInternal, "shared"); |
| 342 CHECK_NE(NULL, compiled_code); | 342 CHECK_NE(NULL, compiled_code); |
| 343 const v8::HeapGraphNode* lazy_code = | 343 const v8::HeapGraphNode* lazy_code = |
| 344 GetProperty(lazy, v8::HeapGraphEdge::kInternal, "shared"); | 344 GetProperty(lazy, v8::HeapGraphEdge::kInternal, "shared"); |
| 345 CHECK_NE(NULL, lazy_code); | 345 CHECK_NE(NULL, lazy_code); |
| 346 | 346 |
| 347 // Check that there's no strong next_code_link. There might be a weak one |
| 348 // but might be not, so we can't check that fact. |
| 349 const v8::HeapGraphNode* code = |
| 350 GetProperty(compiled_code, v8::HeapGraphEdge::kInternal, "code"); |
| 351 CHECK_NE(NULL, code); |
| 352 const v8::HeapGraphNode* next_code_link = |
| 353 GetProperty(code, v8::HeapGraphEdge::kInternal, "code"); |
| 354 CHECK_EQ(NULL, next_code_link); |
| 355 |
| 347 // Verify that non-compiled code doesn't contain references to "x" | 356 // Verify that non-compiled code doesn't contain references to "x" |
| 348 // literal, while compiled code does. The scope info is stored in FixedArray | 357 // literal, while compiled code does. The scope info is stored in FixedArray |
| 349 // objects attached to the SharedFunctionInfo. | 358 // objects attached to the SharedFunctionInfo. |
| 350 bool compiled_references_x = false, lazy_references_x = false; | 359 bool compiled_references_x = false, lazy_references_x = false; |
| 351 for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) { | 360 for (int i = 0, count = compiled_code->GetChildrenCount(); i < count; ++i) { |
| 352 const v8::HeapGraphEdge* prop = compiled_code->GetChild(i); | 361 const v8::HeapGraphEdge* prop = compiled_code->GetChild(i); |
| 353 const v8::HeapGraphNode* node = prop->GetToNode(); | 362 const v8::HeapGraphNode* node = prop->GetToNode(); |
| 354 if (node->GetType() == v8::HeapGraphNode::kArray) { | 363 if (node->GetType() == v8::HeapGraphNode::kArray) { |
| 355 if (HasString(node, "x")) { | 364 if (HasString(node, "x")) { |
| 356 compiled_references_x = true; | 365 compiled_references_x = true; |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 CHECK(ValidateSnapshot(snapshot)); | 739 CHECK(ValidateSnapshot(snapshot)); |
| 731 | 740 |
| 732 TestJSONStream stream; | 741 TestJSONStream stream; |
| 733 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 742 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
| 734 CHECK_GT(stream.size(), 0); | 743 CHECK_GT(stream.size(), 0); |
| 735 CHECK_EQ(1, stream.eos_signaled()); | 744 CHECK_EQ(1, stream.eos_signaled()); |
| 736 i::ScopedVector<char> json(stream.size()); | 745 i::ScopedVector<char> json(stream.size()); |
| 737 stream.WriteTo(json); | 746 stream.WriteTo(json); |
| 738 | 747 |
| 739 // Verify that snapshot string is valid JSON. | 748 // Verify that snapshot string is valid JSON. |
| 740 AsciiResource json_res(json); | 749 AsciiResource* json_res = new AsciiResource(json); |
| 741 v8::Local<v8::String> json_string = | 750 v8::Local<v8::String> json_string = |
| 742 v8::String::NewExternal(env->GetIsolate(), &json_res); | 751 v8::String::NewExternal(env->GetIsolate(), json_res); |
| 743 env->Global()->Set(v8_str("json_snapshot"), json_string); | 752 env->Global()->Set(v8_str("json_snapshot"), json_string); |
| 744 v8::Local<v8::Value> snapshot_parse_result = CompileRun( | 753 v8::Local<v8::Value> snapshot_parse_result = CompileRun( |
| 745 "var parsed = JSON.parse(json_snapshot); true;"); | 754 "var parsed = JSON.parse(json_snapshot); true;"); |
| 746 CHECK(!snapshot_parse_result.IsEmpty()); | 755 CHECK(!snapshot_parse_result.IsEmpty()); |
| 747 | 756 |
| 748 // Verify that snapshot object has required fields. | 757 // Verify that snapshot object has required fields. |
| 749 v8::Local<v8::Object> parsed_snapshot = | 758 v8::Local<v8::Object> parsed_snapshot = |
| 750 env->Global()->Get(v8_str("parsed"))->ToObject(); | 759 env->Global()->Get(v8_str("parsed"))->ToObject(); |
| 751 CHECK(parsed_snapshot->Has(v8_str("snapshot"))); | 760 CHECK(parsed_snapshot->Has(v8_str("snapshot"))); |
| 752 CHECK(parsed_snapshot->Has(v8_str("nodes"))); | 761 CHECK(parsed_snapshot->Has(v8_str("nodes"))); |
| (...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 &name_resolver); | 1530 &name_resolver); |
| 1522 CHECK(ValidateSnapshot(snapshot)); | 1531 CHECK(ValidateSnapshot(snapshot)); |
| 1523 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1532 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1524 CHECK_NE(NULL, global); | 1533 CHECK_NE(NULL, global); |
| 1525 CHECK_EQ("Object / Global object name" , | 1534 CHECK_EQ("Object / Global object name" , |
| 1526 const_cast<i::HeapEntry*>( | 1535 const_cast<i::HeapEntry*>( |
| 1527 reinterpret_cast<const i::HeapEntry*>(global))->name()); | 1536 reinterpret_cast<const i::HeapEntry*>(global))->name()); |
| 1528 } | 1537 } |
| 1529 | 1538 |
| 1530 | 1539 |
| 1540 TEST(GlobalObjectFields) { |
| 1541 LocalContext env; |
| 1542 v8::HandleScope scope(env->GetIsolate()); |
| 1543 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1544 CompileRun("obj = {};"); |
| 1545 const v8::HeapSnapshot* snapshot = |
| 1546 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1547 CHECK(ValidateSnapshot(snapshot)); |
| 1548 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1549 const v8::HeapGraphNode* builtins = |
| 1550 GetProperty(global, v8::HeapGraphEdge::kInternal, "builtins"); |
| 1551 CHECK_NE(NULL, builtins); |
| 1552 const v8::HeapGraphNode* native_context = |
| 1553 GetProperty(global, v8::HeapGraphEdge::kInternal, "native_context"); |
| 1554 CHECK_NE(NULL, native_context); |
| 1555 const v8::HeapGraphNode* global_context = |
| 1556 GetProperty(global, v8::HeapGraphEdge::kInternal, "global_context"); |
| 1557 CHECK_NE(NULL, global_context); |
| 1558 const v8::HeapGraphNode* global_receiver = |
| 1559 GetProperty(global, v8::HeapGraphEdge::kInternal, "global_receiver"); |
| 1560 CHECK_NE(NULL, global_receiver); |
| 1561 } |
| 1562 |
| 1563 |
| 1531 TEST(NoHandleLeaks) { | 1564 TEST(NoHandleLeaks) { |
| 1532 LocalContext env; | 1565 LocalContext env; |
| 1533 v8::HandleScope scope(env->GetIsolate()); | 1566 v8::HandleScope scope(env->GetIsolate()); |
| 1534 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); | 1567 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1535 | 1568 |
| 1536 CompileRun("document = { URL:\"abcdefgh\" };"); | 1569 CompileRun("document = { URL:\"abcdefgh\" };"); |
| 1537 | 1570 |
| 1538 v8::Handle<v8::String> name(v8_str("leakz")); | 1571 v8::Handle<v8::String> name(v8_str("leakz")); |
| 1539 i::Isolate* isolate = CcTest::i_isolate(); | 1572 i::Isolate* isolate = CcTest::i_isolate(); |
| 1540 int count_before = i::HandleScope::NumberOfHandles(isolate); | 1573 int count_before = i::HandleScope::NumberOfHandles(isolate); |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1815 delete data.GetParameter(); | 1848 delete data.GetParameter(); |
| 1816 } | 1849 } |
| 1817 | 1850 |
| 1818 | 1851 |
| 1819 TEST(WeakGlobalHandle) { | 1852 TEST(WeakGlobalHandle) { |
| 1820 LocalContext env; | 1853 LocalContext env; |
| 1821 v8::HandleScope scope(env->GetIsolate()); | 1854 v8::HandleScope scope(env->GetIsolate()); |
| 1822 | 1855 |
| 1823 CHECK(!HasWeakGlobalHandle()); | 1856 CHECK(!HasWeakGlobalHandle()); |
| 1824 | 1857 |
| 1825 v8::Persistent<v8::Object>* handle = | 1858 v8::Persistent<v8::Object> handle(env->GetIsolate(), |
| 1826 new v8::Persistent<v8::Object>(env->GetIsolate(), | 1859 v8::Object::New(env->GetIsolate())); |
| 1827 v8::Object::New(env->GetIsolate())); | 1860 handle.SetWeak(&handle, PersistentHandleCallback); |
| 1828 handle->SetWeak(handle, PersistentHandleCallback); | |
| 1829 | 1861 |
| 1830 CHECK(HasWeakGlobalHandle()); | 1862 CHECK(HasWeakGlobalHandle()); |
| 1831 } | 1863 } |
| 1832 | 1864 |
| 1833 | 1865 |
| 1834 TEST(SfiAndJsFunctionWeakRefs) { | 1866 TEST(SfiAndJsFunctionWeakRefs) { |
| 1835 LocalContext env; | 1867 LocalContext env; |
| 1836 v8::HandleScope scope(env->GetIsolate()); | 1868 v8::HandleScope scope(env->GetIsolate()); |
| 1837 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); | 1869 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1838 | 1870 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2028 const v8::HeapGraphNode* transition_info = | 2060 const v8::HeapGraphNode* transition_info = |
| 2029 GetProperty(allocation_site, v8::HeapGraphEdge::kInternal, | 2061 GetProperty(allocation_site, v8::HeapGraphEdge::kInternal, |
| 2030 "transition_info"); | 2062 "transition_info"); |
| 2031 CHECK_NE(NULL, transition_info); | 2063 CHECK_NE(NULL, transition_info); |
| 2032 | 2064 |
| 2033 const v8::HeapGraphNode* elements = | 2065 const v8::HeapGraphNode* elements = |
| 2034 GetProperty(transition_info, v8::HeapGraphEdge::kInternal, | 2066 GetProperty(transition_info, v8::HeapGraphEdge::kInternal, |
| 2035 "elements"); | 2067 "elements"); |
| 2036 CHECK_NE(NULL, elements); | 2068 CHECK_NE(NULL, elements); |
| 2037 CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); | 2069 CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); |
| 2038 CHECK_EQ(v8::internal::FixedArray::SizeFor(3), elements->GetSelfSize()); | 2070 CHECK_EQ(v8::internal::FixedArray::SizeFor(3), |
| 2071 static_cast<int>(elements->GetShallowSize())); |
| 2039 | 2072 |
| 2040 v8::Handle<v8::Value> array_val = | 2073 v8::Handle<v8::Value> array_val = |
| 2041 heap_profiler->FindObjectById(transition_info->GetId()); | 2074 heap_profiler->FindObjectById(transition_info->GetId()); |
| 2042 CHECK(array_val->IsArray()); | 2075 CHECK(array_val->IsArray()); |
| 2043 v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(array_val); | 2076 v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(array_val); |
| 2044 // Verify the array is "a" in the code above. | 2077 // Verify the array is "a" in the code above. |
| 2045 CHECK_EQ(3, array->Length()); | 2078 CHECK_EQ(3, array->Length()); |
| 2046 CHECK_EQ(v8::Integer::New(isolate, 3), | 2079 CHECK_EQ(v8::Integer::New(isolate, 3), |
| 2047 array->Get(v8::Integer::New(isolate, 0))); | 2080 array->Get(v8::Integer::New(isolate, 0))); |
| 2048 CHECK_EQ(v8::Integer::New(isolate, 2), | 2081 CHECK_EQ(v8::Integer::New(isolate, 2), |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2106 const char* stub_path[] = { | 2139 const char* stub_path[] = { |
| 2107 "::(GC roots)", | 2140 "::(GC roots)", |
| 2108 "::(Strong roots)", | 2141 "::(Strong roots)", |
| 2109 "code_stubs::", | 2142 "code_stubs::", |
| 2110 "::(ArraySingleArgumentConstructorStub code)" | 2143 "::(ArraySingleArgumentConstructorStub code)" |
| 2111 }; | 2144 }; |
| 2112 const v8::HeapGraphNode* node = GetNodeByPath(snapshot, | 2145 const v8::HeapGraphNode* node = GetNodeByPath(snapshot, |
| 2113 stub_path, ARRAY_SIZE(stub_path)); | 2146 stub_path, ARRAY_SIZE(stub_path)); |
| 2114 CHECK_NE(NULL, node); | 2147 CHECK_NE(NULL, node); |
| 2115 | 2148 |
| 2116 const char* builtin_path[] = { | 2149 const char* builtin_path1[] = { |
| 2117 "::(GC roots)", | 2150 "::(GC roots)", |
| 2118 "::(Builtins)", | 2151 "::(Builtins)", |
| 2119 "::(KeyedLoadIC_Generic code)" | 2152 "::(KeyedLoadIC_Generic builtin)" |
| 2120 }; | 2153 }; |
| 2121 node = GetNodeByPath(snapshot, builtin_path, ARRAY_SIZE(builtin_path)); | 2154 node = GetNodeByPath(snapshot, builtin_path1, ARRAY_SIZE(builtin_path1)); |
| 2122 CHECK_NE(NULL, node); | 2155 CHECK_NE(NULL, node); |
| 2156 |
| 2157 const char* builtin_path2[] = { |
| 2158 "::(GC roots)", |
| 2159 "::(Builtins)", |
| 2160 "::(CompileUnoptimized builtin)" |
| 2161 }; |
| 2162 node = GetNodeByPath(snapshot, builtin_path2, ARRAY_SIZE(builtin_path2)); |
| 2163 CHECK_NE(NULL, node); |
| 2164 v8::String::Utf8Value node_name(node->GetName()); |
| 2165 CHECK_EQ("(CompileUnoptimized builtin)", *node_name); |
| 2123 } | 2166 } |
| 2124 | 2167 |
| 2125 | 2168 |
| 2126 static const char* record_trace_tree_source = | 2169 static const char* record_trace_tree_source = |
| 2127 "var topFunctions = [];\n" | 2170 "var topFunctions = [];\n" |
| 2128 "var global = this;\n" | 2171 "var global = this;\n" |
| 2129 "function generateFunctions(width, depth) {\n" | 2172 "function generateFunctions(width, depth) {\n" |
| 2130 " var script = [];\n" | 2173 " var script = [];\n" |
| 2131 " for (var i = 0; i < width; i++) {\n" | 2174 " for (var i = 0; i < width; i++) {\n" |
| 2132 " for (var j = 0; j < depth; j++) {\n" | 2175 " for (var j = 0; j < depth; j++) {\n" |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2312 | 2355 |
| 2313 AllocationTraceNode* node = | 2356 AllocationTraceNode* node = |
| 2314 FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); | 2357 FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); |
| 2315 CHECK_NE(NULL, node); | 2358 CHECK_NE(NULL, node); |
| 2316 CHECK_LT(node->allocation_count(), 100); | 2359 CHECK_LT(node->allocation_count(), 100); |
| 2317 | 2360 |
| 2318 CcTest::heap()->DisableInlineAllocation(); | 2361 CcTest::heap()->DisableInlineAllocation(); |
| 2319 heap_profiler->StopTrackingHeapObjects(); | 2362 heap_profiler->StopTrackingHeapObjects(); |
| 2320 } | 2363 } |
| 2321 } | 2364 } |
| 2365 |
| 2366 |
| 2367 TEST(ArrayBufferAndArrayBufferView) { |
| 2368 LocalContext env; |
| 2369 v8::HandleScope scope(env->GetIsolate()); |
| 2370 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 2371 CompileRun("arr1 = new Uint32Array(100);\n"); |
| 2372 const v8::HeapSnapshot* snapshot = |
| 2373 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 2374 CHECK(ValidateSnapshot(snapshot)); |
| 2375 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 2376 const v8::HeapGraphNode* arr1_obj = |
| 2377 GetProperty(global, v8::HeapGraphEdge::kProperty, "arr1"); |
| 2378 CHECK_NE(NULL, arr1_obj); |
| 2379 const v8::HeapGraphNode* arr1_buffer = |
| 2380 GetProperty(arr1_obj, v8::HeapGraphEdge::kInternal, "buffer"); |
| 2381 CHECK_NE(NULL, arr1_buffer); |
| 2382 const v8::HeapGraphNode* first_view = |
| 2383 GetProperty(arr1_buffer, v8::HeapGraphEdge::kWeak, "weak_first_view"); |
| 2384 CHECK_NE(NULL, first_view); |
| 2385 const v8::HeapGraphNode* backing_store = |
| 2386 GetProperty(arr1_buffer, v8::HeapGraphEdge::kInternal, "backing_store"); |
| 2387 CHECK_NE(NULL, backing_store); |
| 2388 CHECK_EQ(400, static_cast<int>(backing_store->GetShallowSize())); |
| 2389 } |
| 2390 |
| 2391 |
| 2392 static int GetRetainersCount(const v8::HeapSnapshot* snapshot, |
| 2393 const v8::HeapGraphNode* node) { |
| 2394 int count = 0; |
| 2395 for (int i = 0, l = snapshot->GetNodesCount(); i < l; ++i) { |
| 2396 const v8::HeapGraphNode* parent = snapshot->GetNode(i); |
| 2397 for (int j = 0, l2 = parent->GetChildrenCount(); j < l2; ++j) { |
| 2398 if (parent->GetChild(j)->GetToNode() == node) { |
| 2399 ++count; |
| 2400 } |
| 2401 } |
| 2402 } |
| 2403 return count; |
| 2404 } |
| 2405 |
| 2406 |
| 2407 TEST(ArrayBufferSharedBackingStore) { |
| 2408 LocalContext env; |
| 2409 v8::Isolate* isolate = env->GetIsolate(); |
| 2410 v8::HandleScope handle_scope(isolate); |
| 2411 v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); |
| 2412 |
| 2413 v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, 1024); |
| 2414 CHECK_EQ(1024, static_cast<int>(ab->ByteLength())); |
| 2415 CHECK(!ab->IsExternal()); |
| 2416 v8::ArrayBuffer::Contents ab_contents = ab->Externalize(); |
| 2417 CHECK(ab->IsExternal()); |
| 2418 |
| 2419 CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength())); |
| 2420 void* data = ab_contents.Data(); |
| 2421 ASSERT(data != NULL); |
| 2422 v8::Local<v8::ArrayBuffer> ab2 = |
| 2423 v8::ArrayBuffer::New(isolate, data, ab_contents.ByteLength()); |
| 2424 CHECK(ab2->IsExternal()); |
| 2425 env->Global()->Set(v8_str("ab1"), ab); |
| 2426 env->Global()->Set(v8_str("ab2"), ab2); |
| 2427 |
| 2428 v8::Handle<v8::Value> result = CompileRun("ab2.byteLength"); |
| 2429 CHECK_EQ(1024, result->Int32Value()); |
| 2430 |
| 2431 const v8::HeapSnapshot* snapshot = |
| 2432 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 2433 CHECK(ValidateSnapshot(snapshot)); |
| 2434 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 2435 const v8::HeapGraphNode* ab1_node = |
| 2436 GetProperty(global, v8::HeapGraphEdge::kProperty, "ab1"); |
| 2437 CHECK_NE(NULL, ab1_node); |
| 2438 const v8::HeapGraphNode* ab1_data = |
| 2439 GetProperty(ab1_node, v8::HeapGraphEdge::kInternal, "backing_store"); |
| 2440 CHECK_NE(NULL, ab1_data); |
| 2441 const v8::HeapGraphNode* ab2_node = |
| 2442 GetProperty(global, v8::HeapGraphEdge::kProperty, "ab2"); |
| 2443 CHECK_NE(NULL, ab2_node); |
| 2444 const v8::HeapGraphNode* ab2_data = |
| 2445 GetProperty(ab2_node, v8::HeapGraphEdge::kInternal, "backing_store"); |
| 2446 CHECK_NE(NULL, ab2_data); |
| 2447 CHECK_EQ(ab1_data, ab2_data); |
| 2448 CHECK_EQ(2, GetRetainersCount(snapshot, ab1_data)); |
| 2449 free(data); |
| 2450 } |
| 2451 |
| 2452 |
| 2453 TEST(BoxObject) { |
| 2454 v8::Isolate* isolate = CcTest::isolate(); |
| 2455 v8::HandleScope scope(isolate); |
| 2456 LocalContext env; |
| 2457 v8::Handle<v8::Object> global_proxy = env->Global(); |
| 2458 v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); |
| 2459 |
| 2460 i::Factory* factory = CcTest::i_isolate()->factory(); |
| 2461 i::Handle<i::String> string = |
| 2462 factory->NewStringFromAscii(i::CStrVector("string")); |
| 2463 i::Handle<i::Object> box = factory->NewBox(string); |
| 2464 global->Set(0, v8::ToApiHandle<v8::Object>(box)); |
| 2465 |
| 2466 v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); |
| 2467 const v8::HeapSnapshot* snapshot = |
| 2468 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 2469 CHECK(ValidateSnapshot(snapshot)); |
| 2470 const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); |
| 2471 const v8::HeapGraphNode* box_node = |
| 2472 GetProperty(global_node, v8::HeapGraphEdge::kElement, "0"); |
| 2473 CHECK_NE(NULL, box_node); |
| 2474 v8::String::Utf8Value box_node_name(box_node->GetName()); |
| 2475 CHECK_EQ("system / Box", *box_node_name); |
| 2476 const v8::HeapGraphNode* box_value = |
| 2477 GetProperty(box_node, v8::HeapGraphEdge::kInternal, "value"); |
| 2478 CHECK_NE(NULL, box_value); |
| 2479 } |
| OLD | NEW |