deps: update V8 to 4.4.63.30
authorMichaël Zasso <mic.besace@gmail.com>
Thu, 27 Aug 2015 07:10:22 +0000 (09:10 +0200)
committerMichaël Zasso <mic.besace@gmail.com>
Fri, 28 Aug 2015 06:17:46 +0000 (08:17 +0200)
PR-URL: https://github.com/nodejs/node/pull/2482
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
deps/v8/include/v8-version.h
deps/v8/src/heap/gc-idle-time-handler.cc
deps/v8/src/heap/gc-idle-time-handler.h
deps/v8/src/heap/heap.cc
deps/v8/src/hydrogen.cc
deps/v8/src/objects.cc
deps/v8/test/cctest/test-api.cc
deps/v8/test/mjsunit/regress/regress-crbug-513602.js [new file with mode: 0644]

index c52267e..180969f 100644 (file)
@@ -11,7 +11,7 @@
 #define V8_MAJOR_VERSION 4
 #define V8_MINOR_VERSION 4
 #define V8_BUILD_NUMBER 63
-#define V8_PATCH_LEVEL 26
+#define V8_PATCH_LEVEL 30
 
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
index e20a1e4..5baf024 100644 (file)
@@ -113,6 +113,10 @@ bool GCIdleTimeHandler::ShouldDoScavenge(
     size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
     size_t scavenge_speed_in_bytes_per_ms,
     size_t new_space_allocation_throughput_in_bytes_per_ms) {
+  if (idle_time_in_ms >= kMinBackgroundIdleTime) {
+    // It is better to do full GC for the background tab.
+    return false;
+  }
   size_t new_space_allocation_limit =
       kMaxScheduledIdleTime * scavenge_speed_in_bytes_per_ms;
 
@@ -185,7 +189,10 @@ bool GCIdleTimeHandler::ShouldDoOverApproximateWeakClosure(
 }
 
 
-GCIdleTimeAction GCIdleTimeHandler::NothingOrDone() {
+GCIdleTimeAction GCIdleTimeHandler::NothingOrDone(double idle_time_in_ms) {
+  if (idle_time_in_ms >= kMinBackgroundIdleTime) {
+    return GCIdleTimeAction::Nothing();
+  }
   if (idle_times_which_made_no_progress_per_mode_ >=
       kMaxNoProgressIdleTimesPerMode) {
     return GCIdleTimeAction::Done();
@@ -235,6 +242,13 @@ GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms,
                                             HeapState heap_state) {
   Mode next_mode = NextMode(heap_state);
 
+  // Immediately go from reduce latency to reduce memory mode in
+  // background tab.
+  if (next_mode == kReduceLatency &&
+      idle_time_in_ms >= kMinBackgroundIdleTime) {
+    next_mode = kReduceMemory;
+  }
+
   if (next_mode != mode_) {
     mode_ = next_mode;
     ResetCounters();
@@ -298,13 +312,13 @@ GCIdleTimeAction GCIdleTimeHandler::Action(double idle_time_in_ms,
     if (heap_state.sweeping_completed) {
       return GCIdleTimeAction::FinalizeSweeping();
     } else {
-      return NothingOrDone();
+      return NothingOrDone(idle_time_in_ms);
     }
   }
 
   if (heap_state.incremental_marking_stopped &&
       !heap_state.can_start_incremental_marking && !reduce_memory) {
-    return NothingOrDone();
+    return NothingOrDone(idle_time_in_ms);
   }
 
   size_t step_size = EstimateMarkingStepSize(
index 1ffa3ef..1ab506d 100644 (file)
@@ -231,6 +231,10 @@ class GCIdleTimeHandler {
       size_t scavenger_speed_in_bytes_per_ms,
       size_t new_space_allocation_throughput_in_bytes_per_ms);
 
+  bool ShouldGrowHeapSlowly() {
+    return mode() == kDone;
+  }
+
   enum Mode { kReduceLatency, kReduceMemory, kDone };
 
   Mode mode() { return mode_; }
@@ -244,7 +248,7 @@ class GCIdleTimeHandler {
   Mode NextMode(const HeapState& heap_state);
   GCIdleTimeAction Action(double idle_time_in_ms, const HeapState& heap_state,
                           bool reduce_memory);
-  GCIdleTimeAction NothingOrDone();
+  GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
 
   int idle_mark_compacts_;
   int mark_compacts_;
index 6bfa4ae..f971359 100644 (file)
@@ -5407,6 +5407,12 @@ void Heap::SetOldGenerationAllocationLimit(intptr_t old_gen_size,
     factor = min_factor;
   }
 
+  const double kConservativeHeapGrowingFactor = 1.3;
+  if (gc_idle_time_handler_.ShouldGrowHeapSlowly()) {
+    factor = Min(factor, kConservativeHeapGrowingFactor);
+  }
+
+
   idle_factor = Min(factor, idle_max_factor);
 
   old_generation_allocation_limit_ =
index 6a86c73..455af79 100644 (file)
@@ -11300,16 +11300,20 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
   HValue* object_size_constant = Add<HConstant>(initial_map->instance_size());
 
   PretenureFlag pretenure_flag = NOT_TENURED;
-  Handle<AllocationSite> current_site(*site_context->current(), isolate());
+  Handle<AllocationSite> top_site(*site_context->top(), isolate());
   if (FLAG_allocation_site_pretenuring) {
-    pretenure_flag = current_site->GetPretenureMode();
-    top_info()->dependencies()->AssumeTenuringDecision(current_site);
+    pretenure_flag = top_site->GetPretenureMode();
   }
 
+  Handle<AllocationSite> current_site(*site_context->current(), isolate());
+  if (*top_site == *current_site) {
+    // We install a dependency for pretenuring only on the outermost literal.
+    top_info()->dependencies()->AssumeTenuringDecision(top_site);
+  }
   top_info()->dependencies()->AssumeTransitionStable(current_site);
 
   HInstruction* object = Add<HAllocate>(
-      object_size_constant, type, pretenure_flag, instance_type, current_site);
+      object_size_constant, type, pretenure_flag, instance_type, top_site);
 
   // If allocation folding reaches Page::kMaxRegularHeapObjectSize the
   // elements array may not get folded into the object. Hence, we set the
@@ -11349,9 +11353,8 @@ HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
     HValue* object_elements_size = Add<HConstant>(elements_size);
     InstanceType instance_type = boilerplate_object->HasFastDoubleElements()
         ? FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE;
-    object_elements =
-        Add<HAllocate>(object_elements_size, HType::HeapObject(),
-                       pretenure_flag, instance_type, current_site);
+    object_elements = Add<HAllocate>(object_elements_size, HType::HeapObject(),
+                                     pretenure_flag, instance_type, top_site);
     BuildEmitElements(boilerplate_object, elements, object_elements,
                       site_context);
     Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
@@ -11452,10 +11455,6 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
       if (representation.IsDouble()) {
         // Allocate a HeapNumber box and store the value into it.
         HValue* heap_number_constant = Add<HConstant>(HeapNumber::kSize);
-        // This heap number alloc does not have a corresponding
-        // AllocationSite. That is okay because
-        // 1) it's a child object of another object with a valid allocation site
-        // 2) we can just use the mode of the parent object for pretenuring
         HInstruction* double_box =
             Add<HAllocate>(heap_number_constant, HType::HeapObject(),
                 pretenure_flag, MUTABLE_HEAP_NUMBER_TYPE);
index 82a27f4..f0dcaab 100644 (file)
@@ -4765,20 +4765,32 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
     }
   }
 
-  int inobject_props = object->map()->inobject_properties();
+  Handle<Map> old_map(object->map(), isolate);
+
+  int inobject_props = old_map->inobject_properties();
 
   // Allocate new map.
-  Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
+  Handle<Map> new_map = Map::CopyDropDescriptors(old_map);
   new_map->set_dictionary_map(false);
 
-  if (object->map()->is_prototype_map()) {
+  if (old_map->is_prototype_map() && FLAG_track_prototype_users) {
     DCHECK(new_map->is_prototype_map());
-    new_map->set_prototype_info(object->map()->prototype_info());
-    object->map()->set_prototype_info(Smi::FromInt(0));
+
+    Object* maybe_old_prototype = old_map->prototype();
+    if (maybe_old_prototype->IsJSObject()) {
+      Handle<JSObject> old_prototype(JSObject::cast(maybe_old_prototype));
+      bool was_registered =
+          JSObject::UnregisterPrototypeUser(old_prototype, old_map);
+      if (was_registered) {
+        JSObject::LazyRegisterPrototypeUser(new_map, isolate);
+      }
+    }
+    new_map->set_prototype_info(old_map->prototype_info());
+    old_map->set_prototype_info(Smi::FromInt(0));
     if (FLAG_trace_prototype_users) {
       PrintF("Moving prototype_info %p from map %p to map %p.\n",
              reinterpret_cast<void*>(new_map->prototype_info()),
-             reinterpret_cast<void*>(object->map()),
+             reinterpret_cast<void*>(*old_map),
              reinterpret_cast<void*>(*new_map));
     }
   }
@@ -4786,8 +4798,8 @@ void JSObject::MigrateSlowToFast(Handle<JSObject> object,
 #if TRACE_MAPS
   if (FLAG_trace_maps) {
     PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
-           reinterpret_cast<void*>(object->map()),
-           reinterpret_cast<void*>(*new_map), reason);
+           reinterpret_cast<void*>(*old_map), reinterpret_cast<void*>(*new_map),
+           reason);
   }
 #endif
 
index 35e27c3..145d9bc 100644 (file)
@@ -15010,6 +15010,9 @@ TEST(TestIdleNotification) {
         (v8::base::TimeTicks::HighResolutionNow().ToInternalValue() /
          static_cast<double>(v8::base::Time::kMicrosecondsPerSecond)) +
         IdlePauseInSeconds);
+    if (CcTest::heap()->mark_compact_collector()->sweeping_in_progress()) {
+      CcTest::heap()->mark_compact_collector()->EnsureSweepingCompleted();
+    }
   }
   intptr_t final_size = CcTest::heap()->SizeOfObjects();
   CHECK(finished);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-513602.js b/deps/v8/test/mjsunit/regress/regress-crbug-513602.js
new file mode 100644 (file)
index 0000000..ae0441c
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Parent() {}
+
+function Child() {}
+Child.prototype = new Parent();
+var child = new Child();
+
+function crash() {
+  return child.__proto__;
+}
+
+crash();
+crash();
+
+// Trigger a fast->slow->fast dance of Parent.prototype's map...
+Parent.prototype.__defineSetter__("foo", function() { print("A"); });
+Parent.prototype.__defineSetter__("foo", function() { print("B"); });
+// ...and collect more type feedback.
+crash();
+
+// Now modify the prototype chain. The right cell fails to get invalidated.
+delete Object.prototype.__proto__;
+crash();