1ab7dad4f999df008b590c74c2fe3d2e2c67ef7ffjkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
29a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// Redistribution and use in source and binary forms, with or without
39a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// modification, are permitted provided that the following conditions are
49a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// met:
59a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
69a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Redistributions of source code must retain the above copyright
79a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       notice, this list of conditions and the following disclaimer.
89a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Redistributions in binary form must reproduce the above
99a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       copyright notice, this list of conditions and the following
109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       disclaimer in the documentation and/or other materials provided
119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       with the distribution.
129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//     * Neither the name of Google Inc. nor the names of its
139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       contributors may be used to endorse or promote products derived
149a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//       from this software without specific prior written permission.
159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com//
169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
269a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
289a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include <stdlib.h>
299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#ifdef __linux__
3164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#include <sys/types.h>
3264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#include <sys/stat.h>
3364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#include <fcntl.h>
3464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#include <unistd.h>
3564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#include <errno.h>
3664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#endif
3764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
3857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "v8.h"
409a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "global-handles.h"
429a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "snapshot.h"
439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com#include "cctest.h"
449a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comusing namespace v8::internal;
469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
48c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comTEST(MarkingDeque) {
49e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CcTest::InitializeVM();
509a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  int mem_size = 20 * kPointerSize;
519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  byte* mem = NewArray<byte>(20*kPointerSize);
529a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Address low = reinterpret_cast<Address>(mem);
539a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Address high = low + mem_size;
54c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  MarkingDeque s;
559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  s.Initialize(low, high);
569a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Address original_address = reinterpret_cast<Address>(&s);
587c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  Address current_address = original_address;
59c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (!s.IsFull()) {
607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    s.PushBlack(HeapObject::FromAddress(current_address));
617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    current_address += kPointerSize;
629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
639a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
64c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  while (!s.IsEmpty()) {
659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com    Address value = s.Pop()->address();
667c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    current_address -= kPointerSize;
677c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org    CHECK_EQ(current_address, value);
689a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  }
699a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
707c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  CHECK_EQ(original_address, current_address);
719a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  DeleteArray(mem);
729a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
749a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
759a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(Promotion) {
76528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest::InitializeVM();
77528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Heap* heap = CcTest::heap();
78ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  heap->ConfigureHeap(2*256*KB, 1*MB, 1*MB);
799a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
80e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  v8::HandleScope sc(CcTest::isolate());
819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
829a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Allocate a fixed array in the new space.
83ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  int array_length =
84ab30bb83bf3dae0053739c57b1db9ad13c1f9e3ayangguo@chromium.org      (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) /
85ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      (4 * kPointerSize);
86ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  Object* obj = heap->AllocateFixedArray(array_length)->ToObjectChecked();
879a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<FixedArray> array(FixedArray::cast(obj));
889a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
899a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Array should be in the new space.
90528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(heap->InSpace(*array, NEW_SPACE));
919a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
92ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  // Call mark compact GC, so array becomes an old object.
93528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE);
949a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
959a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Array now sits in the old space
96528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(heap->InSpace(*array, OLD_POINTER_SPACE));
979a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(NoPromotion) {
101e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CcTest::InitializeVM();
102ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  Heap* heap = CcTest::heap();
103ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  heap->ConfigureHeap(2*256*KB, 1*MB, 1*MB);
104528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
105e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  v8::HandleScope sc(CcTest::isolate());
1069a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
107ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  // Allocate a big fixed array in the new space.
108ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  int array_length =
109ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      (Page::kMaxNonCodeHeapObjectSize - FixedArray::kHeaderSize) /
110ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org      (2 * kPointerSize);
111ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  Object* obj = heap->AllocateFixedArray(array_length)->ToObjectChecked();
1129a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<FixedArray> array(FixedArray::cast(obj));
1139a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
114ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  // Array should be in the new space.
115ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  CHECK(heap->InSpace(*array, NEW_SPACE));
1169a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
117ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  // Simulate a full old space to make promotion fail.
118ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  SimulateFullSpace(heap->old_pointer_space());
1199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Call mark compact GC, and it should pass.
121ef33a5482a35a9a25f702f8e3f02bb6b49f3854cjkummerow@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE);
1229a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
1239a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1249a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1259a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(MarkCompactCollector) {
1269259716434187c932704601f700375e53d865de8rossberg@chromium.org  FLAG_incremental_marking = false;
127e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CcTest::InitializeVM();
128528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = CcTest::i_isolate();
1299259716434187c932704601f700375e53d865de8rossberg@chromium.org  Heap* heap = isolate->heap();
1309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
131e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  v8::HandleScope sc(CcTest::isolate());
132528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<GlobalObject> global(isolate->context()->global_object());
1339259716434187c932704601f700375e53d865de8rossberg@chromium.org
1349a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // call mark-compact when heap is empty
1359259716434187c932704601f700375e53d865de8rossberg@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 1");
1369a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1379a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // keep allocating garbage in new space until it fails
1389a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  const int ARRAY_SIZE = 100;
1399a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Object* array;
140303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* maybe_array;
1419a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  do {
1429259716434187c932704601f700375e53d865de8rossberg@chromium.org    maybe_array = heap->AllocateFixedArray(ARRAY_SIZE);
143303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  } while (maybe_array->ToObject(&array));
1449259716434187c932704601f700375e53d865de8rossberg@chromium.org  heap->CollectGarbage(NEW_SPACE, "trigger 2");
1459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1469259716434187c932704601f700375e53d865de8rossberg@chromium.org  array = heap->AllocateFixedArray(ARRAY_SIZE)->ToObjectChecked();
1479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1489a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // keep allocating maps until it fails
1499a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Object* mapp;
150303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  MaybeObject* maybe_mapp;
1519a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  do {
1529259716434187c932704601f700375e53d865de8rossberg@chromium.org    maybe_mapp = heap->AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
153303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  } while (maybe_mapp->ToObject(&mapp));
1549259716434187c932704601f700375e53d865de8rossberg@chromium.org  heap->CollectGarbage(MAP_SPACE, "trigger 3");
1559259716434187c932704601f700375e53d865de8rossberg@chromium.org  mapp = heap->AllocateMap(JS_OBJECT_TYPE,
156303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                           JSObject::kHeaderSize)->ToObjectChecked();
1579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1589a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // allocate a garbage
1594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  String* func_name = String::cast(
1609259716434187c932704601f700375e53d865de8rossberg@chromium.org      heap->InternalizeUtf8String("theFunction")->ToObjectChecked());
161303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  SharedFunctionInfo* function_share = SharedFunctionInfo::cast(
1629259716434187c932704601f700375e53d865de8rossberg@chromium.org      heap->AllocateSharedFunctionInfo(func_name)->ToObjectChecked());
163303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  JSFunction* function = JSFunction::cast(
1649259716434187c932704601f700375e53d865de8rossberg@chromium.org      heap->AllocateFunction(*isolate->function_map(),
165303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                             function_share,
1669259716434187c932704601f700375e53d865de8rossberg@chromium.org                             heap->undefined_value())->ToObjectChecked());
1679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Map* initial_map =
1689259716434187c932704601f700375e53d865de8rossberg@chromium.org      Map::cast(heap->AllocateMap(JS_OBJECT_TYPE,
169303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org                                  JSObject::kHeaderSize)->ToObjectChecked());
1709a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  function->set_initial_map(initial_map);
171528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  JSReceiver::SetProperty(
172528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      global, handle(func_name), handle(function), NONE, kNonStrictMode);
1739a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
174ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  JSObject* obj = JSObject::cast(
1759259716434187c932704601f700375e53d865de8rossberg@chromium.org      heap->AllocateJSObject(function)->ToObjectChecked());
1769259716434187c932704601f700375e53d865de8rossberg@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 4");
1779a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  func_name = String::cast(
1799259716434187c932704601f700375e53d865de8rossberg@chromium.org      heap->InternalizeUtf8String("theFunction")->ToObjectChecked());
180528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(JSReceiver::HasLocalProperty(global, handle(func_name)));
1819259716434187c932704601f700375e53d865de8rossberg@chromium.org  Object* func_value = isolate->context()->global_object()->
182ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      GetProperty(func_name)->ToObjectChecked();
1839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  CHECK(func_value->IsJSFunction());
1849a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  function = JSFunction::cast(func_value);
1859a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1869259716434187c932704601f700375e53d865de8rossberg@chromium.org  obj = JSObject::cast(heap->AllocateJSObject(function)->ToObjectChecked());
187303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  String* obj_name =
1889259716434187c932704601f700375e53d865de8rossberg@chromium.org      String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked());
189528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  JSReceiver::SetProperty(
190528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      global, handle(obj_name), handle(obj), NONE, kNonStrictMode);
191303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  String* prop_name =
1929259716434187c932704601f700375e53d865de8rossberg@chromium.org      String::cast(heap->InternalizeUtf8String("theSlot")->ToObjectChecked());
193528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Smi> twenty_three(Smi::FromInt(23), isolate);
194528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  JSReceiver::SetProperty(
195528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      handle(obj), handle(prop_name), twenty_three, NONE, kNonStrictMode);
1969a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
1979259716434187c932704601f700375e53d865de8rossberg@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE, "trigger 5");
1989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
199303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  obj_name =
2009259716434187c932704601f700375e53d865de8rossberg@chromium.org      String::cast(heap->InternalizeUtf8String("theObject")->ToObjectChecked());
201528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(JSReceiver::HasLocalProperty(global, handle(obj_name)));
2029259716434187c932704601f700375e53d865de8rossberg@chromium.org  CHECK(isolate->context()->global_object()->
203ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        GetProperty(obj_name)->ToObjectChecked()->IsJSObject());
2049259716434187c932704601f700375e53d865de8rossberg@chromium.org  obj = JSObject::cast(isolate->context()->global_object()->
205ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                       GetProperty(obj_name)->ToObjectChecked());
206303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org  prop_name =
2079259716434187c932704601f700375e53d865de8rossberg@chromium.org      String::cast(heap->InternalizeUtf8String("theSlot")->ToObjectChecked());
208ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  CHECK(obj->GetProperty(prop_name) == Smi::FromInt(23));
2099a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2109a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2119a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com// TODO(1600): compaction of map space is temporary removed from GC.
213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#if 0
214d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgstatic Handle<Map> CreateMap(Isolate* isolate) {
215d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  return isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
216eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org}
217eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org
218eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org
219eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.orgTEST(MapCompact) {
220eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  FLAG_max_map_space_pages = 16;
221e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CcTest::InitializeVM();
222528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Isolate* isolate = CcTest::i_isolate();
223d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  Factory* factory = isolate->factory();
224eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org
225eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  {
226eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org    v8::HandleScope sc;
227eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org    // keep allocating maps while pointers are still encodable and thus
228eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org    // mark compact is permitted.
229d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org    Handle<JSObject> root = factory->NewJSObjectFromMap(CreateMap());
230eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org    do {
231eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org      Handle<Map> map = CreateMap();
232eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org      map->set_prototype(*root);
233d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org      root = factory->NewJSObjectFromMap(map);
234528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    } while (CcTest::heap()->map_space()->MapPointersEncodable());
235eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  }
236eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // Now, as we don't have any handles to just allocated maps, we should
237eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // be able to trigger map compaction.
238eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // To give an additional chance to fail, try to force compaction which
239eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // should be impossible right now.
240528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CcTest::heap()->CollectAllGarbage(Heap::kForceCompactionMask);
241eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org  // And now map pointers should be encodable again.
242528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  CHECK(CcTest::heap()->map_space()->MapPointersEncodable());
243eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org}
244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com#endif
245eac059f89a80696ba7043be022b761f0e315e1eckasperl@chromium.org
2469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comstatic int NumberOfWeakCalls = 0;
248d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgstatic void WeakPointerCallback(v8::Isolate* isolate,
24957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org                                v8::Persistent<v8::Value>* handle,
250d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org                                void* id) {
251badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  ASSERT(id == reinterpret_cast<void*>(1234));
2529a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  NumberOfWeakCalls++;
253f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  handle->Reset();
2549a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
2559a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
256e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
2579a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.comTEST(ObjectGroups) {
25883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org  FLAG_incremental_marking = false;
259e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CcTest::InitializeVM();
260528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();
261528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Heap* heap = CcTest::heap();
2629a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  NumberOfWeakCalls = 0;
263e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  v8::HandleScope handle_scope(CcTest::isolate());
2649a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2659a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<Object> g1s1 =
266528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
2679a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<Object> g1s2 =
268528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
269badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  Handle<Object> g1c1 =
270528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
271ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g1s1.location(),
272ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
27379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
274ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g1s2.location(),
275ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
27679e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
277ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g1c1.location(),
278ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
27979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
2809a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2819a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<Object> g2s1 =
282528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
2839a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<Object> g2s2 =
284528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
285badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  Handle<Object> g2c1 =
286528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    global_handles->Create(heap->AllocateFixedArray(1)->ToObjectChecked());
287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g2s1.location(),
288ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
28979e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
290ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g2s2.location(),
291ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
29279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
293ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g2c1.location(),
294ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
29579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
296ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
297ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Handle<Object> root = global_handles->Create(*g1s1);  // make a root.
2989a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
2999a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Connect group 1 and 2, make a cycle.
3009a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<FixedArray>::cast(g1s2)->set(0, *g2s2);
3019a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  Handle<FixedArray>::cast(g2s1)->set(0, *g1s1);
3029a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3038bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  {
3048bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    Object** g1_objects[] = { g1s1.location(), g1s2.location() };
305badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    Object** g1_children[] = { g1c1.location() };
3068bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    Object** g2_objects[] = { g2s1.location(), g2s2.location() };
307badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    Object** g2_children[] = { g2c1.location() };
308ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    global_handles->AddObjectGroup(g1_objects, 2, NULL);
30944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    global_handles->AddImplicitReferences(
31044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        Handle<HeapObject>::cast(g1s1).location(), g1_children, 1);
311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    global_handles->AddObjectGroup(g2_objects, 2, NULL);
31244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    global_handles->AddImplicitReferences(
313ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        Handle<HeapObject>::cast(g2s1).location(), g2_children, 1);
3148bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
3159a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Do a full GC
316528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE);
3179a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3189a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // All object should be alive.
3199a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  CHECK_EQ(0, NumberOfWeakCalls);
3209a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3219a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Weaken the root.
322ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(root.location(),
323ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
32479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
325badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // But make children strong roots---all the objects (except for children)
326badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // should be collectable now.
327ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->ClearWeakness(g1c1.location());
328ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->ClearWeakness(g2c1.location());
3299a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3309a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // Groups are deleted, rebuild groups.
3318bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  {
3328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    Object** g1_objects[] = { g1s1.location(), g1s2.location() };
333badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    Object** g1_children[] = { g1c1.location() };
3348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    Object** g2_objects[] = { g2s1.location(), g2s2.location() };
335badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org    Object** g2_children[] = { g2c1.location() };
336ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    global_handles->AddObjectGroup(g1_objects, 2, NULL);
33744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    global_handles->AddImplicitReferences(
33844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        Handle<HeapObject>::cast(g1s1).location(), g1_children, 1);
339ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    global_handles->AddObjectGroup(g2_objects, 2, NULL);
34044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    global_handles->AddImplicitReferences(
341ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org        Handle<HeapObject>::cast(g2s1).location(), g2_children, 1);
3428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
3439a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
344528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE);
3459a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com
3469a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  // All objects should be gone. 5 global handles in total.
3479a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com  CHECK_EQ(5, NumberOfWeakCalls);
348badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
349badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // And now make children weak again and collect them.
350ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g1c1.location(),
351ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
35279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
353ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  global_handles->MakeWeak(g2c1.location(),
354ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                           reinterpret_cast<void*>(1234),
35579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org                           &WeakPointerCallback);
356ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
357528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  heap->CollectGarbage(OLD_POINTER_SPACE);
358badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  CHECK_EQ(7, NumberOfWeakCalls);
3599a4089a092cad9ff23b6416b92cd5d818dc101d1mads.s.ager@gmail.com}
36044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
36144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
36244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgclass TestRetainedObjectInfo : public v8::RetainedObjectInfo {
36344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org public:
36444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  TestRetainedObjectInfo() : has_been_disposed_(false) {}
36544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
36644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  bool has_been_disposed() { return has_been_disposed_; }
36744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
36844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  virtual void Dispose() {
36944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    ASSERT(!has_been_disposed_);
37044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    has_been_disposed_ = true;
37144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
37244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
37344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  virtual bool IsEquivalent(v8::RetainedObjectInfo* other) {
37444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org    return other == this;
37544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  }
37644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
37744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  virtual intptr_t GetHash() { return 0; }
37844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
37944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  virtual const char* GetLabel() { return "whatever"; }
38044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
38144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org private:
38244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  bool has_been_disposed_;
38344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org};
38444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
38544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
38644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgTEST(EmptyObjectGroups) {
387e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  CcTest::InitializeVM();
388528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  GlobalHandles* global_handles = CcTest::i_isolate()->global_handles();
38944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
390e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  v8::HandleScope handle_scope(CcTest::isolate());
39144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
392528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  Handle<Object> object = global_handles->Create(
393528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      CcTest::heap()->AllocateFixedArray(1)->ToObjectChecked());
39444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
39544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  TestRetainedObjectInfo info;
39644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  global_handles->AddObjectGroup(NULL, 0, &info);
39744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  ASSERT(info.has_been_disposed());
39844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org
39944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  global_handles->AddImplicitReferences(
40044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org        Handle<HeapObject>::cast(object).location(), NULL, 0);
40144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}
40264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
40364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
4044e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org#if defined(__has_feature)
4054e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org#if __has_feature(address_sanitizer)
4064e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org#define V8_WITH_ASAN 1
4074e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org#endif
4084e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org#endif
4094e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
4104e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
41164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org// Here is a memory use test that uses /proc, and is therefore Linux-only.  We
41264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org// do not care how much memory the simulator uses, since it is only there for
4134e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org// debugging purposes. Testing with ASAN doesn't make sense, either.
4144e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org#if defined(__linux__) && !defined(USE_SIMULATOR) && !defined(V8_WITH_ASAN)
41564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
41664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
41764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgstatic uintptr_t ReadLong(char* buffer, intptr_t* position, int base) {
41864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  char* end_address = buffer + *position;
41964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  uintptr_t result = strtoul(buffer + *position, &end_address, base);
42064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  CHECK(result != ULONG_MAX || errno != ERANGE);
42164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  CHECK(end_address > buffer + *position);
42264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  *position = end_address - buffer;
42364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  return result;
42464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
42564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
42664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
4274cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org// The memory use computed this way is not entirely accurate and depends on
4284cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org// the way malloc allocates memory.  That's why the memory use may seem to
4294cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org// increase even though the sum of the allocated object sizes decreases.  It
4304cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org// also means that the memory use depends on the kernel and stdlib.
43164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgstatic intptr_t MemoryInUse() {
43264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  intptr_t memory_use = 0;
43364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
43464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  int fd = open("/proc/self/maps", O_RDONLY);
43564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (fd < 0) return -1;
43664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
43764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  const int kBufSize = 10000;
43864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  char buffer[kBufSize];
43964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  int length = read(fd, buffer, kBufSize);
44064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  intptr_t line_start = 0;
44164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  CHECK_LT(length, kBufSize);  // Make the buffer bigger.
44264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  CHECK_GT(length, 0);  // We have to find some data in the file.
44364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  while (line_start < length) {
44464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    if (buffer[line_start] == '\n') {
44564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      line_start++;
44664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      continue;
44764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
44864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    intptr_t position = line_start;
44964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    uintptr_t start = ReadLong(buffer, &position, 16);
45064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK_EQ(buffer[position++], '-');
45164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    uintptr_t end = ReadLong(buffer, &position, 16);
45264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK_EQ(buffer[position++], ' ');
45364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK(buffer[position] == '-' || buffer[position] == 'r');
45464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    bool read_permission = (buffer[position++] == 'r');
45564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK(buffer[position] == '-' || buffer[position] == 'w');
45664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    bool write_permission = (buffer[position++] == 'w');
45764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK(buffer[position] == '-' || buffer[position] == 'x');
45864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    bool execute_permission = (buffer[position++] == 'x');
45964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK(buffer[position] == '-' || buffer[position] == 'p');
46064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    bool private_mapping = (buffer[position++] == 'p');
46164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK_EQ(buffer[position++], ' ');
46264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    uintptr_t offset = ReadLong(buffer, &position, 16);
46364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    USE(offset);
46464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK_EQ(buffer[position++], ' ');
46564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    uintptr_t major = ReadLong(buffer, &position, 16);
46664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    USE(major);
46764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK_EQ(buffer[position++], ':');
46864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    uintptr_t minor = ReadLong(buffer, &position, 16);
46964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    USE(minor);
47064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    CHECK_EQ(buffer[position++], ' ');
47164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    uintptr_t inode = ReadLong(buffer, &position, 10);
47264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    while (position < length && buffer[position] != '\n') position++;
47364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    if ((read_permission || write_permission || execute_permission) &&
47464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org        private_mapping && inode == 0) {
47564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org      memory_use += (end - start);
47664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    }
47764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
47864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org    line_start = position;
47964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
48064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  close(fd);
48164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  return memory_use;
48264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
48364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
48464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
48564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgTEST(BootUpMemoryUse) {
48664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  intptr_t initial_memory = MemoryInUse();
487304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  // Avoid flakiness.
488304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org  FLAG_crankshaft = false;
4899259716434187c932704601f700375e53d865de8rossberg@chromium.org  FLAG_concurrent_recompilation = false;
490304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org
49164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Only Linux has the proc filesystem and only if it is mapped.  If it's not
49264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // there we just skip the test.
49364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  if (initial_memory >= 0) {
494e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    CcTest::InitializeVM();
495830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    intptr_t delta = MemoryInUse() - initial_memory;
4964cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    printf("delta: %" V8_PTR_PREFIX "d kB\n", delta / 1024);
4974cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    if (sizeof(initial_memory) == 8) {  // 64-bit.
498659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      if (v8::internal::Snapshot::IsEnabled()) {
4998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org        CHECK_LE(delta, 4000 * 1024);
500659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      } else {
5018432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org        CHECK_LE(delta, 4500 * 1024);
502659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      }
5034cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    } else {                            // 32-bit.
504659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      if (v8::internal::Snapshot::IsEnabled()) {
5051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        CHECK_LE(delta, 3100 * 1024);
506659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      } else {
507e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org        CHECK_LE(delta, 3450 * 1024);
508659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org      }
509659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org    }
51064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  }
51164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org}
51264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
51393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
51493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgintptr_t ShortLivingIsolate() {
51593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  v8::Isolate* isolate = v8::Isolate::New();
51693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  { v8::Isolate::Scope isolate_scope(isolate);
51793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    v8::Locker lock(isolate);
518c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org    v8::HandleScope handle_scope(isolate);
51993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    v8::Local<v8::Context> context = v8::Context::New(isolate);
52093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    CHECK(!context.IsEmpty());
52193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
52293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  isolate->Dispose();
52393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  return MemoryInUse();
52493a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org}
52593a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
52693a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
52793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.orgTEST(RegressJoinThreadsOnIsolateDeinit) {
52893a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  intptr_t size_limit = ShortLivingIsolate() * 2;
52993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  for (int i = 0; i < 10; i++) {
53093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org    CHECK_GT(size_limit, ShortLivingIsolate());
53193a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org  }
53293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org}
53393a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org
53464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#endif  // __linux__ and !USE_SIMULATOR
535