Revision: 22611
Author:   [email protected]
Date:     Fri Jul 25 00:05:16 2014 UTC
Log:      Version 3.28.38 (based on bleeding_edge revision r22610)

Fix issue with setters and their holders in accessors.cc (Chromium issue 3462).

Introduce more debug events for promises (issue 3093).

Move gc notifications from V8 to Isolate and make idle hint mandatory (Chromium issue 397026).

The accessors should get the value from the holder and not from this (issue 3461).

Performance and stability improvements on all platforms.
http://code.google.com/p/v8/source/detail?r=22611

Added:
 /trunk/src/gc-tracer.cc
 /trunk/src/gc-tracer.h
 /trunk/test/cctest/test-gc-tracer.cc
 /trunk/test/mjsunit/regress/regress-3462.js
 /trunk/test/mjsunit/regress/regress-mask-array-length.js
Modified:
 /trunk/BUILD.gn
 /trunk/ChangeLog
 /trunk/include/v8.h
 /trunk/src/accessors.cc
 /trunk/src/api.cc
 /trunk/src/arm/full-codegen-arm.cc
 /trunk/src/arm64/full-codegen-arm64.cc
 /trunk/src/ast-value-factory.h
 /trunk/src/ast.h
 /trunk/src/code-stubs-hydrogen.cc
 /trunk/src/code-stubs.cc
 /trunk/src/compiler.h
 /trunk/src/counters.h
 /trunk/src/d8.cc
 /trunk/src/debug-debugger.js
 /trunk/src/elements.cc
 /trunk/src/flag-definitions.h
 /trunk/src/heap.cc
 /trunk/src/heap.h
 /trunk/src/ia32/full-codegen-ia32.cc
 /trunk/src/incremental-marking.cc
 /trunk/src/incremental-marking.h
 /trunk/src/lookup.cc
 /trunk/src/lookup.h
 /trunk/src/mips/full-codegen-mips.cc
 /trunk/src/mips64/full-codegen-mips64.cc
 /trunk/src/objects-inl.h
 /trunk/src/objects.cc
 /trunk/src/objects.h
 /trunk/src/parser.cc
 /trunk/src/promise.js
 /trunk/src/serialize.cc
 /trunk/src/store-buffer.cc
 /trunk/src/stub-cache.cc
 /trunk/src/version.cc
 /trunk/src/x64/full-codegen-x64.cc
 /trunk/src/x87/full-codegen-x87.cc
 /trunk/src/x87/lithium-codegen-x87.cc
 /trunk/src/x87/macro-assembler-x87.cc
 /trunk/src/x87/stub-cache-x87.cc
 /trunk/test/cctest/cctest.gyp
 /trunk/test/cctest/cctest.status
 /trunk/test/cctest/test-api.cc
 /trunk/test/cctest/test-heap.cc
 /trunk/test/cctest/test-object-observe.cc
 /trunk/test/cctest/test-serialize.cc
 /trunk/test/mjsunit/es6/debug-promises-new-event.js
 /trunk/test/mjsunit/es7/object-observe.js
 /trunk/test/mjsunit/harmony/iteration-semantics.js
 /trunk/test/mjsunit/mjsunit.status
 /trunk/tools/generate-runtime-tests.py
 /trunk/tools/gyp/v8.gyp
 /trunk/tools/push-to-trunk/auto_tag.py
 /trunk/tools/push-to-trunk/common_includes.py
 /trunk/tools/push-to-trunk/test_scripts.py
 /trunk/tools/whitespace.txt

=======================================
--- /dev/null
+++ /trunk/src/gc-tracer.cc     Fri Jul 25 00:05:16 2014 UTC
@@ -0,0 +1,317 @@
+// Copyright 2014 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.
+
+#include "src/v8.h"
+
+#include "src/gc-tracer.h"
+
+namespace v8 {
+namespace internal {
+
+static intptr_t CountTotalHolesSize(Heap* heap) {
+  intptr_t holes_size = 0;
+  OldSpaces spaces(heap);
+ for (OldSpace* space = spaces.next(); space != NULL; space = spaces.next()) {
+    holes_size += space->Waste() + space->Available();
+  }
+  return holes_size;
+}
+
+
+GCTracer::Event::Event(Type type, const char* gc_reason,
+                       const char* collector_reason)
+    : type(type),
+      gc_reason(gc_reason),
+      collector_reason(collector_reason),
+      start_time(0.0),
+      end_time(0.0),
+      start_object_size(0),
+      end_object_size(0),
+      start_memory_size(0),
+      end_memory_size(0),
+      start_holes_size(0),
+      end_holes_size(0),
+      incremental_marking_steps(0),
+      incremental_marking_duration(0.0) {
+  for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
+    scopes[i] = 0;
+  }
+}
+
+
+const char* GCTracer::Event::TypeName(bool short_name) const {
+  switch (type) {
+    case SCAVENGER:
+      if (short_name) {
+        return "s";
+      } else {
+        return "Scavenge";
+      }
+    case MARK_COMPACTOR:
+      if (short_name) {
+        return "ms";
+      } else {
+        return "Mark-sweep";
+      }
+    case START:
+      if (short_name) {
+        return "st";
+      } else {
+        return "Start";
+      }
+  }
+  return "Unknown Event Type";
+}
+
+
+GCTracer::GCTracer(Heap* heap)
+    : heap_(heap),
+      incremental_marking_steps_(0),
+      incremental_marking_duration_(0.0),
+      longest_incremental_marking_step_(0.0) {
+  current_ = Event(Event::START, NULL, NULL);
+  current_.end_time = base::OS::TimeCurrentMillis();
+  previous_ = previous_mark_compactor_event_ = current_;
+}
+
+
+void GCTracer::Start(GarbageCollector collector, const char* gc_reason,
+                     const char* collector_reason) {
+  if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
+
+  previous_ = current_;
+  if (current_.type == Event::MARK_COMPACTOR)
+    previous_mark_compactor_event_ = current_;
+
+  if (collector == SCAVENGER) {
+    current_ = Event(Event::SCAVENGER, gc_reason, collector_reason);
+  } else {
+    current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason);
+  }
+
+  current_.start_time = base::OS::TimeCurrentMillis();
+  current_.start_object_size = heap_->SizeOfObjects();
+ current_.start_memory_size = heap_->isolate()->memory_allocator()->Size();
+  current_.start_holes_size = CountTotalHolesSize(heap_);
+
+  current_.incremental_marking_steps = incremental_marking_steps_;
+  current_.incremental_marking_duration = incremental_marking_duration_;
+ current_.longest_incremental_marking_step = longest_incremental_marking_step_;
+
+  for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
+    current_.scopes[i] = 0;
+  }
+}
+
+
+void GCTracer::Stop() {
+  if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
+
+  current_.end_time = base::OS::TimeCurrentMillis();
+  current_.end_object_size = heap_->SizeOfObjects();
+  current_.end_memory_size = heap_->isolate()->memory_allocator()->Size();
+  current_.end_holes_size = CountTotalHolesSize(heap_);
+
+  if (current_.type == Event::SCAVENGER) {
+    scavenger_events_.push_front(current_);
+  } else {
+    mark_compactor_events_.push_front(current_);
+  }
+
+  if (current_.type == Event::MARK_COMPACTOR)
+    longest_incremental_marking_step_ = 0.0;
+
+  double duration = current_.end_time - current_.start_time;
+ double spent_in_mutator = Max(current_.start_time - previous_.end_time, 0.0);
+
+  heap_->UpdateCumulativeGCStatistics(duration, spent_in_mutator,
+                                      current_.scopes[Scope::MC_MARK]);
+
+  if (current_.type == Event::SCAVENGER && FLAG_trace_gc_ignore_scavenger)
+    return;
+
+  if (FLAG_trace_gc) {
+    if (FLAG_trace_gc_nvp)
+      PrintNVP();
+    else
+      Print();
+
+    heap_->PrintShortHeapStatistics();
+  }
+}
+
+
+void GCTracer::AddIncrementalMarkingStep(double duration) {
+  incremental_marking_steps_++;
+  incremental_marking_duration_ += duration;
+  longest_incremental_marking_step_ =
+      Max(longest_incremental_marking_step_, duration);
+}
+
+
+void GCTracer::Print() const {
+  PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
+
+  PrintF("%s %.1f (%.1f) -> %.1f (%.1f) MB, ", current_.TypeName(false),
+         static_cast<double>(current_.start_object_size) / MB,
+         static_cast<double>(current_.start_memory_size) / MB,
+         static_cast<double>(current_.end_object_size) / MB,
+         static_cast<double>(current_.end_memory_size) / MB);
+
+  int external_time = static_cast<int>(current_.scopes[Scope::EXTERNAL]);
+  if (external_time > 0) PrintF("%d / ", external_time);
+
+  double duration = current_.end_time - current_.start_time;
+  PrintF("%.1f ms", duration);
+  if (current_.type == Event::SCAVENGER) {
+    int steps = current_.incremental_marking_steps -
+                previous_.incremental_marking_steps;
+    if (steps > 0) {
+      PrintF(" (+ %.1f ms in %d steps since last GC)",
+             current_.incremental_marking_duration -
+                 previous_.incremental_marking_duration,
+             steps);
+    }
+  } else {
+    int steps = current_.incremental_marking_steps -
+                previous_mark_compactor_event_.incremental_marking_steps;
+    if (steps > 0) {
+      PrintF(
+          " (+ %.1f ms in %d steps since start of marking, "
+          "biggest step %.1f ms)",
+          current_.incremental_marking_duration -
+              previous_mark_compactor_event_.incremental_marking_duration,
+          steps, current_.longest_incremental_marking_step);
+    }
+  }
+
+  if (current_.gc_reason != NULL) {
+    PrintF(" [%s]", current_.gc_reason);
+  }
+
+  if (current_.collector_reason != NULL) {
+    PrintF(" [%s]", current_.collector_reason);
+  }
+
+  PrintF(".\n");
+}
+
+
+void GCTracer::PrintNVP() const {
+  PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
+
+  double duration = current_.end_time - current_.start_time;
+  double spent_in_mutator = current_.start_time - previous_.end_time;
+
+  PrintF("pause=%.1f ", duration);
+  PrintF("mutator=%.1f ", spent_in_mutator);
+  PrintF("gc=%s ", current_.TypeName(true));
+
+  PrintF("external=%.1f ", current_.scopes[Scope::EXTERNAL]);
+  PrintF("mark=%.1f ", current_.scopes[Scope::MC_MARK]);
+  PrintF("sweep=%.2f ", current_.scopes[Scope::MC_SWEEP]);
+  PrintF("sweepns=%.2f ", current_.scopes[Scope::MC_SWEEP_NEWSPACE]);
+  PrintF("sweepos=%.2f ", current_.scopes[Scope::MC_SWEEP_OLDSPACE]);
+  PrintF("sweepcode=%.2f ", current_.scopes[Scope::MC_SWEEP_CODE]);
+  PrintF("sweepcell=%.2f ", current_.scopes[Scope::MC_SWEEP_CELL]);
+  PrintF("sweepmap=%.2f ", current_.scopes[Scope::MC_SWEEP_MAP]);
+  PrintF("evacuate=%.1f ", current_.scopes[Scope::MC_EVACUATE_PAGES]);
+  PrintF("new_new=%.1f ",
+         current_.scopes[Scope::MC_UPDATE_NEW_TO_NEW_POINTERS]);
+  PrintF("root_new=%.1f ",
+         current_.scopes[Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS]);
+  PrintF("old_new=%.1f ",
+         current_.scopes[Scope::MC_UPDATE_OLD_TO_NEW_POINTERS]);
+  PrintF("compaction_ptrs=%.1f ",
+         current_.scopes[Scope::MC_UPDATE_POINTERS_TO_EVACUATED]);
+  PrintF("intracompaction_ptrs=%.1f ",
+         current_.scopes[Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED]);
+  PrintF("misc_compaction=%.1f ",
+         current_.scopes[Scope::MC_UPDATE_MISC_POINTERS]);
+  PrintF("weakcollection_process=%.1f ",
+         current_.scopes[Scope::MC_WEAKCOLLECTION_PROCESS]);
+  PrintF("weakcollection_clear=%.1f ",
+         current_.scopes[Scope::MC_WEAKCOLLECTION_CLEAR]);
+
+ PrintF("total_size_before=%" V8_PTR_PREFIX "d ", current_.start_object_size); + PrintF("total_size_after=%" V8_PTR_PREFIX "d ", current_.end_object_size); + PrintF("holes_size_before=%" V8_PTR_PREFIX "d ", current_.start_holes_size);
+  PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", current_.end_holes_size);
+
+  intptr_t allocated_since_last_gc =
+      current_.start_object_size - previous_.end_object_size;
+  PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc);
+  PrintF("promoted=%" V8_PTR_PREFIX "d ", heap_->promoted_objects_size_);
+  PrintF("semi_space_copied=%" V8_PTR_PREFIX "d ",
+         heap_->semi_space_copied_object_size_);
+  PrintF("nodes_died_in_new=%d ", heap_->nodes_died_in_new_space_);
+  PrintF("nodes_copied_in_new=%d ", heap_->nodes_copied_in_new_space_);
+  PrintF("nodes_promoted=%d ", heap_->nodes_promoted_);
+  PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_);
+  PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_);
+
+  if (current_.type == Event::SCAVENGER) {
+    PrintF("stepscount=%d ", current_.incremental_marking_steps -
+                                 previous_.incremental_marking_steps);
+    PrintF("stepstook=%.1f ", current_.incremental_marking_duration -
+                                  previous_.incremental_marking_duration);
+  } else {
+    PrintF("stepscount=%d ",
+           current_.incremental_marking_steps -
+               previous_mark_compactor_event_.incremental_marking_steps);
+    PrintF("stepstook=%.1f ",
+           current_.incremental_marking_duration -
+ previous_mark_compactor_event_.incremental_marking_duration);
+    PrintF("longeststep=%.1f ", current_.longest_incremental_marking_step);
+  }
+
+  PrintF("\n");
+}
+
+
+double GCTracer::MeanDuration(const EventBuffer& events) const {
+  if (events.empty()) return 0.0;
+
+  double mean = 0.0;
+  EventBuffer::const_iterator iter = events.begin();
+  while (iter != events.end()) {
+    mean += iter->end_time - iter->start_time;
+    ++iter;
+  }
+
+  return mean / events.size();
+}
+
+
+double GCTracer::MaxDuration(const EventBuffer& events) const {
+  if (events.empty()) return 0.0;
+
+  double maximum = 0.0f;
+  EventBuffer::const_iterator iter = events.begin();
+  while (iter != events.end()) {
+    maximum = Max(iter->end_time - iter->start_time, maximum);
+    ++iter;
+  }
+
+  return maximum;
+}
+
+
+double GCTracer::MeanIncrementalMarkingDuration() const {
+  if (mark_compactor_events_.empty()) return 0.0;
+
+  EventBuffer::const_iterator last_mc = mark_compactor_events_.begin();
+  return last_mc->incremental_marking_duration /
+         last_mc->incremental_marking_steps;
+}
+
+
+double GCTracer::MaxIncrementalMarkingDuration() const {
+  if (mark_compactor_events_.empty()) return 0.0;
+
+  EventBuffer::const_iterator last_mc = mark_compactor_events_.begin();
+  return last_mc->longest_incremental_marking_step;
+}
+}
+}  // namespace v8::internal
=======================================
--- /dev/null
+++ /trunk/src/gc-tracer.h      Fri Jul 25 00:05:16 2014 UTC
@@ -0,0 +1,283 @@
+// Copyright 2014 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.
+
+#ifndef V8_GC_TRACER_H_
+#define V8_GC_TRACER_H_
+
+namespace v8 {
+namespace internal {
+
+// A simple ring buffer class with maximum size known at compile time.
+// The class only implements the functionality required in GCTracer.
+template <typename T, size_t MAX_SIZE>
+class RingBuffer {
+ public:
+  class const_iterator {
+   public:
+    const_iterator() : index_(0), elements_(NULL) {}
+
+    const_iterator(size_t index, const T* elements)
+        : index_(index), elements_(elements) {}
+
+    bool operator==(const const_iterator& rhs) const {
+      return elements_ == rhs.elements_ && index_ == rhs.index_;
+    }
+
+    bool operator!=(const const_iterator& rhs) const {
+      return elements_ != rhs.elements_ || index_ != rhs.index_;
+    }
+
+    operator const T*() const { return elements_ + index_; }
+
+    const T* operator->() const { return elements_ + index_; }
+
+    const T& operator*() const { return elements_[index_]; }
+
+    const_iterator& operator++() {
+      index_ = (index_ + 1) % (MAX_SIZE + 1);
+      return *this;
+    }
+
+    const_iterator& operator--() {
+      index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1);
+      return *this;
+    }
+
+   private:
+    size_t index_;
+    const T* elements_;
+  };
+
+  RingBuffer() : begin_(0), end_(0) {}
+
+  bool empty() const { return begin_ == end_; }
+  size_t size() const {
+    return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1);
+  }
+ const_iterator begin() const { return const_iterator(begin_, elements_); }
+  const_iterator end() const { return const_iterator(end_, elements_); }
+  const_iterator back() const { return --end(); }
+  void push_back(const T& element) {
+    elements_[end_] = element;
+    end_ = (end_ + 1) % (MAX_SIZE + 1);
+    if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1);
+  }
+  void push_front(const T& element) {
+    begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1);
+    if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1);
+    elements_[begin_] = element;
+  }
+
+ private:
+  T elements_[MAX_SIZE + 1];
+  size_t begin_;
+  size_t end_;
+
+  DISALLOW_COPY_AND_ASSIGN(RingBuffer);
+};
+
+
+// GCTracer collects and prints ONE line after each garbage collector
+// invocation IFF --trace_gc is used.
+// TODO(ernstm): Unit tests.
+class GCTracer BASE_EMBEDDED {
+ public:
+  class Scope BASE_EMBEDDED {
+   public:
+    enum ScopeId {
+      EXTERNAL,
+      MC_MARK,
+      MC_SWEEP,
+      MC_SWEEP_NEWSPACE,
+      MC_SWEEP_OLDSPACE,
+      MC_SWEEP_CODE,
+      MC_SWEEP_CELL,
+      MC_SWEEP_MAP,
+      MC_EVACUATE_PAGES,
+      MC_UPDATE_NEW_TO_NEW_POINTERS,
+      MC_UPDATE_ROOT_TO_NEW_POINTERS,
+      MC_UPDATE_OLD_TO_NEW_POINTERS,
+      MC_UPDATE_POINTERS_TO_EVACUATED,
+      MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
+      MC_UPDATE_MISC_POINTERS,
+      MC_WEAKCOLLECTION_PROCESS,
+      MC_WEAKCOLLECTION_CLEAR,
+      MC_FLUSH_CODE,
+      NUMBER_OF_SCOPES
+    };
+
+ Scope(GCTracer* tracer, ScopeId scope) : tracer_(tracer), scope_(scope) {
+      start_time_ = base::OS::TimeCurrentMillis();
+    }
+
+    ~Scope() {
+      ASSERT(scope_ < NUMBER_OF_SCOPES);  // scope_ is unsigned.
+      tracer_->current_.scopes[scope_] +=
+          base::OS::TimeCurrentMillis() - start_time_;
+    }
+
+   private:
+    GCTracer* tracer_;
+    ScopeId scope_;
+    double start_time_;
+
+    DISALLOW_COPY_AND_ASSIGN(Scope);
+  };
+
+
+  class Event {
+   public:
+    enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 };
+
+    // Default constructor leaves the event uninitialized.
+    Event() {}
+
+    Event(Type type, const char* gc_reason, const char* collector_reason);
+
+    // Returns a string describing the event type.
+    const char* TypeName(bool short_name) const;
+
+    // Type of event
+    Type type;
+
+    const char* gc_reason;
+    const char* collector_reason;
+
+    // Timestamp set in the constructor.
+    double start_time;
+
+    // Timestamp set in the destructor.
+    double end_time;
+
+    // Size of objects in heap set in constructor.
+    intptr_t start_object_size;
+
+    // Size of objects in heap set in destructor.
+    intptr_t end_object_size;
+
+    // Size of memory allocated from OS set in constructor.
+    intptr_t start_memory_size;
+
+    // Size of memory allocated from OS set in destructor.
+    intptr_t end_memory_size;
+
+ // Total amount of space either wasted or contained in one of free lists
+    // before the current GC.
+    intptr_t start_holes_size;
+
+ // Total amount of space either wasted or contained in one of free lists
+    // after the current GC.
+    intptr_t end_holes_size;
+
+    // Number of incremental marking steps since creation of tracer.
+    // (value at start of event)
+    int incremental_marking_steps;
+
+    // Cumulative duration of incremental marking steps since creation of
+    // tracer. (value at start of event)
+    double incremental_marking_duration;
+
+    // Longest incremental marking step since start of marking.
+    // (value at start of event)
+    double longest_incremental_marking_step;
+
+    // Amounts of time spent in different scopes during GC.
+    double scopes[Scope::NUMBER_OF_SCOPES];
+  };
+
+  static const int kRingBufferMaxSize = 10;
+
+  typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer;
+
+  explicit GCTracer(Heap* heap);
+
+  // Start collecting data.
+  void Start(GarbageCollector collector, const char* gc_reason,
+             const char* collector_reason);
+
+  // Stop collecting data and print results.
+  void Stop();
+
+  // Log an incremental marking step.
+  void AddIncrementalMarkingStep(double duration);
+
+ // Compute the mean duration of the last scavenger events. Returns 0 if no
+  // events have been recorded.
+  double MeanScavengerDuration() const {
+    return MeanDuration(scavenger_events_);
+  }
+
+  // Compute the max duration of the last scavenger events. Returns 0 if no
+  // events have been recorded.
+ double MaxScavengerDuration() const { return MaxDuration(scavenger_events_); }
+
+ // Compute the mean duration of the last mark compactor events. Returns 0 if
+  // no events have been recorded.
+  double MeanMarkCompactorDuration() const {
+    return MeanDuration(mark_compactor_events_);
+  }
+
+ // Compute the max duration of the last mark compactor events. Return 0 if no
+  // events have been recorded.
+  double MaxMarkCompactorDuration() const {
+    return MaxDuration(mark_compactor_events_);
+  }
+
+  // Compute the mean step duration of the last incremental marking round.
+  // Returns 0 if no incremental marking round has been completed.
+  double MeanIncrementalMarkingDuration() const;
+
+  // Compute the max step duration of the last incremental marking round.
+  // Returns 0 if no incremental marking round has been completed.
+  double MaxIncrementalMarkingDuration() const;
+
+ private:
+  // Print one detailed trace line in name=value format.
+  // TODO(ernstm): Move to Heap.
+  void PrintNVP() const;
+
+  // Print one trace line.
+  // TODO(ernstm): Move to Heap.
+  void Print() const;
+
+  // Compute the mean duration of the events in the given ring buffer.
+  double MeanDuration(const EventBuffer& events) const;
+
+  // Compute the max duration of the events in the given ring buffer.
+  double MaxDuration(const EventBuffer& events) const;
+
+  // Pointer to the heap that owns this tracer.
+  Heap* heap_;
+
+ // Current tracer event. Populated during Start/Stop cycle. Valid after Stop()
+  // has returned.
+  Event current_;
+
+  // Previous tracer event.
+  Event previous_;
+
+  // Previous MARK_COMPACTOR event.
+  Event previous_mark_compactor_event_;
+
+  // RingBuffers for SCAVENGER events.
+  EventBuffer scavenger_events_;
+
+  // RingBuffers for MARK_COMPACTOR events.
+  EventBuffer mark_compactor_events_;
+
+ // Cumulative number of incremental marking steps since creation of tracer.
+  int incremental_marking_steps_;
+
+ // Cumulative duration of incremental marking steps since creation of tracer.
+  double incremental_marking_duration_;
+
+  // Longest incremental marking step since start of marking.
+  double longest_incremental_marking_step_;
+
+  DISALLOW_COPY_AND_ASSIGN(GCTracer);
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_GC_TRACER_H_
=======================================
--- /dev/null
+++ /trunk/test/cctest/test-gc-tracer.cc        Fri Jul 25 00:05:16 2014 UTC
@@ -0,0 +1,125 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <stdlib.h>
+#include <utility>
+
+#include "src/v8.h"
+
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+TEST(RingBufferPartialFill) {
+  const int max_size = 6;
+  typedef RingBuffer<int, max_size>::const_iterator Iter;
+  RingBuffer<int, max_size> ring_buffer;
+  CHECK(ring_buffer.empty());
+  CHECK_EQ(static_cast<int>(ring_buffer.size()), 0);
+  CHECK(ring_buffer.begin() == ring_buffer.end());
+
+  // Fill ring_buffer partially: [0, 1, 2]
+  for (int i = 0; i < max_size / 2; i++) ring_buffer.push_back(i);
+
+  CHECK(!ring_buffer.empty());
+  CHECK(static_cast<int>(ring_buffer.size()) == max_size / 2);
+  CHECK(ring_buffer.begin() != ring_buffer.end());
+
+  // Test forward itartion
+  int i = 0;
+ for (Iter iter = ring_buffer.begin(); iter != ring_buffer.end(); ++iter) {
+    CHECK(*iter == i);
+    ++i;
+  }
+  CHECK_EQ(i, 3);  // one past last element.
+
+  // Test backward iteration
+  i = 2;
+  Iter iter = ring_buffer.back();
+  while (true) {
+    CHECK(*iter == i);
+    if (iter == ring_buffer.begin()) break;
+    --iter;
+    --i;
+  }
+  CHECK_EQ(i, 0);
+}
+
+
+TEST(RingBufferWrapAround) {
+  const int max_size = 6;
+  typedef RingBuffer<int, max_size>::const_iterator Iter;
+  RingBuffer<int, max_size> ring_buffer;
+
+  // Fill ring_buffer (wrap around): [9, 10, 11, 12, 13, 14]
+  for (int i = 0; i < 2 * max_size + 3; i++) ring_buffer.push_back(i);
+
+  CHECK(!ring_buffer.empty());
+  CHECK(static_cast<int>(ring_buffer.size()) == max_size);
+  CHECK(ring_buffer.begin() != ring_buffer.end());
+
+  // Test forward iteration
+  int i = 9;
+ for (Iter iter = ring_buffer.begin(); iter != ring_buffer.end(); ++iter) {
+    CHECK(*iter == i);
+    ++i;
+  }
+  CHECK_EQ(i, 15);  // one past last element.
+
+  // Test backward iteration
+  i = 14;
+  Iter iter = ring_buffer.back();
+  while (true) {
+    CHECK(*iter == i);
+    if (iter == ring_buffer.begin()) break;
+    --iter;
+    --i;
+  }
+  CHECK_EQ(i, 9);
+}
+
+
+TEST(RingBufferPushFront) {
+  const int max_size = 6;
+  typedef RingBuffer<int, max_size>::const_iterator Iter;
+  RingBuffer<int, max_size> ring_buffer;
+
+  // Fill ring_buffer (wrap around): [14, 13, 12, 11, 10, 9]
+  for (int i = 0; i < 2 * max_size + 3; i++) ring_buffer.push_front(i);
+
+  CHECK(!ring_buffer.empty());
+  CHECK(static_cast<int>(ring_buffer.size()) == max_size);
+  CHECK(ring_buffer.begin() != ring_buffer.end());
+
+  // Test forward iteration
+  int i = 14;
+ for (Iter iter = ring_buffer.begin(); iter != ring_buffer.end(); ++iter) {
+    CHECK(*iter == i);
+    --i;
+  }
+  CHECK_EQ(i, 8);  // one past last element.
+}
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-3462.js Fri Jul 25 00:05:16 2014 UTC
@@ -0,0 +1,48 @@
+// Copyright 2014 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 TestFunctionPrototypeSetter() {
+  var f = function() {};
+  var o = {__proto__: f};
+  o.prototype = 42;
+  assertEquals(42, o.prototype);
+  assertTrue(o.hasOwnProperty('prototype'));
+}
+TestFunctionPrototypeSetter();
+
+
+function TestFunctionPrototypeSetterOnValue() {
+  var f = function() {};
+  var fp = f.prototype;
+  Number.prototype.__proto__ = f;
+  var n = 42;
+  var o = {};
+  n.prototype = o;
+  assertEquals(fp, n.prototype);
+  assertEquals(fp, f.prototype);
+  assertFalse(Number.prototype.hasOwnProperty('prototype'));
+}
+TestFunctionPrototypeSetterOnValue();
+
+
+function TestArrayLengthSetter() {
+  var a = [1];
+  var o = {__proto__: a};
+  o.length = 2;
+  assertEquals(2, o.length);
+  assertEquals(1, a.length);
+  assertTrue(o.hasOwnProperty('length'));
+}
+TestArrayLengthSetter();
+
+
+function TestArrayLengthSetterOnValue() {
+  Number.prototype.__proto__ = [1];
+  var n = 42;
+  n.length = 2;
+  assertEquals(1, n.length);
+  assertFalse(Number.prototype.hasOwnProperty('length'));
+}
+TestArrayLengthSetterOnValue();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-mask-array-length.js Fri Jul 25 00:05:16 2014 UTC
@@ -0,0 +1,10 @@
+// Copyright 2014 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.
+
+var a = [];
+var o = {
+  __proto__: a
+};
+Object.preventExtensions(o);
+o.length = 'abc';
=======================================
--- /trunk/BUILD.gn     Fri Jul 18 00:04:27 2014 UTC
+++ /trunk/BUILD.gn     Fri Jul 25 00:05:16 2014 UTC
@@ -543,6 +543,8 @@
     "src/full-codegen.h",
     "src/func-name-inferrer.cc",
     "src/func-name-inferrer.h",
+    "src/gc-tracer.cc",
+    "src/gc-tracer.h",
     "src/gdb-jit.cc",
     "src/gdb-jit.h",
     "src/global-handles.cc",
=======================================
--- /trunk/ChangeLog    Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/ChangeLog    Fri Jul 25 00:05:16 2014 UTC
@@ -1,3 +1,19 @@
+2014-07-25: Version 3.28.38
+
+ Fix issue with setters and their holders in accessors.cc (Chromium issue
+        3462).
+
+        Introduce more debug events for promises (issue 3093).
+
+ Move gc notifications from V8 to Isolate and make idle hint mandatory
+        (Chromium issue 397026).
+
+ The accessors should get the value from the holder and not from this
+        (issue 3461).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-07-24: Version 3.28.35

         Rebaseline/update the intl tests with ICU 52 (issue 3454).
=======================================
--- /trunk/include/v8.h Thu Jul 17 00:05:04 2014 UTC
+++ /trunk/include/v8.h Fri Jul 25 00:05:16 2014 UTC
@@ -4459,6 +4459,34 @@
   void SetCreateHistogramFunction(CreateHistogramCallback);
   void SetAddHistogramSampleFunction(AddHistogramSampleCallback);

+  /**
+   * Optional notification that the embedder is idle.
+   * V8 uses the notification to reduce memory footprint.
+   * This call can be used repeatedly if the embedder remains idle.
+   * Returns true if the embedder should stop calling IdleNotification
+   * until real work has been done.  This indicates that V8 has done
+   * as much cleanup as it will be able to do.
+   *
+   * The idle_time_in_ms argument specifies the time V8 has to do reduce
+ * the memory footprint. There is no guarantee that the actual work will be
+   * done within the time limit.
+   */
+  bool IdleNotification(int idle_time_in_ms);
+
+  /**
+   * Optional notification that the system is running low on memory.
+   * V8 uses these notifications to attempt to free memory.
+   */
+  void LowMemoryNotification();
+
+  /**
+   * Optional notification that a context has been disposed. V8 uses
+   * these notifications to guide the GC heuristic. Returns the number
+   * of context disposals - including this one - since the last time
+   * V8 had a chance to clean up.
+   */
+  int ContextDisposedNotification();
+
  private:
   template<class K, class V, class Traits> friend class PersistentValueMap;

@@ -4969,12 +4997,16 @@
* The hint argument specifies the amount of work to be done in the function * on scale from 1 to 1000. There is no guarantee that the actual work will
    * match the hint.
+   *
+   * Deprecated, please use Isolate::IdleNotification.
    */
   static bool IdleNotification(int hint = 1000);

   /**
    * Optional notification that the system is running low on memory.
    * V8 uses these notifications to attempt to free memory.
+   *
+   * Deprecated, please use Isolate::LowMemoryNotification.
    */
   static void LowMemoryNotification();

@@ -4983,6 +5015,8 @@
    * these notifications to guide the GC heuristic. Returns the number
    * of context disposals - including this one - since the last time
    * V8 had a chance to clean up.
+   *
+   * Deprecated, please use Isolate::ContextDisposedNotification.
    */
   static int ContextDisposedNotification();

=======================================
--- /trunk/src/accessors.cc     Fri Jul 18 00:04:27 2014 UTC
+++ /trunk/src/accessors.cc     Fri Jul 25 00:05:16 2014 UTC
@@ -19,16 +19,6 @@

 namespace v8 {
 namespace internal {
-
-
-// We have a slight impedance mismatch between the external API and the way we
-// use callbacks internally: Externally, callbacks can only be used with
-// v8::Object, but internally we even have callbacks on entities which are
-// higher in the hierarchy, so we can only return i::Object here, not
-// i::JSObject.
-Handle<Object> GetThisFrom(const v8::PropertyCallbackInfo<v8::Value>& info) {
-  return Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
-}


 Handle<AccessorInfo> Accessors::MakeAccessor(
@@ -144,6 +134,25 @@
 bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type,
                                                   Handle<String> name,
                                                   int* object_offset);
+
+
+bool SetPropertyOnInstanceIfInherited(
+    Isolate* isolate, const v8::PropertyCallbackInfo<void>& info,
+    v8::Local<v8::String> name, Handle<Object> value) {
+  Handle<Object> holder = Utils::OpenHandle(*info.Holder());
+  Handle<Object> receiver = Utils::OpenHandle(*info.This());
+  if (*holder == *receiver) return false;
+  if (receiver->IsJSObject()) {
+    Handle<JSObject> object = Handle<JSObject>::cast(receiver);
+    // This behaves sloppy since we lost the actual strict-mode.
+ // TODO(verwaest): Fix by making ExecutableAccessorInfo behave like data
+    // properties.
+    if (!object->map()->is_extensible()) return true;
+ JSObject::SetOwnPropertyIgnoreAttributes(object, Utils::OpenHandle(*name),
+                                             value, NONE).Check();
+  }
+  return true;
+}


 //
@@ -172,15 +181,8 @@
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
   HandleScope scope(isolate);
-  Object* object = *GetThisFrom(info);
-  // Traverse the prototype chain until we reach an array.
-  JSArray* holder = FindInstanceOf<JSArray>(isolate, object);
-  Object* result;
-  if (holder != NULL) {
-    result = holder->length();
-  } else {
-    result = Smi::FromInt(0);
-  }
+  JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
+  Object* result = holder->length();
info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
 }

@@ -191,16 +193,9 @@
     const v8::PropertyCallbackInfo<void>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<JSObject> object = Handle<JSObject>::cast(
-      Utils::OpenHandle(*info.This()));
+  Handle<JSObject> object = Utils::OpenHandle(*info.This());
   Handle<Object> value = Utils::OpenHandle(*val);
-  // This means one of the object's prototypes is a JSArray and the
-  // object does not have a 'length' property.  Calling SetProperty
-  // causes an infinite loop.
-  if (!object->IsJSArray()) {
- MaybeHandle<Object> maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
-        object, isolate->factory()->length_string(), value, NONE);
-    maybe_result.Check();
+  if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
     return;
   }

@@ -254,16 +249,19 @@
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   DisallowHeapAllocation no_allocation;
   HandleScope scope(isolate);
-  Object* value = *GetThisFrom(info);
-  Object* result;
-  if (value->IsJSValue()) value = JSValue::cast(value)->value();
-  if (value->IsString()) {
-    result = Smi::FromInt(String::cast(value)->length());
-  } else {
-    // If object is not a string we return 0 to be compatible with WebKit.
-    // Note: Firefox returns the length of ToString(object).
-    result = Smi::FromInt(0);
+
+ // We have a slight impedance mismatch between the external API and the way we
+  // use callbacks internally: Externally, callbacks can only be used with
+ // v8::Object, but internally we have callbacks on entities which are higher
+  // in the hierarchy, in this case for String values.
+
+  Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
+  if (!value->IsString()) {
+ // Not a string value. That means that we either got a String wrapper or
+    // a Value with a String wrapper in its prototype chain.
+    value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
   }
+  Object* result = Smi::FromInt(String::cast(value)->length());
info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
 }

@@ -839,21 +837,7 @@
 //

 static Handle<Object> GetFunctionPrototype(Isolate* isolate,
-                                           Handle<Object> receiver) {
-  Handle<JSFunction> function;
-  {
-    DisallowHeapAllocation no_allocation;
- JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver);
-    if (function_raw == NULL) return isolate->factory()->undefined_value();
-    while (!function_raw->should_have_prototype()) {
-      PrototypeIterator iter(isolate, function_raw);
- function_raw = FindInstanceOf<JSFunction>(isolate, iter.GetCurrent());
-      // There has to be one because we hit the getter.
-      ASSERT(function_raw != NULL);
-    }
-    function = Handle<JSFunction>(function_raw, isolate);
-  }
-
+                                           Handle<JSFunction> function) {
   if (!function->has_prototype()) {
Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
     JSFunction::SetPrototype(function, proto);
@@ -863,25 +847,10 @@


 static Handle<Object> SetFunctionPrototype(Isolate* isolate,
-                                           Handle<JSObject> receiver,
+                                           Handle<JSFunction> function,
                                            Handle<Object> value) {
-  Handle<JSFunction> function;
-  {
-    DisallowHeapAllocation no_allocation;
- JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver);
-    if (function_raw == NULL) return isolate->factory()->undefined_value();
-    function = Handle<JSFunction>(function_raw, isolate);
-  }
-
-  if (!function->should_have_prototype()) {
-    // Since we hit this accessor, object will have no prototype property.
- MaybeHandle<Object> maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
-        receiver, isolate->factory()->prototype_string(), value, NONE);
-    return maybe_result.ToHandleChecked();
-  }
-
   Handle<Object> old_value;
- bool is_observed = *function == *receiver && function->map()->is_observed();
+  bool is_observed = function->map()->is_observed();
   if (is_observed) {
     if (function->has_prototype())
       old_value = handle(function->prototype(), isolate);
@@ -919,8 +888,9 @@
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<Object> object = GetThisFrom(info);
-  Handle<Object> result = GetFunctionPrototype(isolate, object);
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  Handle<Object> result = GetFunctionPrototype(isolate, function);
   info.GetReturnValue().Set(Utils::ToLocal(result));
 }

@@ -931,10 +901,12 @@
     const v8::PropertyCallbackInfo<void>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<JSObject> object =
-      Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
   Handle<Object> value = Utils::OpenHandle(*val);
-
+  if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) {
+    return;
+  }
+  Handle<JSFunction> object =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
   SetFunctionPrototype(isolate, object, value);
 }

@@ -959,29 +931,20 @@
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<Object> object = GetThisFrom(info);
-  MaybeHandle<JSFunction> maybe_function;
-
-  {
-    DisallowHeapAllocation no_allocation;
-    JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
-    if (function != NULL) maybe_function = Handle<JSFunction>(function);
-  }
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));

   int length = 0;
-  Handle<JSFunction> function;
-  if (maybe_function.ToHandle(&function)) {
-    if (function->shared()->is_compiled()) {
+  if (function->shared()->is_compiled()) {
+    length = function->shared()->length();
+  } else {
+    // If the function isn't compiled yet, the length is not computed
+    // correctly yet. Compile it now and return the right length.
+    if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
       length = function->shared()->length();
-    } else {
-      // If the function isn't compiled yet, the length is not computed
-      // correctly yet. Compile it now and return the right length.
-      if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) {
-        length = function->shared()->length();
-      }
-      if (isolate->has_pending_exception()) {
-        isolate->OptionalRescheduleException(false);
-      }
+    }
+    if (isolate->has_pending_exception()) {
+      isolate->OptionalRescheduleException(false);
     }
   }
   Handle<Object> result(Smi::FromInt(length), isolate);
@@ -993,7 +956,8 @@
     v8::Local<v8::String> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
-  // Do nothing.
+  // Function length is non writable, non configurable.
+  UNREACHABLE();
 }


@@ -1017,22 +981,9 @@
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<Object> object = GetThisFrom(info);
-  MaybeHandle<JSFunction> maybe_function;
-
-  {
-    DisallowHeapAllocation no_allocation;
-    JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
-    if (function != NULL) maybe_function = Handle<JSFunction>(function);
-  }
-
-  Handle<JSFunction> function;
-  Handle<Object> result;
-  if (maybe_function.ToHandle(&function)) {
-    result = Handle<Object>(function->shared()->name(), isolate);
-  } else {
-    result = isolate->factory()->undefined_value();
-  }
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  Handle<Object> result(function->shared()->name(), isolate);
   info.GetReturnValue().Set(Utils::ToLocal(result));
 }

@@ -1041,7 +992,8 @@
     v8::Local<v8::String> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
-  // Do nothing.
+  // Function name is non writable, non configurable.
+  UNREACHABLE();
 }


@@ -1166,22 +1118,9 @@
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<Object> object = GetThisFrom(info);
-  MaybeHandle<JSFunction> maybe_function;
-
-  {
-    DisallowHeapAllocation no_allocation;
-    JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
-    if (function != NULL) maybe_function = Handle<JSFunction>(function);
-  }
-
-  Handle<JSFunction> function;
-  Handle<Object> result;
-  if (maybe_function.ToHandle(&function)) {
-    result = GetFunctionArguments(isolate, function);
-  } else {
-    result = isolate->factory()->undefined_value();
-  }
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
+  Handle<Object> result = GetFunctionArguments(isolate, function);
   info.GetReturnValue().Set(Utils::ToLocal(result));
 }

@@ -1190,7 +1129,8 @@
     v8::Local<v8::String> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
-  // Do nothing.
+  // Function arguments is non writable, non configurable.
+  UNREACHABLE();
 }


@@ -1321,26 +1261,16 @@
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
   HandleScope scope(isolate);
-  Handle<Object> object = GetThisFrom(info);
-  MaybeHandle<JSFunction> maybe_function;
-  {
-    DisallowHeapAllocation no_allocation;
-    JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object);
-    if (function != NULL) maybe_function = Handle<JSFunction>(function);
-  }
-  Handle<JSFunction> function;
+  Handle<JSFunction> function =
+      Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
   Handle<Object> result;
-  if (maybe_function.ToHandle(&function)) {
-    MaybeHandle<JSFunction> maybe_caller;
-    maybe_caller = FindCaller(isolate, function);
-    Handle<JSFunction> caller;
-    if (maybe_caller.ToHandle(&caller)) {
-      result = caller;
-    } else {
-      result = isolate->factory()->null_value();
-    }
+  MaybeHandle<JSFunction> maybe_caller;
+  maybe_caller = FindCaller(isolate, function);
+  Handle<JSFunction> caller;
+  if (maybe_caller.ToHandle(&caller)) {
+    result = caller;
   } else {
-    result = isolate->factory()->undefined_value();
+    result = isolate->factory()->null_value();
   }
   info.GetReturnValue().Set(Utils::ToLocal(result));
 }
@@ -1350,7 +1280,8 @@
     v8::Local<v8::String> name,
     v8::Local<v8::Value> val,
     const v8::PropertyCallbackInfo<void>& info) {
-  // Do nothing.
+  // Function caller is non writable, non configurable.
+  UNREACHABLE();
 }


=======================================
--- /trunk/src/api.cc   Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/api.cc   Fri Jul 25 00:05:16 2014 UTC
@@ -5063,7 +5063,11 @@
 void v8::V8::LowMemoryNotification() {
   i::Isolate* isolate = i::Isolate::Current();
   if (isolate == NULL || !isolate->IsInitialized()) return;
-  isolate->heap()->CollectAllAvailableGarbage("low memory notification");
+  {
+    i::HistogramTimerScope idle_notification_scope(
+        isolate->counters()->gc_low_memory_notification());
+    isolate->heap()->CollectAllAvailableGarbage("low memory notification");
+  }
 }


@@ -6710,6 +6714,31 @@
       ->stats_table()
       ->SetAddHistogramSampleFunction(callback);
 }
+
+
+bool v8::Isolate::IdleNotification(int idle_time_in_ms) {
+  // Returning true tells the caller that it need not
+  // continue to call IdleNotification.
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  if (!i::FLAG_use_idle_notification) return true;
+  return isolate->heap()->IdleNotification(idle_time_in_ms);
+}
+
+
+void v8::Isolate::LowMemoryNotification() {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  {
+    i::HistogramTimerScope idle_notification_scope(
+        isolate->counters()->gc_low_memory_notification());
+    isolate->heap()->CollectAllAvailableGarbage("low memory notification");
+  }
+}
+
+
+int v8::Isolate::ContextDisposedNotification() {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  return isolate->heap()->NotifyContextDisposed();
+}


 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
=======================================
--- /trunk/src/arm/full-codegen-arm.cc  Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/arm/full-codegen-arm.cc  Fri Jul 25 00:05:16 2014 UTC
@@ -1276,15 +1276,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ CompareRoot(r0, Heap::kUndefinedValueRootIndex);
-  __ b(eq, loop_statement.break_label());
-  __ CompareRoot(r0, Heap::kNullValueRootIndex);
-  __ b(eq, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /trunk/src/arm64/full-codegen-arm64.cc      Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/arm64/full-codegen-arm64.cc      Fri Jul 25 00:05:16 2014 UTC
@@ -1271,16 +1271,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  Register iterator = x0;
-  __ JumpIfRoot(iterator, Heap::kUndefinedValueRootIndex,
-                loop_statement.break_label());
-  __ JumpIfRoot(iterator, Heap::kNullValueRootIndex,
-                loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /trunk/src/ast-value-factory.h      Tue Jul  1 11:58:10 2014 UTC
+++ /trunk/src/ast-value-factory.h      Fri Jul 25 00:05:16 2014 UTC
@@ -243,7 +243,6 @@
   F(dot_for, ".for") \
   F(dot_generator, ".generator") \
   F(dot_generator_object, ".generator_object") \
-  F(dot_iterable, ".iterable") \
   F(dot_iterator, ".iterator") \
   F(dot_module, ".module") \
   F(dot_result, ".result") \
=======================================
--- /trunk/src/ast.h    Wed Jul 23 00:04:36 2014 UTC
+++ /trunk/src/ast.h    Fri Jul 25 00:05:16 2014 UTC
@@ -961,13 +961,11 @@
   void Initialize(Expression* each,
                   Expression* subject,
                   Statement* body,
-                  Expression* assign_iterable,
                   Expression* assign_iterator,
                   Expression* next_result,
                   Expression* result_done,
                   Expression* assign_each) {
     ForEachStatement::Initialize(each, subject, body);
-    assign_iterable_ = assign_iterable;
     assign_iterator_ = assign_iterator;
     next_result_ = next_result;
     result_done_ = result_done;
@@ -978,12 +976,7 @@
     return subject();
   }

-  // var iterable = subject;
-  Expression* assign_iterable() const {
-    return assign_iterable_;
-  }
-
-  // var iterator = iterable[Symbol.iterator]();
+  // var iterator = subject[Symbol.iterator]();
   Expression* assign_iterator() const {
     return assign_iterator_;
   }
@@ -1018,7 +1011,6 @@
         back_edge_id_(GetNextId(zone)) {
   }

-  Expression* assign_iterable_;
   Expression* assign_iterator_;
   Expression* next_result_;
   Expression* result_done_;
=======================================
--- /trunk/src/code-stubs-hydrogen.cc   Fri Jul 18 00:04:27 2014 UTC
+++ /trunk/src/code-stubs-hydrogen.cc   Fri Jul 25 00:05:16 2014 UTC
@@ -270,6 +270,8 @@
   }
   CodeStubGraphBuilder<Stub> builder(isolate, stub);
   LChunk* chunk = OptimizeGraph(builder.CreateGraph());
+  // TODO(yangguo) remove this once the code serializer handles code stubs.
+  if (FLAG_serialize_toplevel) chunk->info()->PrepareForSerializing();
   Handle<Code> code = chunk->Codegen();
   if (FLAG_profile_hydrogen_code_stub_compilation) {
     OFStream os(stdout);
=======================================
--- /trunk/src/code-stubs.cc    Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/code-stubs.cc    Fri Jul 25 00:05:16 2014 UTC
@@ -149,6 +149,9 @@
   // Generate the new code.
   MacroAssembler masm(isolate(), NULL, 256);

+  // TODO(yangguo) remove this once the code serializer handles code stubs.
+  if (FLAG_serialize_toplevel) masm.enable_serializer();
+
   {
     // Update the static counter each time a new code stub is generated.
     isolate()->counters()->code_stubs()->Increment();
=======================================
--- /trunk/src/compiler.h       Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/compiler.h       Fri Jul 25 00:05:16 2014 UTC
@@ -184,7 +184,6 @@
   }

   void PrepareForSerializing() {
-    ASSERT(!is_lazy());
     flags_ |= PrepareForSerializing::encode(true);
   }

=======================================
--- /trunk/src/counters.h       Mon Jul 21 00:04:41 2014 UTC
+++ /trunk/src/counters.h       Fri Jul 25 00:05:16 2014 UTC
@@ -299,6 +299,7 @@
   HT(gc_context, V8.GCContext) /* GC context cleanup time */ \
   HT(gc_idle_notification, V8.GCIdleNotification)            \
   HT(gc_incremental_marking, V8.GCIncrementalMarking)        \
+  HT(gc_low_memory_notification, V8.GCLowMemoryNotification) \
   /* Parsing timers. */                                      \
   HT(parse, V8.Parse)                                        \
   HT(parse_lazy, V8.ParseLazy)                               \
=======================================
--- /trunk/src/d8.cc    Thu Jul 17 00:05:04 2014 UTC
+++ /trunk/src/d8.cc    Fri Jul 25 00:05:16 2014 UTC
@@ -1251,14 +1251,14 @@
       }
       if (Shell::options.send_idle_notification) {
         const int kLongIdlePauseInMs = 1000;
-        V8::ContextDisposedNotification();
-        V8::IdleNotification(kLongIdlePauseInMs);
+        isolate->ContextDisposedNotification();
+        isolate->IdleNotification(kLongIdlePauseInMs);
       }
       if (Shell::options.invoke_weak_callbacks) {
// By sending a low memory notifications, we will try hard to collect
         // all garbage and will therefore also invoke all weak callbacks of
         // actually unreachable persistent handles.
-        V8::LowMemoryNotification();
+        isolate->LowMemoryNotification();
       }
     }
     done_semaphore_.Signal();
@@ -1440,14 +1440,14 @@
   }
   if (options.send_idle_notification) {
     const int kLongIdlePauseInMs = 1000;
-    V8::ContextDisposedNotification();
-    V8::IdleNotification(kLongIdlePauseInMs);
+    isolate->ContextDisposedNotification();
+    isolate->IdleNotification(kLongIdlePauseInMs);
   }
   if (options.invoke_weak_callbacks) {
// By sending a low memory notifications, we will try hard to collect all // garbage and will therefore also invoke all weak callbacks of actually
     // unreachable persistent handles.
-    V8::LowMemoryNotification();
+    isolate->LowMemoryNotification();
   }

 #ifndef V8_SHARED
=======================================
--- /trunk/src/debug-debugger.js        Mon Jul  7 00:05:07 2014 UTC
+++ /trunk/src/debug-debugger.js        Fri Jul 25 00:05:16 2014 UTC
@@ -1202,9 +1202,15 @@


 function MakePromiseEvent(event_data) {
-  if (event_data.type = "new Promise") {
+  if (event_data.type == "new") {
     return new NewPromiseEvent(event_data);
   }
+  if (event_data.type == "update") {
+    return new UpdatePromiseStatusEvent(event_data);
+  }
+  if (event_data.type == "chain") {
+    return new UpdatePromiseParentEvent(event_data);
+  }
 }


@@ -1225,6 +1231,40 @@
 NewPromiseEvent.prototype.resolver = function() {
   return MakeMirror(this.resolver_);
 }
+
+
+function UpdatePromiseStatusEvent(event_data) {
+  this.promise_ = event_data.promise;
+  this.status_ = event_data.status;
+  this.value_ = event_data.value;
+}
+
+
+UpdatePromiseStatusEvent.prototype.promise = PromiseGetter;
+
+
+UpdatePromiseStatusEvent.prototype.status = function() {
+  return this.status_;
+}
+
+
+UpdatePromiseStatusEvent.prototype.value = function() {
+  return MakeMirror(this.value_);
+}
+
+
+function UpdatePromiseParentEvent(event_data) {
+  this.promise_ = event_data.promise;
+  this.parentPromise_ = event_data.parentPromise;
+}
+
+
+UpdatePromiseParentEvent.prototype.promise = PromiseGetter;
+
+
+UpdatePromiseParentEvent.prototype.parentPromise = function() {
+  return MakeMirror(this.parentPromise_);
+}


 function MakeAsyncTaskEvent(event_data) {
=======================================
--- /trunk/src/elements.cc      Mon Jun 16 11:20:10 2014 UTC
+++ /trunk/src/elements.cc      Fri Jul 25 00:05:16 2014 UTC
@@ -951,8 +951,8 @@
     uint32_t min = JSObject::NewElementsCapacity(old_capacity);
     uint32_t new_capacity = length > min ? length : min;
     if (!array->ShouldConvertToSlowElements(new_capacity)) {
-      FastElementsAccessorSubclass::
-          SetFastElementsCapacityAndLength(array, new_capacity, length);
+      FastElementsAccessorSubclass::SetFastElementsCapacityAndLength(
+          array, new_capacity, length);
       JSObject::ValidateElements(array);
       return length_object;
     }
=======================================
--- /trunk/src/flag-definitions.h       Tue Jul 22 00:04:43 2014 UTC
+++ /trunk/src/flag-definitions.h       Fri Jul 25 00:05:16 2014 UTC
@@ -171,7 +171,6 @@
 DEFINE_IMPLICATION(harmony, harmony_proxies)
 DEFINE_IMPLICATION(harmony, harmony_collections)
 DEFINE_IMPLICATION(harmony, harmony_generators)
-DEFINE_IMPLICATION(harmony, harmony_iteration)
 DEFINE_IMPLICATION(harmony, harmony_numeric_literals)
 DEFINE_IMPLICATION(harmony, harmony_strings)
 DEFINE_IMPLICATION(harmony, harmony_arrays)
@@ -184,6 +183,7 @@
 DEFINE_IMPLICATION(harmony, es_staging)
 DEFINE_IMPLICATION(es_staging, harmony_symbols)
 DEFINE_IMPLICATION(es_staging, harmony_collections)
+DEFINE_IMPLICATION(es_staging, harmony_iteration)

 // Flags for experimental implementation features.
 DEFINE_BOOL(compiled_keyed_dictionary_loads, true,
=======================================
--- /trunk/src/heap.cc  Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/heap.cc  Fri Jul 25 00:05:16 2014 UTC
@@ -114,8 +114,6 @@
       total_gc_time_ms_(0.0),
       max_alive_after_gc_(0),
       min_in_mutator_(kMaxInt),
-      alive_after_last_gc_(0),
-      last_gc_end_timestamp_(base::OS::TimeCurrentMillis()),
       marking_time_(0.0),
       sweeping_time_(0.0),
       mark_compact_collector_(this),
@@ -842,7 +840,7 @@
   bool next_gc_likely_to_collect_more = false;

   {
-    tracer()->start(collector, gc_reason, collector_reason);
+    tracer()->Start(collector, gc_reason, collector_reason);
     ASSERT(AllowHeapAllocation::IsAllowed());
     DisallowHeapAllocation no_allocation_during_gc;
     GarbageCollectionPrologue();
@@ -856,7 +854,7 @@
     }

     GarbageCollectionEpilogue();
-    tracer()->stop();
+    tracer()->Stop();
   }

   // Start incremental marking for the next cycle. The heap snapshot
@@ -5957,28 +5955,13 @@
 #endif


-static intptr_t CountTotalHolesSize(Heap* heap) {
-  intptr_t holes_size = 0;
-  OldSpaces spaces(heap);
-  for (OldSpace* space = spaces.next();
-       space != NULL;
-       space = spaces.next()) {
-    holes_size += space->Waste() + space->Available();
-  }
-  return holes_size;
-}
-
-
-void Heap::UpdateGCStatistics(double start_time, double end_time,
- double spent_in_mutator, double marking_time) {
-  double duration = end_time - start_time;
-  alive_after_last_gc_ = SizeOfObjects();
-  last_gc_end_timestamp_ = end_time;
-
+void Heap::UpdateCumulativeGCStatistics(double duration,
+                                        double spent_in_mutator,
+                                        double marking_time) {
   if (FLAG_print_cumulative_gc_stat) {
     total_gc_time_ms_ += duration;
     max_gc_pause_ = Max(max_gc_pause_, duration);
-    max_alive_after_gc_ = Max(max_alive_after_gc_, alive_after_last_gc_);
+    max_alive_after_gc_ = Max(max_alive_after_gc_, SizeOfObjects());
     min_in_mutator_ = Min(min_in_mutator_, spent_in_mutator);
   } else if (FLAG_trace_gc_verbose) {
     total_gc_time_ms_ += duration;
@@ -5986,202 +5969,6 @@

   marking_time_ += marking_time;
 }
-
-
-GCTracer::GCTracer(Heap* heap)
-    : start_time_(0.0),
-      end_time_(0.0),
-      start_object_size_(0),
-      end_object_size_(0),
-      start_memory_size_(0),
-      end_memory_size_(0),
-      in_free_list_or_wasted_before_gc_(0),
-      allocated_since_last_gc_(0),
-      spent_in_mutator_(0),
-      steps_count_(0),
-      steps_took_(0.0),
-      longest_step_(0.0),
-      steps_count_since_last_gc_(0),
-      steps_took_since_last_gc_(0.0),
-      heap_(heap),
-      gc_reason_(NULL),
-      collector_reason_(NULL) {
-  for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
-    scopes_[i] = 0;
-  }
-}
-
-
-void GCTracer::start(GarbageCollector collector, const char* gc_reason,
-                     const char* collector_reason) {
-  if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
-
-  collector_ = collector;
-  gc_reason_ = gc_reason;
-  collector_reason_ = collector_reason;
-
-  start_time_ = base::OS::TimeCurrentMillis();
-  start_object_size_ = heap_->SizeOfObjects();
-  start_memory_size_ = heap_->isolate()->memory_allocator()->Size();
-
-  for (int i = 0; i < Scope::NUMBER_OF_SCOPES; i++) {
-    scopes_[i] = 0;
-  }
-
-  in_free_list_or_wasted_before_gc_ = CountTotalHolesSize(heap_);
-
-  allocated_since_last_gc_ =
-      heap_->SizeOfObjects() - heap_->alive_after_last_gc_;
-
- spent_in_mutator_ = Max(start_time_ - heap_->last_gc_end_timestamp_, 0.0);
-
-  steps_count_ = heap_->incremental_marking()->steps_count();
-  steps_took_ = heap_->incremental_marking()->steps_took();
-  longest_step_ = heap_->incremental_marking()->longest_step();
-  steps_count_since_last_gc_ =
-      heap_->incremental_marking()->steps_count_since_last_gc();
-  steps_took_since_last_gc_ =
-      heap_->incremental_marking()->steps_took_since_last_gc();
-}
-
-
-void GCTracer::stop() {
-  if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
-
-  end_time_ = base::OS::TimeCurrentMillis();
-  end_object_size_ = heap_->SizeOfObjects();
-  end_memory_size_ = heap_->isolate()->memory_allocator()->Size();
-
-  heap_->UpdateGCStatistics(start_time_, end_time_, spent_in_mutator_,
-                            scopes_[Scope::MC_MARK]);
-
-  if (collector_ == SCAVENGER && FLAG_trace_gc_ignore_scavenger) return;
-
-  if (FLAG_trace_gc) {
-    if (FLAG_trace_gc_nvp)
-      PrintNVP();
-    else
-      Print();
-
-    heap_->PrintShortHeapStatistics();
-  }
-}
-
-
-void GCTracer::Print() const {
-  PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
-
-  PrintF("%s %.1f (%.1f) -> %.1f (%.1f) MB, ", CollectorString(),
-         static_cast<double>(start_object_size_) / MB,
-         static_cast<double>(start_memory_size_) / MB,
-         static_cast<double>(end_object_size_) / MB,
-         static_cast<double>(end_memory_size_) / MB);
-
-  int external_time = static_cast<int>(scopes_[Scope::EXTERNAL]);
-  if (external_time > 0) PrintF("%d / ", external_time);
-
-  PrintF("%.1f ms", end_time_ - start_time_);
-  if (steps_count_ > 0) {
-    if (collector_ == SCAVENGER) {
-      PrintF(" (+ %.1f ms in %d steps since last GC)",
-             steps_took_since_last_gc_, steps_count_since_last_gc_);
-    } else {
-      PrintF(
-          " (+ %.1f ms in %d steps since start of marking, "
-          "biggest step %.1f ms)",
-          steps_took_, steps_count_, longest_step_);
-    }
-  }
-
-  if (gc_reason_ != NULL) {
-    PrintF(" [%s]", gc_reason_);
-  }
-
-  if (collector_reason_ != NULL) {
-    PrintF(" [%s]", collector_reason_);
-  }
-
-  PrintF(".\n");
-}
-
-
-void GCTracer::PrintNVP() const {
-  PrintPID("%8.0f ms: ", heap_->isolate()->time_millis_since_init());
-
-  PrintF("pause=%.1f ", end_time_ - start_time_);
-  PrintF("mutator=%.1f ", spent_in_mutator_);
-  PrintF("gc=");
-  switch (collector_) {
-    case SCAVENGER:
-      PrintF("s");
-      break;
-    case MARK_COMPACTOR:
-      PrintF("ms");
-      break;
-    default:
-      UNREACHABLE();
-  }
-  PrintF(" ");
-
-  PrintF("external=%.1f ", scopes_[Scope::EXTERNAL]);
-  PrintF("mark=%.1f ", scopes_[Scope::MC_MARK]);
-  PrintF("sweep=%.2f ", scopes_[Scope::MC_SWEEP]);
-  PrintF("sweepns=%.2f ", scopes_[Scope::MC_SWEEP_NEWSPACE]);
-  PrintF("sweepos=%.2f ", scopes_[Scope::MC_SWEEP_OLDSPACE]);
-  PrintF("sweepcode=%.2f ", scopes_[Scope::MC_SWEEP_CODE]);
-  PrintF("sweepcell=%.2f ", scopes_[Scope::MC_SWEEP_CELL]);
-  PrintF("sweepmap=%.2f ", scopes_[Scope::MC_SWEEP_MAP]);
-  PrintF("evacuate=%.1f ", scopes_[Scope::MC_EVACUATE_PAGES]);
-  PrintF("new_new=%.1f ", scopes_[Scope::MC_UPDATE_NEW_TO_NEW_POINTERS]);
-  PrintF("root_new=%.1f ", scopes_[Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS]);
-  PrintF("old_new=%.1f ", scopes_[Scope::MC_UPDATE_OLD_TO_NEW_POINTERS]);
-  PrintF("compaction_ptrs=%.1f ",
-         scopes_[Scope::MC_UPDATE_POINTERS_TO_EVACUATED]);
-  PrintF("intracompaction_ptrs=%.1f ",
-         scopes_[Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED]);
-  PrintF("misc_compaction=%.1f ", scopes_[Scope::MC_UPDATE_MISC_POINTERS]);
-  PrintF("weakcollection_process=%.1f ",
-         scopes_[Scope::MC_WEAKCOLLECTION_PROCESS]);
- PrintF("weakcollection_clear=%.1f ", scopes_[Scope::MC_WEAKCOLLECTION_CLEAR]);
-
-  PrintF("total_size_before=%" V8_PTR_PREFIX "d ", start_object_size_);
-  PrintF("total_size_after=%" V8_PTR_PREFIX "d ", end_object_size_);
-  PrintF("holes_size_before=%" V8_PTR_PREFIX "d ",
-         in_free_list_or_wasted_before_gc_);
- PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize(heap_));
-
-  PrintF("allocated=%" V8_PTR_PREFIX "d ", allocated_since_last_gc_);
-  PrintF("promoted=%" V8_PTR_PREFIX "d ", heap_->promoted_objects_size_);
-  PrintF("semi_space_copied=%" V8_PTR_PREFIX "d ",
-         heap_->semi_space_copied_object_size_);
-  PrintF("nodes_died_in_new=%d ", heap_->nodes_died_in_new_space_);
-  PrintF("nodes_copied_in_new=%d ", heap_->nodes_copied_in_new_space_);
-  PrintF("nodes_promoted=%d ", heap_->nodes_promoted_);
-  PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_);
-  PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_);
-
-  if (collector_ == SCAVENGER) {
-    PrintF("stepscount=%d ", steps_count_since_last_gc_);
-    PrintF("stepstook=%.1f ", steps_took_since_last_gc_);
-  } else {
-    PrintF("stepscount=%d ", steps_count_);
-    PrintF("stepstook=%.1f ", steps_took_);
-    PrintF("longeststep=%.1f ", longest_step_);
-  }
-
-  PrintF("\n");
-}
-
-
-const char* GCTracer::CollectorString() const {
-  switch (collector_) {
-    case SCAVENGER:
-      return "Scavenge";
-    case MARK_COMPACTOR:
-      return "Mark-sweep";
-  }
-  return "Unknown GC";
-}


 int KeyedLookupCache::Hash(Handle<Map> map, Handle<Name> name) {
=======================================
--- /trunk/src/heap.h   Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/heap.h   Fri Jul 25 00:05:16 2014 UTC
@@ -10,6 +10,7 @@
 #include "src/allocation.h"
 #include "src/assert-scope.h"
 #include "src/counters.h"
+#include "src/gc-tracer.h"
 #include "src/globals.h"
 #include "src/incremental-marking.h"
 #include "src/list.h"
@@ -548,125 +549,6 @@
 };


-// GCTracer collects and prints ONE line after each garbage collector
-// invocation IFF --trace_gc is used.
-
-class GCTracer BASE_EMBEDDED {
- public:
-  class Scope BASE_EMBEDDED {
-   public:
-    enum ScopeId {
-      EXTERNAL,
-      MC_MARK,
-      MC_SWEEP,
-      MC_SWEEP_NEWSPACE,
-      MC_SWEEP_OLDSPACE,
-      MC_SWEEP_CODE,
-      MC_SWEEP_CELL,
-      MC_SWEEP_MAP,
-      MC_EVACUATE_PAGES,
-      MC_UPDATE_NEW_TO_NEW_POINTERS,
-      MC_UPDATE_ROOT_TO_NEW_POINTERS,
-      MC_UPDATE_OLD_TO_NEW_POINTERS,
-      MC_UPDATE_POINTERS_TO_EVACUATED,
-      MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
-      MC_UPDATE_MISC_POINTERS,
-      MC_WEAKCOLLECTION_PROCESS,
-      MC_WEAKCOLLECTION_CLEAR,
-      MC_FLUSH_CODE,
-      NUMBER_OF_SCOPES
-    };
-
-    Scope(GCTracer* tracer, ScopeId scope)
-        : tracer_(tracer),
-        scope_(scope) {
-      start_time_ = base::OS::TimeCurrentMillis();
-    }
-
-    ~Scope() {
-      ASSERT(scope_ < NUMBER_OF_SCOPES);  // scope_ is unsigned.
- tracer_->scopes_[scope_] += base::OS::TimeCurrentMillis() - start_time_;
-    }
-
-   private:
-    GCTracer* tracer_;
-    ScopeId scope_;
-    double start_time_;
-
-    DISALLOW_COPY_AND_ASSIGN(Scope);
-  };
-
-  explicit GCTracer(Heap* heap);
-
-  // Start collecting data.
-  void start(GarbageCollector collector, const char* gc_reason,
-             const char* collector_reason);
-
-  // Stop collecting data and print results.
-  void stop();
-
- private:
-  // Returns a string matching the collector.
-  const char* CollectorString() const;
-
-  // Print one detailed trace line in name=value format.
-  void PrintNVP() const;
-
-  // Print one trace line.
-  void Print() const;
-
-  // Timestamp set in the constructor.
-  double start_time_;
-
-  // Timestamp set in the destructor.
-  double end_time_;
-
-  // Size of objects in heap set in constructor.
-  intptr_t start_object_size_;
-
-  // Size of objects in heap set in destructor.
-  intptr_t end_object_size_;
-
-  // Size of memory allocated from OS set in constructor.
-  intptr_t start_memory_size_;
-
-  // Size of memory allocated from OS set in destructor.
-  intptr_t end_memory_size_;
-
-  // Type of collector.
-  GarbageCollector collector_;
-
-  // Amounts of time spent in different scopes during GC.
-  double scopes_[Scope::NUMBER_OF_SCOPES];
-
-  // Total amount of space either wasted or contained in one of free lists
-  // before the current GC.
-  intptr_t in_free_list_or_wasted_before_gc_;
-
- // Difference between space used in the heap at the beginning of the current
-  // collection and the end of the previous collection.
-  intptr_t allocated_since_last_gc_;
-
- // Amount of time spent in mutator that is time elapsed between end of the
-  // previous collection and the beginning of the current one.
-  double spent_in_mutator_;
-
-  // Incremental marking steps counters.
-  int steps_count_;
-  double steps_took_;
-  double longest_step_;
-  int steps_count_since_last_gc_;
-  double steps_took_since_last_gc_;
-
-  Heap* heap_;
-
-  const char* gc_reason_;
-  const char* collector_reason_;
-
-  DISALLOW_COPY_AND_ASSIGN(GCTracer);
-};
-
-
 class Heap {
  public:
// Configure heap size in MB before setup. Return false if the heap has been
@@ -1367,8 +1249,8 @@
   }

   // Update GC statistics that are tracked on the Heap.
-  void UpdateGCStatistics(double start_time, double end_time,
-                          double spent_in_mutator, double marking_time);
+ void UpdateCumulativeGCStatistics(double duration, double spent_in_mutator,
+                                    double marking_time);

   // Returns maximum GC pause.
   double get_max_gc_pause() { return max_gc_pause_; }
@@ -2238,11 +2120,6 @@
   // Minimal interval between two subsequent collections.
   double min_in_mutator_;

-  // Size of objects alive after last GC.
-  intptr_t alive_after_last_gc_;
-
-  double last_gc_end_timestamp_;
-
   // Cumulative GC time spent in marking
   double marking_time_;

=======================================
--- /trunk/src/ia32/full-codegen-ia32.cc        Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/ia32/full-codegen-ia32.cc        Fri Jul 25 00:05:16 2014 UTC
@@ -1207,15 +1207,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ CompareRoot(eax, Heap::kUndefinedValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-  __ CompareRoot(eax, Heap::kNullValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /trunk/src/incremental-marking.cc   Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/incremental-marking.cc   Fri Jul 25 00:05:16 2014 UTC
@@ -22,12 +22,8 @@
       marking_deque_memory_(NULL),
       marking_deque_memory_committed_(false),
       steps_count_(0),
-      steps_took_(0),
-      longest_step_(0.0),
       old_generation_space_available_at_start_of_incremental_(0),
       old_generation_space_used_at_start_of_incremental_(0),
-      steps_count_since_last_gc_(0),
-      steps_took_since_last_gc_(0),
       should_hurry_(false),
       marking_speed_(0),
       allocated_(0),
@@ -658,9 +654,6 @@
     }
   }
   marking_deque_.set_top(new_top);
-
-  steps_took_since_last_gc_ = 0;
-  steps_count_since_last_gc_ = 0;
 }


@@ -895,7 +888,6 @@
   }

   steps_count_++;
-  steps_count_since_last_gc_++;

   bool speed_up = false;

@@ -964,9 +956,7 @@
       FLAG_print_cumulative_gc_stat) {
     double end = base::OS::TimeCurrentMillis();
     double delta = (end - start);
-    longest_step_ = Max(longest_step_, delta);
-    steps_took_ += delta;
-    steps_took_since_last_gc_ += delta;
+    heap_->tracer()->AddIncrementalMarkingStep(delta);
     heap_->AddMarkingTime(delta);
   }
 }
@@ -974,14 +964,10 @@

 void IncrementalMarking::ResetStepCounters() {
   steps_count_ = 0;
-  steps_took_ = 0;
-  longest_step_ = 0.0;
   old_generation_space_available_at_start_of_incremental_ =
       SpaceLeftInOldSpace();
   old_generation_space_used_at_start_of_incremental_ =
       heap_->PromotedTotalSize();
-  steps_count_since_last_gc_ = 0;
-  steps_took_since_last_gc_ = 0;
   bytes_rescanned_ = 0;
   marking_speed_ = kInitialMarkingSpeed;
   bytes_scanned_ = 0;
=======================================
--- /trunk/src/incremental-marking.h    Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/incremental-marking.h    Fri Jul 25 00:05:16 2014 UTC
@@ -135,16 +135,6 @@
   inline void BlackToGreyAndUnshift(HeapObject* obj, MarkBit mark_bit);

   inline void WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit);
-
-  inline int steps_count() { return steps_count_; }
-
-  inline double steps_took() { return steps_took_; }
-
-  inline double longest_step() { return longest_step_; }
-
- inline int steps_count_since_last_gc() { return steps_count_since_last_gc_; }
-
- inline double steps_took_since_last_gc() { return steps_took_since_last_gc_; }

   inline void SetOldSpacePageFlags(MemoryChunk* chunk) {
     SetOldSpacePageFlags(chunk, IsMarking(), IsCompacting());
@@ -226,12 +216,8 @@
   MarkingDeque marking_deque_;

   int steps_count_;
-  double steps_took_;
-  double longest_step_;
   int64_t old_generation_space_available_at_start_of_incremental_;
   int64_t old_generation_space_used_at_start_of_incremental_;
-  int steps_count_since_last_gc_;
-  double steps_took_since_last_gc_;
   int64_t bytes_rescanned_;
   bool should_hurry_;
   int marking_speed_;
=======================================
--- /trunk/src/lookup.cc        Mon Jul 21 00:04:41 2014 UTC
+++ /trunk/src/lookup.cc        Fri Jul 25 00:05:16 2014 UTC
@@ -100,7 +100,7 @@
 bool LookupIterator::HasAccess(v8::AccessType access_type) const {
   ASSERT_EQ(ACCESS_CHECK, state_);
   ASSERT(is_guaranteed_to_have_holder());
-  return isolate_->MayNamedAccess(GetHolder(), name_, access_type);
+ return isolate_->MayNamedAccess(GetHolder<JSObject>(), name_, access_type);
 }


@@ -109,11 +109,11 @@
   ASSERT(is_guaranteed_to_have_holder());

   if (property_encoding_ == DICTIONARY) {
-    Handle<JSObject> holder = GetHolder();
+    Handle<JSObject> holder = GetHolder<JSObject>();
     number_ = holder->property_dictionary()->FindEntry(name_);
     if (number_ == NameDictionary::kNotFound) return false;

- property_details_ = GetHolder()->property_dictionary()->DetailsAt(number_);
+    property_details_ = holder->property_dictionary()->DetailsAt(number_);
     // Holes in dictionary cells are absent values.
     if (holder->IsGlobalObject() &&
         (property_details_.IsDeleted() || FetchValue()->IsTheHole())) {
@@ -149,7 +149,7 @@
   ASSERT(HolderIsReceiver());
   if (property_encoding_ == DICTIONARY) return;
   holder_map_ = Map::PrepareForDataProperty(holder_map_, number_, value);
-  JSObject::MigrateToMap(GetHolder(), holder_map_);
+  JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_);
   // Reload property information.
   if (holder_map_->is_dictionary_map()) {
     property_encoding_ = DICTIONARY;
@@ -218,10 +218,11 @@

 Handle<Object> LookupIterator::FetchValue() const {
   Object* result = NULL;
+  Handle<JSObject> holder = GetHolder<JSObject>();
   switch (property_encoding_) {
     case DICTIONARY:
-      result = GetHolder()->property_dictionary()->ValueAt(number_);
-      if (GetHolder()->IsGlobalObject()) {
+      result = holder->property_dictionary()->ValueAt(number_);
+      if (holder->IsGlobalObject()) {
         result = PropertyCell::cast(result)->value();
       }
       break;
@@ -230,7 +231,7 @@
         FieldIndex field_index = FieldIndex::ForDescriptor(
             *holder_map_, number_);
         return JSObject::FastPropertyAt(
-            GetHolder(), property_details_.representation(), field_index);
+            holder, property_details_.representation(), field_index);
       }
       result = holder_map_->instance_descriptors()->GetValue(number_);
   }
@@ -256,8 +257,8 @@
 void LookupIterator::WriteDataValue(Handle<Object> value) {
   ASSERT(is_guaranteed_to_have_holder());
   ASSERT(has_property_);
+  Handle<JSObject> holder = GetHolder<JSObject>();
   if (property_encoding_ == DICTIONARY) {
-    Handle<JSObject> holder = GetHolder();
     NameDictionary* property_dictionary = holder->property_dictionary();
     if (holder->IsGlobalObject()) {
       Handle<PropertyCell> cell(
@@ -267,7 +268,7 @@
       property_dictionary->ValueAtPut(number_, *value);
     }
   } else if (property_details_.type() == v8::internal::FIELD) {
-    GetHolder()->WriteToField(number_, *value);
+    holder->WriteToField(number_, *value);
   } else {
     ASSERT_EQ(v8::internal::CONSTANT, property_details_.type());
   }
=======================================
--- /trunk/src/lookup.h Mon Jul 21 00:04:41 2014 UTC
+++ /trunk/src/lookup.h Fri Jul 25 00:05:16 2014 UTC
@@ -93,9 +93,10 @@
     return Handle<Object>::cast(maybe_receiver_.ToHandleChecked());
   }
   Handle<Map> holder_map() const { return holder_map_; }
-  Handle<JSObject> GetHolder() const {
-    ASSERT(IsFound() && state_ != JSPROXY);
-    return Handle<JSObject>::cast(maybe_holder_.ToHandleChecked());
+  template <class T>
+  Handle<T> GetHolder() const {
+    ASSERT(IsFound());
+    return Handle<T>::cast(maybe_holder_.ToHandleChecked());
   }
   Handle<JSReceiver> GetRoot() const;
   bool HolderIsReceiver() const;
@@ -140,11 +141,6 @@
   void WriteDataValue(Handle<Object> value);

   void InternalizeName();
-
-  /* JSPROXY */
-  Handle<JSProxy> GetJSProxy() const {
-    return Handle<JSProxy>::cast(maybe_holder_.ToHandleChecked());
-  }

  private:
   Handle<Map> GetReceiverMap() const;
=======================================
--- /trunk/src/mips/full-codegen-mips.cc        Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/mips/full-codegen-mips.cc        Fri Jul 25 00:05:16 2014 UTC
@@ -1272,16 +1272,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-  __ mov(a0, v0);
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-  __ LoadRoot(at, Heap::kNullValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /trunk/src/mips64/full-codegen-mips64.cc    Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/mips64/full-codegen-mips64.cc    Fri Jul 25 00:05:16 2014 UTC
@@ -1267,16 +1267,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-  __ mov(a0, v0);
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-  __ LoadRoot(at, Heap::kNullValueRootIndex);
-  __ Branch(loop_statement.break_label(), eq, a0, Operand(at));
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /trunk/src/objects-inl.h    Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/objects-inl.h    Fri Jul 25 00:05:16 2014 UTC
@@ -1478,6 +1478,24 @@
 int HeapObject::Size() {
   return SizeFromMap(map());
 }
+
+
+bool HeapObject::MayContainNewSpacePointers() {
+  InstanceType type = map()->instance_type();
+  if (type <= LAST_NAME_TYPE) {
+    if (type == SYMBOL_TYPE) {
+      return true;
+    }
+    ASSERT(type < FIRST_NONSTRING_TYPE);
+    // There are four string representations: sequential strings, external
+    // strings, cons strings, and sliced strings.
+    // Only the latter two contain non-map-word pointers to heap objects.
+    return ((type & kIsIndirectStringMask) == kIsIndirectStringTag);
+  }
+ // The ConstantPoolArray contains heap pointers, but not new space pointers.
+  if (type == CONSTANT_POOL_ARRAY_TYPE) return false;
+  return (type > LAST_DATA_TYPE);
+}


 void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
=======================================
--- /trunk/src/objects.cc       Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/objects.cc       Fri Jul 25 00:05:16 2014 UTC
@@ -135,11 +135,11 @@
       case LookupIterator::NOT_FOUND:
         UNREACHABLE();
       case LookupIterator::JSPROXY:
-        return JSProxy::GetPropertyWithHandler(
-            it->GetJSProxy(), it->GetReceiver(), it->name());
+        return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(),
+ it->GetReceiver(), it->name());
       case LookupIterator::INTERCEPTOR: {
MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor(
-            it->GetHolder(), it->GetReceiver(), it->name());
+            it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
         if (!maybe_result.is_null()) return maybe_result;
         if (it->isolate()->has_pending_exception()) return maybe_result;
         break;
@@ -151,9 +151,9 @@
         if (it->HasProperty()) {
           switch (it->property_kind()) {
             case LookupIterator::ACCESSOR:
-              return GetPropertyWithAccessor(
-                  it->GetReceiver(), it->name(),
-                  it->GetHolder(), it->GetAccessors());
+              return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
+                                             it->GetHolder<JSObject>(),
+                                             it->GetAccessors());
             case LookupIterator::DATA:
               return it->GetDataValue();
           }
@@ -582,10 +582,11 @@

 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
     LookupIterator* it) {
-  Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder());
+  Handle<JSObject> checked = it->GetHolder<JSObject>();
   if (FindAllCanReadHolder(it)) {
-    return GetPropertyWithAccessor(
- it->GetReceiver(), it->name(), it->GetHolder(), it->GetAccessors());
+    return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
+                                   it->GetHolder<JSObject>(),
+                                   it->GetAccessors());
   }
   it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET);
   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
@@ -595,7 +596,7 @@

 PropertyAttributes JSObject::GetPropertyAttributesWithFailedAccessCheck(
     LookupIterator* it) {
-  Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder());
+  Handle<JSObject> checked = it->GetHolder<JSObject>();
   if (FindAllCanReadHolder(it)) return it->property_details().attributes();
   it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS);
   // TODO(yangguo): Issue 3269, check for scheduled exception missing?
@@ -621,11 +622,11 @@

 MaybeHandle<Object> JSObject::SetPropertyWithFailedAccessCheck(
     LookupIterator* it, Handle<Object> value, StrictMode strict_mode) {
-  Handle<JSObject> checked = Handle<JSObject>::cast(it->GetHolder());
+  Handle<JSObject> checked = it->GetHolder<JSObject>();
   if (FindAllCanWriteHolder(it)) {
     return SetPropertyWithAccessor(it->GetReceiver(), it->name(), value,
-                                   it->GetHolder(), it->GetAccessors(),
-                                   strict_mode);
+                                   it->GetHolder<JSObject>(),
+                                   it->GetAccessors(), strict_mode);
   }

   it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET);
@@ -2941,7 +2942,7 @@
   if (it->name()->IsSymbol()) return value;

   Handle<String> name_string = Handle<String>::cast(it->name());
-  Handle<JSObject> holder = it->GetHolder();
+  Handle<JSObject> holder = it->GetHolder<JSObject>();
   Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
   if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>();

@@ -2993,7 +2994,7 @@

       case LookupIterator::JSPROXY:
         if (it->HolderIsReceiver()) {
-          return JSProxy::SetPropertyWithHandler(it->GetJSProxy(),
+          return JSProxy::SetPropertyWithHandler(it->GetHolder<JSProxy>(),
it->GetReceiver(), it->name(),
                                                  value, strict_mode);
         } else {
@@ -3001,8 +3002,8 @@
           bool has_result = false;
           MaybeHandle<Object> maybe_result =
               JSProxy::SetPropertyViaPrototypesWithHandler(
-                  it->GetJSProxy(), it->GetReceiver(), it->name(), value,
-                  strict_mode, &has_result);
+                  it->GetHolder<JSProxy>(), it->GetReceiver(), it->name(),
+                  value, strict_mode, &has_result);
           if (has_result) return maybe_result;
           done = true;
         }
@@ -3017,7 +3018,7 @@
         } else {
           Maybe<PropertyAttributes> maybe_attributes =
               JSObject::GetPropertyAttributesWithInterceptor(
-                  it->GetHolder(), it->GetReceiver(), it->name());
+ it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
           RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
           done = maybe_attributes.has_value;
           if (done && (maybe_attributes.value & READ_ONLY) != 0) {
@@ -3036,7 +3037,7 @@
             if (it->HolderIsReceiver() ||
                 !it->GetAccessors()->IsDeclaredAccessorInfo()) {
               return SetPropertyWithAccessor(it->GetReceiver(), it->name(),
-                                             value, it->GetHolder(),
+ value, it->GetHolder<JSObject>(), it->GetAccessors(), strict_mode);
             }
             break;
@@ -4333,11 +4334,11 @@
         UNREACHABLE();
       case LookupIterator::JSPROXY:
         return JSProxy::GetPropertyAttributesWithHandler(
-            it->GetJSProxy(), it->GetReceiver(), it->name());
+            it->GetHolder<JSProxy>(), it->GetReceiver(), it->name());
       case LookupIterator::INTERCEPTOR: {
         Maybe<PropertyAttributes> result =
             JSObject::GetPropertyAttributesWithInterceptor(
-                it->GetHolder(), it->GetReceiver(), it->name());
+                it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
         if (result.has_value) return result.value;
         break;
       }
=======================================
--- /trunk/src/objects.h        Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/objects.h        Fri Jul 25 00:05:16 2014 UTC
@@ -1747,6 +1747,10 @@
   // Returns the heap object's size in bytes
   inline int Size();

+ // Returns true if this heap object may contain pointers to objects in new
+  // space.
+  inline bool MayContainNewSpacePointers();
+
   // Given a heap object's map pointer, returns the heap size in bytes
   // Useful when the map pointer field is used for other purposes.
   // GC internal.
=======================================
--- /trunk/src/parser.cc        Tue Jul 22 00:04:43 2014 UTC
+++ /trunk/src/parser.cc        Fri Jul 25 00:05:16 2014 UTC
@@ -2749,37 +2749,26 @@
   ForOfStatement* for_of = stmt->AsForOfStatement();

   if (for_of != NULL) {
-    Variable* iterable = scope_->DeclarationScope()->NewTemporary(
-        ast_value_factory_->dot_iterable_string());
     Variable* iterator = scope_->DeclarationScope()->NewTemporary(
         ast_value_factory_->dot_iterator_string());
     Variable* result = scope_->DeclarationScope()->NewTemporary(
         ast_value_factory_->dot_result_string());

-    Expression* assign_iterable;
     Expression* assign_iterator;
     Expression* next_result;
     Expression* result_done;
     Expression* assign_each;

-    // var iterable = subject;
-    {
-      Expression* iterable_proxy = factory()->NewVariableProxy(iterable);
-      assign_iterable = factory()->NewAssignment(
-          Token::ASSIGN, iterable_proxy, subject, subject->position());
-    }
-
-    // var iterator = iterable[Symbol.iterator]();
+    // var iterator = subject[Symbol.iterator]();
     {
-      Expression* iterable_proxy = factory()->NewVariableProxy(iterable);
       Expression* iterator_symbol_literal =
factory()->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition); // FIXME(wingo): Unhappily, it will be a common error that the RHS of a // for-of doesn't have a Symbol.iterator property. We should do better
       // than informing the user that "undefined is not a function".
       int pos = subject->position();
-      Expression* iterator_property = factory()->NewProperty(
-          iterable_proxy, iterator_symbol_literal, pos);
+      Expression* iterator_property =
+          factory()->NewProperty(subject, iterator_symbol_literal, pos);
       ZoneList<Expression*>* iterator_arguments =
           new(zone()) ZoneList<Expression*>(0, zone());
       Expression* iterator_call = factory()->NewCall(
@@ -2826,7 +2815,6 @@
     }

     for_of->Initialize(each, subject, body,
-                       assign_iterable,
                        assign_iterator,
                        next_result,
                        result_done,
=======================================
--- /trunk/src/promise.js       Tue Jul 15 00:04:47 2014 UTC
+++ /trunk/src/promise.js       Fri Jul 25 00:05:16 2014 UTC
@@ -40,7 +40,7 @@
       throw MakeTypeError('resolver_not_a_function', [resolver]);
     var promise = PromiseInit(this);
     if (DEBUG_IS_ACTIVE) {
-      %DebugPromiseEvent({ type : "new Promise",
+      %DebugPromiseEvent({ type : "new",
                            promise: this,
                            resolver: resolver });
     }
@@ -62,6 +62,12 @@
     SET_PRIVATE(promise, promiseValue, value);
     SET_PRIVATE(promise, promiseOnResolve, onResolve);
     SET_PRIVATE(promise, promiseOnReject, onReject);
+    if (DEBUG_IS_ACTIVE && status !== 0) {
+      %DebugPromiseEvent({ type: "update",
+                           promise: promise,
+                           status: status,
+                           value: value });
+    }
     return promise;
   }

@@ -234,6 +240,11 @@
                        -1);
         break;
     }
+    if (DEBUG_IS_ACTIVE) {
+      %DebugPromiseEvent({ type: "chain",
+                           promise: deferred.promise,
+                           parentPromise: this });
+    }
     return deferred.promise;
   }

=======================================
--- /trunk/src/serialize.cc     Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/serialize.cc     Fri Jul 25 00:05:16 2014 UTC
@@ -791,6 +791,8 @@
   if (external_reference_decoder_ == NULL) {
     external_reference_decoder_ = new ExternalReferenceDecoder(isolate);
   }
+
+  DisallowHeapAllocation no_gc;

   // Keep track of the code space start and end pointers in case new
   // code objects were unserialized
@@ -1909,6 +1911,7 @@
   List<byte> payload;
   ListSnapshotSink list_sink(&payload);
   CodeSerializer cs(isolate, &list_sink, *source);
+  DisallowHeapAllocation no_gc;
   Object** location = Handle<Object>::cast(info).location();
   cs.VisitPointer(location);
   cs.Pad();
@@ -2023,7 +2026,6 @@
   for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
     deserializer.set_reservation(i, scd.GetReservation(i));
   }
-  DisallowHeapAllocation no_gc;

   // Prepare and register list of attached objects.
   Vector<Object*> attached_objects = Vector<Object*>::New(1);
=======================================
--- /trunk/src/store-buffer.cc  Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/store-buffer.cc  Fri Jul 25 00:05:16 2014 UTC
@@ -515,8 +515,25 @@
                 heap_->mark_compact_collector()->EnsureSweepingCompleted();
               }
             }
-            FindPointersToNewSpaceInRegion(
-                start, end, slot_callback, clear_maps);
+ // TODO(hpayer): remove the special casing and merge map and pointer
+            // space handling as soon as we removed conservative sweeping.
+            CHECK(page->owner() == heap_->old_pointer_space());
+            if (heap_->old_pointer_space()->swept_precisely()) {
+              HeapObjectIterator iterator(page, NULL);
+              for (HeapObject* heap_object = iterator.Next();
+                   heap_object != NULL; heap_object = iterator.Next()) {
+ // We iterate over objects that contain new space pointers only.
+                if (heap_object->MayContainNewSpacePointers()) {
+                  FindPointersToNewSpaceInRegion(
+                      heap_object->address() + HeapObject::kHeaderSize,
+                      heap_object->address() + heap_object->Size(),
+                      slot_callback, clear_maps);
+                }
+              }
+            } else {
+              FindPointersToNewSpaceInRegion(start, end, slot_callback,
+                                             clear_maps);
+            }
           }
         }
       }
=======================================
--- /trunk/src/stub-cache.cc    Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/stub-cache.cc    Fri Jul 25 00:05:16 2014 UTC
@@ -606,7 +606,16 @@
   Handle<JSObject> receiver = args.at<JSObject>(0);
   Handle<Name> name = args.at<Name>(1);
   Handle<Object> value = args.at<Object>(2);
-  ASSERT(receiver->HasNamedInterceptor());
+#ifdef DEBUG
+  if (receiver->IsJSGlobalProxy()) {
+    PrototypeIterator iter(isolate, receiver);
+    ASSERT(iter.IsAtEnd() ||
+ Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter))
+               ->HasNamedInterceptor());
+  } else {
+    ASSERT(receiver->HasNamedInterceptor());
+  }
+#endif
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, result,
=======================================
--- /trunk/src/version.cc       Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/version.cc       Fri Jul 25 00:05:16 2014 UTC
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     28
-#define BUILD_NUMBER      35
+#define BUILD_NUMBER      38
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/src/x64/full-codegen-x64.cc  Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/x64/full-codegen-x64.cc  Fri Jul 25 00:05:16 2014 UTC
@@ -1241,15 +1241,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterable is null or undefined.
-  __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-  __ CompareRoot(rax, Heap::kNullValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /trunk/src/x87/full-codegen-x87.cc  Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/x87/full-codegen-x87.cc  Fri Jul 25 00:05:16 2014 UTC
@@ -1204,15 +1204,6 @@
   Iteration loop_statement(this, stmt);
   increment_loop_depth();

-  // var iterable = subject
-  VisitForAccumulatorValue(stmt->assign_iterable());
-
-  // As with for-in, skip the loop if the iterator is null or undefined.
-  __ CompareRoot(eax, Heap::kUndefinedValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-  __ CompareRoot(eax, Heap::kNullValueRootIndex);
-  __ j(equal, loop_statement.break_label());
-
   // var iterator = iterable[Symbol.iterator]();
   VisitForEffect(stmt->assign_iterator());

=======================================
--- /trunk/src/x87/lithium-codegen-x87.cc       Thu Jul 24 00:04:58 2014 UTC
+++ /trunk/src/x87/lithium-codegen-x87.cc       Fri Jul 25 00:05:16 2014 UTC
@@ -3131,16 +3131,6 @@
   Register temp = ToRegister(instr->temp());
   Register result = ToRegister(instr->result());

-  // Check that the function really is a function.
-  __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
-  DeoptimizeIf(not_equal, instr->environment());
-
-  // Check whether the function has an instance prototype.
-  Label non_instance;
-  __ test_b(FieldOperand(result, Map::kBitFieldOffset),
-            1 << Map::kHasNonInstancePrototype);
-  __ j(not_zero, &non_instance, Label::kNear);
-
   // Get the prototype or initial map from the function.
   __ mov(result,
          FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
@@ -3156,12 +3146,6 @@

   // Get the prototype from the initial map.
   __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
-  __ jmp(&done, Label::kNear);
-
-  // Non-instance prototype: Fetch prototype from constructor field
-  // in the function's map.
-  __ bind(&non_instance);
-  __ mov(result, FieldOperand(result, Map::kConstructorOffset));

   // All done.
   __ bind(&done);
=======================================
--- /trunk/src/x87/macro-assembler-x87.cc       Wed Jul 16 00:04:33 2014 UTC
+++ /trunk/src/x87/macro-assembler-x87.cc       Fri Jul 25 00:05:16 2014 UTC
@@ -1869,27 +1869,27 @@
                                              Register scratch,
                                              Label* miss,
                                              bool miss_on_bound_function) {
-  // Check that the receiver isn't a smi.
-  JumpIfSmi(function, miss);
+  Label non_instance;
+  if (miss_on_bound_function) {
+    // Check that the receiver isn't a smi.
+    JumpIfSmi(function, miss);

-  // Check that the function really is a function.
-  CmpObjectType(function, JS_FUNCTION_TYPE, result);
-  j(not_equal, miss);
+    // Check that the function really is a function.
+    CmpObjectType(function, JS_FUNCTION_TYPE, result);
+    j(not_equal, miss);

-  if (miss_on_bound_function) {
     // If a bound function, go to miss label.
     mov(scratch,
         FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
     BooleanBitTest(scratch, SharedFunctionInfo::kCompilerHintsOffset,
                    SharedFunctionInfo::kBoundFunction);
     j(not_zero, miss);
+
+    // Make sure that the function has an instance prototype.
+    movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset));
+    test(scratch, Immediate(1 << Map::kHasNonInstancePrototype));
+    j(not_zero, &non_instance);
   }
-
-  // Make sure that the function has an instance prototype.
-  Label non_instance;
-  movzx_b(scratch, FieldOperand(result, Map::kBitFieldOffset));
-  test(scratch, Immediate(1 << Map::kHasNonInstancePrototype));
-  j(not_zero, &non_instance);

   // Get the prototype or initial map from the function.
   mov(result,
@@ -1908,12 +1908,15 @@

   // Get the prototype from the initial map.
   mov(result, FieldOperand(result, Map::kPrototypeOffset));
-  jmp(&done);
+
+  if (miss_on_bound_function) {
+    jmp(&done);

-  // Non-instance prototype: Fetch prototype from constructor field
-  // in initial map.
-  bind(&non_instance);
-  mov(result, FieldOperand(result, Map::kConstructorOffset));
+    // Non-instance prototype: Fetch prototype from constructor field
+    // in initial map.
+    bind(&non_instance);
+    mov(result, FieldOperand(result, Map::kConstructorOffset));
+  }

   // All done.
   bind(&done);
=======================================
--- /trunk/src/x87/stub-cache-x87.cc    Mon Jul 21 08:16:09 2014 UTC
+++ /trunk/src/x87/stub-cache-x87.cc    Fri Jul 25 00:05:16 2014 UTC
@@ -967,13 +967,8 @@
                                          FieldIndex field,
                                          Representation representation) {
   if (!reg.is(receiver())) __ mov(receiver(), reg);
-  if (kind() == Code::LOAD_IC) {
-    LoadFieldStub stub(isolate(), field);
-    GenerateTailCall(masm(), stub.GetCode());
-  } else {
-    KeyedLoadFieldStub stub(isolate(), field);
-    GenerateTailCall(masm(), stub.GetCode());
-  }
+  LoadFieldStub stub(isolate(), field);
+  GenerateTailCall(masm(), stub.GetCode());
 }


=======================================
--- /trunk/test/cctest/cctest.gyp       Thu Jul 10 00:04:42 2014 UTC
+++ /trunk/test/cctest/cctest.gyp       Fri Jul 25 00:05:16 2014 UTC
@@ -78,6 +78,7 @@
         'test-fixed-dtoa.cc',
         'test-flags.cc',
         'test-func-name-inference.cc',
+        'test-gc-tracer.cc',
         'test-global-handles.cc',
         'test-global-object.cc',
         'test-hashing.cc',
=======================================
--- /trunk/test/cctest/cctest.status    Fri Jul 18 00:04:27 2014 UTC
+++ /trunk/test/cctest/cctest.status    Fri Jul 25 00:05:16 2014 UTC
@@ -31,6 +31,7 @@
   'test-api/Bug*': [FAIL],

##############################################################################
+
   # BUG(382): Weird test. Can't guarantee that it never times out.
   'test-api/ApplyInterruption': [PASS, TIMEOUT],

@@ -70,6 +71,11 @@
   'test-hydrogen-types/*': [PASS, NO_VARIANTS],
   'test-types/*': [PASS, NO_VARIANTS],

+  # The cpu profiler tests are notoriously flaky.
+  # BUG(2999). (test/cpu-profiler/CollectCpuProfile)
+  # BUG(3287). (test-cpu-profiler/SampleWhenFrameIsNotSetup)
+  'test-cpu-profiler/*': [PASS, FLAKY],
+
############################################################################
   # Slow tests.
   'test-api/Threading1': [PASS, ['mode == debug', SLOW]],
=======================================
--- /trunk/test/cctest/test-api.cc      Mon Jul 21 00:04:41 2014 UTC
+++ /trunk/test/cctest/test-api.cc      Fri Jul 25 00:05:16 2014 UTC
@@ -13498,21 +13498,21 @@
     { v8::HandleScope scope(CcTest::isolate());
       LocalContext context;
     }
-    v8::V8::ContextDisposedNotification();
+    CcTest::isolate()->ContextDisposedNotification();
     CheckSurvivingGlobalObjectsCount(0);

     { v8::HandleScope scope(CcTest::isolate());
       LocalContext context;
       v8_compile("Date")->Run();
     }
-    v8::V8::ContextDisposedNotification();
+    CcTest::isolate()->ContextDisposedNotification();
     CheckSurvivingGlobalObjectsCount(0);

     { v8::HandleScope scope(CcTest::isolate());
       LocalContext context;
       v8_compile("/aaa/")->Run();
     }
-    v8::V8::ContextDisposedNotification();
+    CcTest::isolate()->ContextDisposedNotification();
     CheckSurvivingGlobalObjectsCount(0);

     { v8::HandleScope scope(CcTest::isolate());
@@ -13521,7 +13521,7 @@
       LocalContext context(&extensions);
       v8_compile("gc();")->Run();
     }
-    v8::V8::ContextDisposedNotification();
+    CcTest::isolate()->ContextDisposedNotification();
     CheckSurvivingGlobalObjectsCount(0);
   }
 }
@@ -17600,6 +17600,7 @@
 // Test that idle notification can be handled and eventually returns true.
 TEST(IdleNotification) {
   const intptr_t MB = 1024 * 1024;
+  const int IdlePauseInMs = 1000;
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
   intptr_t initial_size = CcTest::heap()->SizeOfObjects();
@@ -17608,7 +17609,7 @@
   CHECK_GT(size_with_garbage, initial_size + MB);
   bool finished = false;
   for (int i = 0; i < 200 && !finished; i++) {
-    finished = v8::V8::IdleNotification();
+    finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
   }
   intptr_t final_size = CcTest::heap()->SizeOfObjects();
   CHECK(finished);
@@ -17628,7 +17629,7 @@
   CHECK_GT(size_with_garbage, initial_size + MB);
   bool finished = false;
   for (int i = 0; i < 200 && !finished; i++) {
-    finished = v8::V8::IdleNotification(IdlePauseInMs);
+    finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
   }
   intptr_t final_size = CcTest::heap()->SizeOfObjects();
   CHECK(finished);
@@ -17648,7 +17649,7 @@
   CHECK_GT(size_with_garbage, initial_size + MB);
   bool finished = false;
   for (int i = 0; i < 200 && !finished; i++) {
-    finished = v8::V8::IdleNotification(IdlePauseInMs);
+    finished = env->GetIsolate()->IdleNotification(IdlePauseInMs);
   }
   intptr_t final_size = CcTest::heap()->SizeOfObjects();
   CHECK(finished);
@@ -17665,7 +17666,7 @@
   v8::HandleScope scope(env->GetIsolate());
   intptr_t initial_size = CcTest::heap()->SizeOfObjects();
   // Send idle notification to start a round of incremental GCs.
-  v8::V8::IdleNotification(kShortIdlePauseInMs);
+  env->GetIsolate()->IdleNotification(kShortIdlePauseInMs);
   // Emulate 7 page reloads.
   for (int i = 0; i < 7; i++) {
     {
@@ -17675,8 +17676,8 @@
       CreateGarbageInOldSpace();
       ctx->Exit();
     }
-    v8::V8::ContextDisposedNotification();
-    v8::V8::IdleNotification(kLongIdlePauseInMs);
+    env->GetIsolate()->ContextDisposedNotification();
+    env->GetIsolate()->IdleNotification(kLongIdlePauseInMs);
   }
   // Create garbage and check that idle notification still collects it.
   CreateGarbageInOldSpace();
@@ -17684,7 +17685,7 @@
   CHECK_GT(size_with_garbage, initial_size + MB);
   bool finished = false;
   for (int i = 0; i < 200 && !finished; i++) {
-    finished = v8::V8::IdleNotification(kShortIdlePauseInMs);
+    finished = env->GetIsolate()->IdleNotification(kShortIdlePauseInMs);
   }
   intptr_t final_size = CcTest::heap()->SizeOfObjects();
   CHECK_LT(final_size, initial_size + 1);
@@ -18160,7 +18161,7 @@
     CompileRun(source_simple);
     context->Exit();
   }
-  v8::V8::ContextDisposedNotification();
+  isolate->ContextDisposedNotification();
   for (gc_count = 1; gc_count < 10; gc_count++) {
     other_context->Enter();
     CompileRun(source_simple);
@@ -18182,7 +18183,7 @@
     CompileRun(source_eval);
     context->Exit();
   }
-  v8::V8::ContextDisposedNotification();
+  isolate->ContextDisposedNotification();
   for (gc_count = 1; gc_count < 10; gc_count++) {
     other_context->Enter();
     CompileRun(source_eval);
@@ -18209,7 +18210,7 @@
     CHECK_EQ(1, message->GetLineNumber());
     context->Exit();
   }
-  v8::V8::ContextDisposedNotification();
+  isolate->ContextDisposedNotification();
   for (gc_count = 1; gc_count < 10; gc_count++) {
     other_context->Enter();
     CompileRun(source_exception);
@@ -18220,7 +18221,7 @@
   CHECK_GE(2, gc_count);
   CHECK_EQ(1, GetGlobalObjectsCount());

-  v8::V8::ContextDisposedNotification();
+  isolate->ContextDisposedNotification();
 }


=======================================
--- /trunk/test/cctest/test-heap.cc     Tue Jul 22 00:04:43 2014 UTC
+++ /trunk/test/cctest/test-heap.cc     Fri Jul 25 00:05:16 2014 UTC
@@ -1797,7 +1797,7 @@
     ctx2->Exit();
     v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
     ctx1p.Reset();
-    v8::V8::ContextDisposedNotification();
+    isolate->ContextDisposedNotification();
   }
   CcTest::heap()->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1843,7 +1843,7 @@
     ctx2->Exit();
     ctx1->Exit();
     ctx1p.Reset();
-    v8::V8::ContextDisposedNotification();
+    isolate->ContextDisposedNotification();
   }
   CcTest::heap()->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1887,7 +1887,7 @@
     ctx2->Exit();
     ctx1->Exit();
     ctx1p.Reset();
-    v8::V8::ContextDisposedNotification();
+    isolate->ContextDisposedNotification();
   }
   CcTest::heap()->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
@@ -1935,7 +1935,7 @@
     ctx2->Exit();
     ctx1->Exit();
     ctx1p.Reset();
-    v8::V8::ContextDisposedNotification();
+    isolate->ContextDisposedNotification();
   }
   CcTest::heap()->CollectAllAvailableGarbage();
   CHECK_EQ(2, NumberOfGlobalObjects());
@@ -2096,8 +2096,8 @@

// The following two calls will increment CcTest::heap()->global_ic_age().
   const int kLongIdlePauseInMs = 1000;
-  v8::V8::ContextDisposedNotification();
-  v8::V8::IdleNotification(kLongIdlePauseInMs);
+  CcTest::isolate()->ContextDisposedNotification();
+  CcTest::isolate()->IdleNotification(kLongIdlePauseInMs);

   while (!marking->IsStopped() && !marking->IsComplete()) {
     marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
@@ -2152,8 +2152,8 @@
// The following two calls will increment CcTest::heap()->global_ic_age().
   // Since incremental marking is off, IdleNotification will do full GC.
   const int kLongIdlePauseInMs = 1000;
-  v8::V8::ContextDisposedNotification();
-  v8::V8::IdleNotification(kLongIdlePauseInMs);
+  CcTest::isolate()->ContextDisposedNotification();
+  CcTest::isolate()->IdleNotification(kLongIdlePauseInMs);

   CHECK_EQ(CcTest::heap()->global_ic_age(), f->shared()->ic_age());
   CHECK_EQ(0, f->shared()->opt_count());
@@ -3207,7 +3207,7 @@
   CHECK(ic_before->ic_state() == MONOMORPHIC);

   // Fire context dispose notification.
-  v8::V8::ContextDisposedNotification();
+  CcTest::isolate()->ContextDisposedNotification();
   SimulateIncrementalMarking();
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);

@@ -3248,7 +3248,7 @@
   CHECK(ic_before->ic_state() == POLYMORPHIC);

   // Fire context dispose notification.
-  v8::V8::ContextDisposedNotification();
+  CcTest::isolate()->ContextDisposedNotification();
   SimulateIncrementalMarking();
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);

=======================================
--- /trunk/test/cctest/test-object-observe.cc   Tue Jul 15 00:04:47 2014 UTC
+++ /trunk/test/cctest/test-object-observe.cc   Fri Jul 25 00:05:16 2014 UTC
@@ -658,7 +658,7 @@
                "Object.unobserve(obj, observer);");
   }

-  v8::V8::ContextDisposedNotification();
+  CcTest::isolate()->ContextDisposedNotification();
   CheckSurvivingGlobalObjectsCount(1);
 }

@@ -679,7 +679,7 @@
     CompileRun("Object.getNotifier(obj);");
   }

-  v8::V8::ContextDisposedNotification();
+  CcTest::isolate()->ContextDisposedNotification();
   CheckSurvivingGlobalObjectsCount(1);
 }

@@ -706,6 +706,6 @@
                    "notifier, 'foo', function(){})");
   }

-  v8::V8::ContextDisposedNotification();
+  CcTest::isolate()->ContextDisposedNotification();
   CheckSurvivingGlobalObjectsCount(1);
 }
=======================================
***Additional files exist in this changeset.***

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to