820
820
FACTORY->NewStringFromAscii(CStrVector("abcdefghij"), TENURED);
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';
1190
TEST(TestSizeOfObjects) {
1191
v8::V8::Initialize();
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());
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()));
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()));
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()));
1190
1228
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
1191
1229
InitializeVM();
1192
1230
HEAP->EnsureHeapIsIterable();
1290
1328
CHECK(old_capacity == new_capacity);
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;
1336
v8::HandleScope scope;
1337
const char* source = "function binom(n, m) {"
1339
" for (var i = 1; i <= n; ++i) {"
1341
" for (var j = 1; j < i; ++j) {"
1342
" C[i][j] = C[i-1][j-1] + C[i-1][j];"
1350
AlwaysAllocateScope aa_scope;
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);
1294
1361
static int NumberOfGlobalObjects() {
1452
1519
TEST(InstanceOfStubWriteBarrier) {
1453
if (!i::FLAG_crankshaft) return;
1454
1520
i::FLAG_allow_natives_syntax = true;
1456
1522
i::FLAG_verify_heap = true;
1458
1524
InitializeVM();
1525
if (!i::V8::UseCrankshaft()) return;
1459
1526
v8::HandleScope outer_scope;
1505
1572
HEAP->incremental_marking()->set_should_hurry(true);
1506
1573
HEAP->CollectGarbage(OLD_POINTER_SPACE);
1577
TEST(PrototypeTransitionClearing) {
1579
v8::HandleScope scope;
1584
"for (var i = 0; i < 10; i++) {"
1586
" var prototype = {};"
1587
" object.__proto__ = prototype;"
1588
" if (i >= 3) live.push(object, prototype);"
1591
Handle<JSObject> baseObject =
1592
v8::Utils::OpenHandle(
1593
*v8::Handle<v8::Object>::Cast(
1594
v8::Context::GetCurrent()->Global()->Get(v8_str("base"))));
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());
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());
1610
// Make sure next prototype is placed on an old-space evacuation candidate.
1611
Handle<JSObject> prototype;
1612
PagedSpace* space = HEAP->old_pointer_space();
1614
prototype = FACTORY->NewJSArray(32 * KB, TENURED);
1615
} while (space->FirstPage() == space->LastPage() ||
1616
!space->LastPage()->Contains(prototype->address()));
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());