Version 3.17.0

Enabled parallel sweeping.

Don't try to unlink instructions twice during GVN (Chromium issue 175141)

Fixed code flusher disabling while marking incrementally. (Chromium issue 173458, 168582)

Don't use TLS for space iterators. (issue 2531)

Added new GetHeapStatistics API entry and deprecated old one.

Fixed DoubleStackSlot-to-DoubleStackSlot moves on ia32. Unified platform-independent code. (Chromium issue 173907)

Added --trace-array-abuse to help find OOB accesses.

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@13663 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index 5a80972..648d7eb 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -820,10 +820,10 @@
 }
 
 
-static int ObjectsFoundInHeap(Handle<Object> objs[], int size) {
+static int ObjectsFoundInHeap(Heap* heap, Handle<Object> objs[], int size) {
   // Count the number of objects found in the heap.
   int found_count = 0;
-  HeapIterator iterator;
+  HeapIterator iterator(heap);
   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
     for (int i = 0; i < size; i++) {
       if (*objs[i] == obj) {
@@ -869,7 +869,7 @@
   objs[next_objs_index++] = Handle<Map>(HeapObject::cast(*objs[0])->map());
 
   CHECK_EQ(objs_count, next_objs_index);
-  CHECK_EQ(objs_count, ObjectsFoundInHeap(objs, objs_count));
+  CHECK_EQ(objs_count, ObjectsFoundInHeap(HEAP, objs, objs_count));
 }
 
 
@@ -1465,7 +1465,7 @@
   InitializeVM();
   HEAP->EnsureHeapIsIterable();
   intptr_t size_of_objects_1 = HEAP->SizeOfObjects();
-  HeapIterator iterator;
+  HeapIterator iterator(HEAP);
   intptr_t size_of_objects_2 = 0;
   for (HeapObject* obj = iterator.next();
        obj != NULL;
@@ -1586,7 +1586,7 @@
 
 static int NumberOfGlobalObjects() {
   int count = 0;
-  HeapIterator iterator;
+  HeapIterator iterator(HEAP);
   for (HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next()) {
     if (obj->IsGlobalObject()) count++;
   }
@@ -2837,3 +2837,54 @@
   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
   HEAP->CollectAllGarbage(Heap::kNoGCFlags);
 }
+
+
+TEST(Regress173458) {
+  i::FLAG_always_compact = true;
+  i::FLAG_cache_optimized_code = false;
+  i::FLAG_allow_natives_syntax = true;
+  i::FLAG_flush_code_incrementally = true;
+  InitializeVM();
+  v8::HandleScope scope;
+
+  // Perform one initial GC to enable code flushing.
+  HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+
+  // Ensure the code ends up on an evacuation candidate.
+  SimulateFullSpace(HEAP->code_space());
+
+  // Prepare an unoptimized function that is eligible for code flushing.
+  Handle<JSFunction> function;
+  {
+    HandleScope inner_scope;
+    CompileRun("function mkClosure() {"
+               "  return function(x) { return x + 1; };"
+               "}"
+               "var f = mkClosure();"
+               "f(1); f(2);");
+
+    Handle<JSFunction> f =
+        v8::Utils::OpenHandle(
+            *v8::Handle<v8::Function>::Cast(
+                v8::Context::GetCurrent()->Global()->Get(v8_str("f"))));
+    CHECK(f->is_compiled());
+    const int kAgingThreshold = 6;
+    for (int i = 0; i < kAgingThreshold; i++) {
+      f->shared()->code()->MakeOlder(static_cast<MarkingParity>(i % 2));
+    }
+
+    function = inner_scope.CloseAndEscape(handle(*f, ISOLATE));
+  }
+
+  // Simulate incremental marking so that unoptimized function is enqueued as a
+  // candidate for code flushing. The shared function info however will not be
+  // explicitly enqueued.
+  SimulateIncrementalMarking();
+
+  // Now enable the debugger which in turn will disable code flushing.
+  CHECK(ISOLATE->debug()->Load());
+
+  // This cycle will bust the heap and subsequent cycles will go ballistic.
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+  HEAP->CollectAllGarbage(Heap::kNoGCFlags);
+}