13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include <stdlib.h> 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#ifdef __linux__ 313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include <sys/types.h> 323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include <sys/stat.h> 333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include <fcntl.h> 343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include <unistd.h> 353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include <errno.h> 363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "global-handles.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "snapshot.h" 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "cctest.h" 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockusing namespace v8::internal; 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic v8::Persistent<v8::Context> env; 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitializeVM() { 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (env.IsEmpty()) env = v8::Context::New(); 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope scope; 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block env->Enter(); 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 553ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(MarkingDeque) { 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int mem_size = 20 * kPointerSize; 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* mem = NewArray<byte>(20*kPointerSize); 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address low = reinterpret_cast<Address>(mem); 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address high = low + mem_size; 603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch MarkingDeque s; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block s.Initialize(low, high); 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address address = NULL; 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!s.IsFull()) { 653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch s.PushBlack(HeapObject::FromAddress(address)); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block address += kPointerSize; 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!s.IsEmpty()) { 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address value = s.Pop()->address(); 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block address -= kPointerSize; 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(address, value); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(NULL, address); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(mem); 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(Promotion) { 81b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // This test requires compaction. If compaction is turned off, we 82b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // skip the entire test. 83b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_never_compact) return; 84b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Ensure that we get a compacting collection so that objects are promoted 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // from new space. 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_gc_global = true; 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FLAG_always_compact = true; 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->ConfigureHeap(2*256*KB, 8*MB, 8*MB); 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate a fixed array in the new space. 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int array_size = 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) / 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block (kPointerSize * 4); 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* obj = HEAP->AllocateFixedArray(array_size)->ToObjectChecked(); 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> array(FixedArray::cast(obj)); 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Array should be in the new space. 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->InSpace(*array, NEW_SPACE)); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call the m-c collector, so array becomes an old object. 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Array now sits in the old space 11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->InSpace(*array, OLD_POINTER_SPACE)); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(NoPromotion) { 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->ConfigureHeap(2*256*KB, 8*MB, 8*MB); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Test the situation that some objects in new space are promoted to 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the old space 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do a mark compact GC to shrink the heap. 12444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate a big Fixed array in the new space. 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int max_size = 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Min(Page::kMaxNonCodeHeapObjectSize, HEAP->MaxObjectSizeInNewSpace()); 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = (max_size - FixedArray::kHeaderSize) / (2*kPointerSize); 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* obj = i::Isolate::Current()->heap()->AllocateFixedArray(length)-> 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ToObjectChecked(); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray> array(FixedArray::cast(obj)); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Array still stays in the new space. 13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->InSpace(*array, NEW_SPACE)); 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Allocate objects in the old space until out of memory. 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FixedArray* host = *array; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (true) { 1425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* obj; 14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block { MaybeObject* maybe_obj = HEAP->AllocateFixedArray(100, TENURED); 1445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!maybe_obj->ToObject(&obj)) break; 1455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host->set(0, obj); 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block host = FixedArray::cast(obj); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call mark compact GC, and it should pass. 15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(MarkCompactCollector) { 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope sc; 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // call mark-compact when heap is empty 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // keep allocating garbage in new space until it fails 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int ARRAY_SIZE = 100; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* array; 1665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* maybe_array; 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block maybe_array = HEAP->AllocateFixedArray(ARRAY_SIZE); 1695913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } while (maybe_array->ToObject(&array)); 17044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(NEW_SPACE); 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 17244f0eee88ff00398ff7f715fab053374d808c90dSteve Block array = HEAP->AllocateFixedArray(ARRAY_SIZE)->ToObjectChecked(); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // keep allocating maps until it fails 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* mapp; 1765913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* maybe_mapp; 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { 17844f0eee88ff00398ff7f715fab053374d808c90dSteve Block maybe_mapp = HEAP->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 1795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } while (maybe_mapp->ToObject(&mapp)); 18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(MAP_SPACE); 18144f0eee88ff00398ff7f715fab053374d808c90dSteve Block mapp = HEAP->AllocateMap(JS_OBJECT_TYPE, 1825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck JSObject::kHeaderSize)->ToObjectChecked(); 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // allocate a garbage 1855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck String* func_name = 18644f0eee88ff00398ff7f715fab053374d808c90dSteve Block String::cast(HEAP->LookupAsciiSymbol("theFunction")->ToObjectChecked()); 1875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck SharedFunctionInfo* function_share = SharedFunctionInfo::cast( 18844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->AllocateSharedFunctionInfo(func_name)->ToObjectChecked()); 1895913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck JSFunction* function = JSFunction::cast( 19044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->AllocateFunction(*Isolate::Current()->function_map(), 1915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck function_share, 19244f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->undefined_value())->ToObjectChecked()); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* initial_map = 19444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Map::cast(HEAP->AllocateMap(JS_OBJECT_TYPE, 1955913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck JSObject::kHeaderSize)->ToObjectChecked()); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function->set_initial_map(initial_map); 19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->context()->global()->SetProperty( 19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block func_name, function, NONE, kNonStrictMode)->ToObjectChecked(); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block JSObject* obj = JSObject::cast( 20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->AllocateJSObject(function)->ToObjectChecked()); 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2045913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck func_name = 20544f0eee88ff00398ff7f715fab053374d808c90dSteve Block String::cast(HEAP->LookupAsciiSymbol("theFunction")->ToObjectChecked()); 20644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->context()->global()->HasLocalProperty(func_name)); 20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* func_value = Isolate::Current()->context()->global()-> 20844f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(func_name)->ToObjectChecked(); 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(func_value->IsJSFunction()); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block function = JSFunction::cast(func_value); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block obj = JSObject::cast(HEAP->AllocateJSObject(function)->ToObjectChecked()); 2135913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck String* obj_name = 21444f0eee88ff00398ff7f715fab053374d808c90dSteve Block String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked()); 21544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->context()->global()->SetProperty( 21644f0eee88ff00398ff7f715fab053374d808c90dSteve Block obj_name, obj, NONE, kNonStrictMode)->ToObjectChecked(); 2175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck String* prop_name = 21844f0eee88ff00398ff7f715fab053374d808c90dSteve Block String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked()); 219e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch obj->SetProperty(prop_name, 220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Smi::FromInt(23), 221e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch NONE, 222e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch kNonStrictMode)->ToObjectChecked(); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck obj_name = 22744f0eee88ff00398ff7f715fab053374d808c90dSteve Block String::cast(HEAP->LookupAsciiSymbol("theObject")->ToObjectChecked()); 22844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->context()->global()->HasLocalProperty(obj_name)); 22944f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(Isolate::Current()->context()->global()-> 23044f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(obj_name)->ToObjectChecked()->IsJSObject()); 23144f0eee88ff00398ff7f715fab053374d808c90dSteve Block obj = JSObject::cast(Isolate::Current()->context()->global()-> 23244f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetProperty(obj_name)->ToObjectChecked()); 2335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck prop_name = 23444f0eee88ff00398ff7f715fab053374d808c90dSteve Block String::cast(HEAP->LookupAsciiSymbol("theSlot")->ToObjectChecked()); 23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23)); 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// TODO(1600): compaction of map space is temporary removed from GC. 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if 0 241d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarkestatic Handle<Map> CreateMap() { 24244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return FACTORY->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 243d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 245d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 246d91b9f7d46489a9ee00f9cb415630299c76a502bLeon ClarkeTEST(MapCompact) { 247d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke FLAG_max_map_space_pages = 16; 248d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke InitializeVM(); 249d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 250d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke { 251d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke v8::HandleScope sc; 252d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // keep allocating maps while pointers are still encodable and thus 253d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // mark compact is permitted. 25444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSObject> root = FACTORY->NewJSObjectFromMap(CreateMap()); 255d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke do { 256d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke Handle<Map> map = CreateMap(); 257d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke map->set_prototype(*root); 25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block root = FACTORY->NewJSObjectFromMap(map); 25944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } while (HEAP->map_space()->MapPointersEncodable()); 260d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke } 261d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // Now, as we don't have any handles to just allocated maps, we should 262d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // be able to trigger map compaction. 263d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // To give an additional chance to fail, try to force compaction which 264d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // should be impossible right now. 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch HEAP->CollectAllGarbage(Heap::kForceCompactionMask); 266d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke // And now map pointers should be encodable again. 26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK(HEAP->map_space()->MapPointersEncodable()); 268d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke} 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif 270d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int gc_starts = 0; 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int gc_ends = 0; 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void GCPrologueCallbackFunc() { 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(gc_starts == gc_ends); 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block gc_starts++; 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void GCEpilogueCallbackFunc() { 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK(gc_starts == gc_ends + 1); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block gc_ends++; 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(GCCallback) { 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->SetGlobalGCPrologueCallback(&GCPrologueCallbackFunc); 29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->SetGlobalGCEpilogueCallback(&GCEpilogueCallbackFunc); 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Scavenge does not call GC callback functions. 29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->PerformScavenge(); 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, gc_starts); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(gc_ends, gc_starts); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(1, gc_starts); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(gc_ends, gc_starts); 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int NumberOfWeakCalls = 0; 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void WeakPointerCallback(v8::Persistent<v8::Value> handle, void* id) { 30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(id == reinterpret_cast<void*>(1234)); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NumberOfWeakCalls++; 30850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen handle.Dispose(); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockTEST(ObjectGroups) { 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block InitializeVM(); 3138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GlobalHandles* global_handles = Isolate::Current()->global_handles(); 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NumberOfWeakCalls = 0; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope handle_scope; 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> g1s1 = 31944f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> g1s2 = 3218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); 32244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> g1c1 = 3238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); 32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g1s1.location(), 32544f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g1s2.location(), 32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g1c1.location(), 33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> g2s1 = 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> g2s2 = 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); 33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> g2c1 = 33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); 34044f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g2s1.location(), 34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g2s2.location(), 34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 34544f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g2c1.location(), 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> root = global_handles->Create(*g1s1); // make a root. 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Connect group 1 and 2, make a cycle. 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray>::cast(g1s2)->set(0, *g2s2); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FixedArray>::cast(g2s1)->set(0, *g1s1); 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** g1_objects[] = { g1s1.location(), g1s2.location() }; 35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object** g1_children[] = { g1c1.location() }; 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** g2_objects[] = { g2s1.location(), g2s2.location() }; 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object** g2_children[] = { g2c1.location() }; 36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->AddObjectGroup(g1_objects, 2, NULL); 3628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->AddImplicitReferences( 3638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<HeapObject>::cast(g1s1).location(), g1_children, 1); 36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->AddObjectGroup(g2_objects, 2, NULL); 3658b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->AddImplicitReferences( 3668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<HeapObject>::cast(g2s2).location(), g2_children, 1); 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Do a full GC 36944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All object should be alive. 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(0, NumberOfWeakCalls); 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Weaken the root. 37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(root.location(), 37644f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // But make children strong roots---all the objects (except for children) 37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // should be collectable now. 38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->ClearWeakness(g1c1.location()); 38144f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->ClearWeakness(g2c1.location()); 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Groups are deleted, rebuild groups. 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** g1_objects[] = { g1s1.location(), g1s2.location() }; 38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object** g1_children[] = { g1c1.location() }; 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** g2_objects[] = { g2s1.location(), g2s2.location() }; 38844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object** g2_children[] = { g2c1.location() }; 38944f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->AddObjectGroup(g1_objects, 2, NULL); 3908b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->AddImplicitReferences( 3918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<HeapObject>::cast(g1s1).location(), g1_children, 1); 39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->AddObjectGroup(g2_objects, 2, NULL); 3938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->AddImplicitReferences( 3948b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<HeapObject>::cast(g2s2).location(), g2_children, 1); 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All objects should be gone. 5 global handles in total. 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CHECK_EQ(5, NumberOfWeakCalls); 40144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 40244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // And now make children weak again and collect them. 40344f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g1c1.location(), 40444f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 40544f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block global_handles->MakeWeak(g2c1.location(), 40744f0eee88ff00398ff7f715fab053374d808c90dSteve Block reinterpret_cast<void*>(1234), 40844f0eee88ff00398ff7f715fab053374d808c90dSteve Block &WeakPointerCallback); 40944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 41044f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->CollectGarbage(OLD_POINTER_SPACE); 41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CHECK_EQ(7, NumberOfWeakCalls); 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 4138b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochclass TestRetainedObjectInfo : public v8::RetainedObjectInfo { 4168b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch public: 4178b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch TestRetainedObjectInfo() : has_been_disposed_(false) {} 4188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch bool has_been_disposed() { return has_been_disposed_; } 4208b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual void Dispose() { 4228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(!has_been_disposed_); 4238b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch has_been_disposed_ = true; 4248b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 4258b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4268b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual bool IsEquivalent(v8::RetainedObjectInfo* other) { 4278b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return other == this; 4288b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 4298b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual intptr_t GetHash() { return 0; } 4318b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch virtual const char* GetLabel() { return "whatever"; } 4338b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch private: 4358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch bool has_been_disposed_; 4368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}; 4378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4398b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochTEST(EmptyObjectGroups) { 4408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch InitializeVM(); 4418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GlobalHandles* global_handles = Isolate::Current()->global_handles(); 4428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch v8::HandleScope handle_scope; 4448b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4458b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Object> object = 4468b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->Create(HEAP->AllocateFixedArray(1)->ToObjectChecked()); 4478b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4488b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch TestRetainedObjectInfo info; 4498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->AddObjectGroup(NULL, 0, &info); 4508b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(info.has_been_disposed()); 4518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 4528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch global_handles->AddImplicitReferences( 4538b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<HeapObject>::cast(object).location(), NULL, 0); 4548b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch} 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Here is a memory use test that uses /proc, and is therefore Linux-only. We 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// do not care how much memory the simulator uses, since it is only there for 4593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// debugging purposes. 4603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#if defined(__linux__) && !defined(USE_SIMULATOR) 4613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic uintptr_t ReadLong(char* buffer, intptr_t* position, int base) { 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char* end_address = buffer + *position; 4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t result = strtoul(buffer + *position, &end_address, base); 4663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(result != ULONG_MAX || errno != ERANGE); 4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(end_address > buffer + *position); 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *position = end_address - buffer; 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return result; 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic intptr_t MemoryInUse() { 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t memory_use = 0; 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int fd = open("/proc/self/maps", O_RDONLY); 4773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (fd < 0) return -1; 4783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int kBufSize = 10000; 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch char buffer[kBufSize]; 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = read(fd, buffer, kBufSize); 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t line_start = 0; 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_LT(length, kBufSize); // Make the buffer bigger. 4843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_GT(length, 0); // We have to find some data in the file. 4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (line_start < length) { 4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (buffer[line_start] == '\n') { 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch line_start++; 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t position = line_start; 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t start = ReadLong(buffer, &position, 16); 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(buffer[position++], '-'); 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t end = ReadLong(buffer, &position, 16); 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(buffer[position++], ' '); 4953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(buffer[position] == '-' || buffer[position] == 'r'); 4963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool read_permission = (buffer[position++] == 'r'); 4973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(buffer[position] == '-' || buffer[position] == 'w'); 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool write_permission = (buffer[position++] == 'w'); 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(buffer[position] == '-' || buffer[position] == 'x'); 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool execute_permission = (buffer[position++] == 'x'); 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK(buffer[position] == '-' || buffer[position] == 'p'); 5023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool private_mapping = (buffer[position++] == 'p'); 5033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(buffer[position++], ' '); 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t offset = ReadLong(buffer, &position, 16); 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch USE(offset); 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(buffer[position++], ' '); 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t major = ReadLong(buffer, &position, 16); 5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch USE(major); 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(buffer[position++], ':'); 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t minor = ReadLong(buffer, &position, 16); 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch USE(minor); 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_EQ(buffer[position++], ' '); 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uintptr_t inode = ReadLong(buffer, &position, 10); 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (position < length && buffer[position] != '\n') position++; 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((read_permission || write_permission || execute_permission) && 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private_mapping && inode == 0) { 5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch memory_use += (end - start); 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch line_start = position; 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch close(fd); 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return memory_use; 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochTEST(BootUpMemoryUse) { 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t initial_memory = MemoryInUse(); 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FLAG_crankshaft = false; // Avoid flakiness. 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only Linux has the proc filesystem and only if it is mapped. If it's not 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // there we just skip the test. 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (initial_memory >= 0) { 5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch InitializeVM(); 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch intptr_t booted_memory = MemoryInUse(); 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (sizeof(initial_memory) == 8) { 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (v8::internal::Snapshot::IsEnabled()) { 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_LE(booted_memory - initial_memory, 6686 * 1024); // 6476. 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_LE(booted_memory - initial_memory, 6809 * 1024); // 6628. 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (v8::internal::Snapshot::IsEnabled()) { 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_LE(booted_memory - initial_memory, 6532 * 1024); // 6388. 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CHECK_LE(booted_memory - initial_memory, 6940 * 1024); // 6456 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif // __linux__ and !USE_SIMULATOR 552