~ubuntu-branches/ubuntu/saucy/libv8/saucy

« back to all changes in this revision

Viewing changes to test/cctest/test-heap.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2012-04-07 16:26:13 UTC
  • mfrom: (15.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120407162613-dqo1m6w9r3fh8tst
Tags: 3.8.9.16-3
* mipsel build fixes :
  + v8_use_mips_abi_hardfloat=false, this lowers EABI requirements.
  + v8_can_use_fpu_instructions=false, detect if FPU is present.
  + set -Wno-unused-but-set-variable only on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
820
820
      FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
821
821
 
822
822
  // Allocate a large string (for large object space).
823
 
  int large_size = HEAP->MaxObjectSizeInPagedSpace() + 1;
 
823
  int large_size = Page::kMaxNonCodeHeapObjectSize + 1;
824
824
  char* str = new char[large_size];
825
825
  for (int i = 0; i < large_size - 1; ++i) str[i] = 'a';
826
826
  str[large_size - 1] = '\0';
1187
1187
}
1188
1188
 
1189
1189
 
 
1190
TEST(TestSizeOfObjects) {
 
1191
  v8::V8::Initialize();
 
1192
 
 
1193
  // Get initial heap size after several full GCs, which will stabilize
 
1194
  // the heap size and return with sweeping finished completely.
 
1195
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
1196
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
1197
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
1198
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
1199
  CHECK(HEAP->old_pointer_space()->IsSweepingComplete());
 
1200
  int initial_size = static_cast<int>(HEAP->SizeOfObjects());
 
1201
 
 
1202
  {
 
1203
    // Allocate objects on several different old-space pages so that
 
1204
    // lazy sweeping kicks in for subsequent GC runs.
 
1205
    AlwaysAllocateScope always_allocate;
 
1206
    int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
 
1207
    for (int i = 1; i <= 100; i++) {
 
1208
      HEAP->AllocateFixedArray(8192, TENURED)->ToObjectChecked();
 
1209
      CHECK_EQ(initial_size + i * filler_size,
 
1210
               static_cast<int>(HEAP->SizeOfObjects()));
 
1211
    }
 
1212
  }
 
1213
 
 
1214
  // The heap size should go back to initial size after a full GC, even
 
1215
  // though sweeping didn't finish yet.
 
1216
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
1217
  CHECK(!HEAP->old_pointer_space()->IsSweepingComplete());
 
1218
  CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
 
1219
 
 
1220
  // Advancing the sweeper step-wise should not change the heap size.
 
1221
  while (!HEAP->old_pointer_space()->IsSweepingComplete()) {
 
1222
    HEAP->old_pointer_space()->AdvanceSweeper(KB);
 
1223
    CHECK_EQ(initial_size, static_cast<int>(HEAP->SizeOfObjects()));
 
1224
  }
 
1225
}
 
1226
 
 
1227
 
1190
1228
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
1191
1229
  InitializeVM();
1192
1230
  HEAP->EnsureHeapIsIterable();
1290
1328
  CHECK(old_capacity == new_capacity);
1291
1329
}
1292
1330
 
 
1331
// This just checks the contract of the IdleNotification() function,
 
1332
// and does not verify that it does reasonable work.
 
1333
TEST(IdleNotificationAdvancesIncrementalMarking) {
 
1334
  if (!FLAG_incremental_marking || !FLAG_incremental_marking_steps) return;
 
1335
  InitializeVM();
 
1336
  v8::HandleScope scope;
 
1337
  const char* source = "function binom(n, m) {"
 
1338
                       "  var C = [[1]];"
 
1339
                       "  for (var i = 1; i <= n; ++i) {"
 
1340
                       "    C[i] = [1];"
 
1341
                       "    for (var j = 1; j < i; ++j) {"
 
1342
                       "      C[i][j] = C[i-1][j-1] + C[i-1][j];"
 
1343
                       "    }"
 
1344
                       "    C[i][i] = 1;"
 
1345
                       "  }"
 
1346
                       "  return C[n][m];"
 
1347
                       "};"
 
1348
                       "binom(1000, 500)";
 
1349
  {
 
1350
    AlwaysAllocateScope aa_scope;
 
1351
    CompileRun(source);
 
1352
  }
 
1353
  intptr_t old_size = HEAP->SizeOfObjects();
 
1354
  bool no_idle_work = v8::V8::IdleNotification(900);
 
1355
  while (!v8::V8::IdleNotification(900)) ;
 
1356
  intptr_t new_size = HEAP->SizeOfObjects();
 
1357
  CHECK(no_idle_work || new_size < old_size);
 
1358
}
 
1359
 
1293
1360
 
1294
1361
static int NumberOfGlobalObjects() {
1295
1362
  int count = 0;
1450
1517
 
1451
1518
 
1452
1519
TEST(InstanceOfStubWriteBarrier) {
1453
 
  if (!i::FLAG_crankshaft) return;
1454
1520
  i::FLAG_allow_natives_syntax = true;
1455
1521
#ifdef DEBUG
1456
1522
  i::FLAG_verify_heap = true;
1457
1523
#endif
1458
1524
  InitializeVM();
 
1525
  if (!i::V8::UseCrankshaft()) return;
1459
1526
  v8::HandleScope outer_scope;
1460
1527
 
1461
1528
  {
1505
1572
  HEAP->incremental_marking()->set_should_hurry(true);
1506
1573
  HEAP->CollectGarbage(OLD_POINTER_SPACE);
1507
1574
}
 
1575
 
 
1576
 
 
1577
TEST(PrototypeTransitionClearing) {
 
1578
  InitializeVM();
 
1579
  v8::HandleScope scope;
 
1580
 
 
1581
  CompileRun(
 
1582
      "var base = {};"
 
1583
      "var live = [];"
 
1584
      "for (var i = 0; i < 10; i++) {"
 
1585
      "  var object = {};"
 
1586
      "  var prototype = {};"
 
1587
      "  object.__proto__ = prototype;"
 
1588
      "  if (i >= 3) live.push(object, prototype);"
 
1589
      "}");
 
1590
 
 
1591
  Handle<JSObject> baseObject =
 
1592
      v8::Utils::OpenHandle(
 
1593
          *v8::Handle<v8::Object>::Cast(
 
1594
              v8::Context::GetCurrent()->Global()->Get(v8_str("base"))));
 
1595
 
 
1596
  // Verify that only dead prototype transitions are cleared.
 
1597
  CHECK_EQ(10, baseObject->map()->NumberOfProtoTransitions());
 
1598
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
1599
  CHECK_EQ(10 - 3, baseObject->map()->NumberOfProtoTransitions());
 
1600
 
 
1601
  // Verify that prototype transitions array was compacted.
 
1602
  FixedArray* trans = baseObject->map()->prototype_transitions();
 
1603
  for (int i = 0; i < 10 - 3; i++) {
 
1604
    int j = Map::kProtoTransitionHeaderSize +
 
1605
        i * Map::kProtoTransitionElementsPerEntry;
 
1606
    CHECK(trans->get(j + Map::kProtoTransitionMapOffset)->IsMap());
 
1607
    CHECK(trans->get(j + Map::kProtoTransitionPrototypeOffset)->IsJSObject());
 
1608
  }
 
1609
 
 
1610
  // Make sure next prototype is placed on an old-space evacuation candidate.
 
1611
  Handle<JSObject> prototype;
 
1612
  PagedSpace* space = HEAP->old_pointer_space();
 
1613
  do {
 
1614
    prototype = FACTORY->NewJSArray(32 * KB, TENURED);
 
1615
  } while (space->FirstPage() == space->LastPage() ||
 
1616
      !space->LastPage()->Contains(prototype->address()));
 
1617
 
 
1618
  // Add a prototype on an evacuation candidate and verify that transition
 
1619
  // clearing correctly records slots in prototype transition array.
 
1620
  i::FLAG_always_compact = true;
 
1621
  Handle<Map> map(baseObject->map());
 
1622
  CHECK(!space->LastPage()->Contains(map->prototype_transitions()->address()));
 
1623
  CHECK(space->LastPage()->Contains(prototype->address()));
 
1624
  baseObject->SetPrototype(*prototype, false)->ToObjectChecked();
 
1625
  CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
 
1626
  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 
1627
  CHECK(map->GetPrototypeTransition(*prototype)->IsMap());
 
1628
}