Revision: 24709
Author:   [email protected]
Date:     Fri Oct 17 20:38:26 2014 UTC
Log:      Version 3.30.13 (based on bleeding_edge revision r24708)

Don't expose Array.prototype.values as it breaks webcompat (Chromium issue 409858).

Fix break location calculation (Chromium issue 419663).

Enable libstdc++ debug mode in debug builds (issue 3638).

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

Added:
 /trunk/src/compiler/control-reducer.cc
 /trunk/src/compiler/control-reducer.h
 /trunk/test/cctest/compiler/test-control-reducer.cc
 /trunk/test/cctest/types-fuzz.h
 /trunk/test/js-perf-test/Classes
 /trunk/test/js-perf-test/Classes/Classes.json
 /trunk/test/js-perf-test/Classes/run.js
 /trunk/test/js-perf-test/Classes/super.js
 /trunk/test/js-perf-test/Iterators
 /trunk/test/js-perf-test/Iterators/Iterators.json
 /trunk/test/js-perf-test/Iterators/forof.js
 /trunk/test/js-perf-test/Iterators/run.js
 /trunk/test/js-perf-test/base.js
 /trunk/test/mjsunit/asm/do-while-false.js
 /trunk/test/mjsunit/asm/if-folding.js
 /trunk/test/mjsunit/asm/if-reduction.js
 /trunk/test/mjsunit/asm/infinite-loops-taken.js
 /trunk/test/mjsunit/asm/infinite-loops.js
 /trunk/test/mjsunit/asm/int32array-constant-key.js
 /trunk/test/mjsunit/asm/word32and.js
 /trunk/test/mjsunit/regress/regress-419663.js
 /trunk/test/mjsunit/unused-context-in-with.js
Deleted:
 /trunk/test/js-perf-test/Collections/base.js
Modified:
 /trunk/AUTHORS
 /trunk/BUILD.gn
 /trunk/ChangeLog
 /trunk/build/standalone.gypi
 /trunk/include/v8.h
 /trunk/src/api.cc
 /trunk/src/arm/code-stubs-arm.cc
 /trunk/src/arm/disasm-arm.cc
 /trunk/src/arm/full-codegen-arm.cc
 /trunk/src/arm64/code-stubs-arm64.cc
 /trunk/src/arm64/disasm-arm64.cc
 /trunk/src/arm64/full-codegen-arm64.cc
 /trunk/src/array-iterator.js
 /trunk/src/array.js
 /trunk/src/ast.cc
 /trunk/src/ast.h
 /trunk/src/code-stubs.h
 /trunk/src/compiler/arm/instruction-selector-arm.cc
 /trunk/src/compiler/arm64/instruction-selector-arm64.cc
 /trunk/src/compiler/ast-graph-builder.cc
 /trunk/src/compiler/ia32/instruction-selector-ia32.cc
 /trunk/src/compiler/mips/instruction-selector-mips.cc
 /trunk/src/compiler/node-matchers.h
 /trunk/src/compiler/pipeline.cc
 /trunk/src/compiler/simplified-operator-reducer.cc
 /trunk/src/compiler/simplified-operator-reducer.h
 /trunk/src/compiler/x64/code-generator-x64.cc
 /trunk/src/compiler/x64/instruction-selector-x64.cc
 /trunk/src/compiler.cc
 /trunk/src/cpu-profiler.cc
 /trunk/src/debug.cc
 /trunk/src/factory.cc
 /trunk/src/factory.h
 /trunk/src/harmony-string.js
 /trunk/src/ia32/code-stubs-ia32.cc
 /trunk/src/ia32/disasm-ia32.cc
 /trunk/src/ia32/full-codegen-ia32.cc
 /trunk/src/ia32/macro-assembler-ia32.cc
 /trunk/src/ic/x87/ic-x87.cc
 /trunk/src/isolate.h
 /trunk/src/lookup.cc
 /trunk/src/lookup.h
 /trunk/src/mips/code-stubs-mips.cc
 /trunk/src/mips/full-codegen-mips.cc
 /trunk/src/mips64/code-stubs-mips64.cc
 /trunk/src/mips64/full-codegen-mips64.cc
 /trunk/src/objects.cc
 /trunk/src/objects.h
 /trunk/src/runtime/runtime-classes.cc
 /trunk/src/sampler.cc
 /trunk/src/sampler.h
 /trunk/src/version.cc
 /trunk/src/x64/assembler-x64-inl.h
 /trunk/src/x64/assembler-x64.cc
 /trunk/src/x64/assembler-x64.h
 /trunk/src/x64/code-stubs-x64.cc
 /trunk/src/x64/disasm-x64.cc
 /trunk/src/x64/full-codegen-x64.cc
 /trunk/src/x64/macro-assembler-x64.cc
 /trunk/src/x64/macro-assembler-x64.h
 /trunk/src/x87/code-stubs-x87.cc
 /trunk/test/cctest/cctest.gyp
 /trunk/test/cctest/cctest.status
 /trunk/test/cctest/compiler/test-run-jsbranches.cc
 /trunk/test/cctest/compiler/test-typer.cc
 /trunk/test/cctest/test-api.cc
 /trunk/test/cctest/test-disasm-x64.cc
 /trunk/test/cctest/test-serialize.cc
 /trunk/test/cctest/test-types.cc
 /trunk/test/cctest/trace-extension.cc
 /trunk/test/js-perf-test/Collections/run.js
 /trunk/test/mjsunit/es6/arguments-iterator.js
 /trunk/test/mjsunit/es6/array-iterator.js
 /trunk/test/mjsunit/es6/typed-array-iterator.js
 /trunk/test/mjsunit/harmony/string-repeat.js
 /trunk/test/mjsunit/harmony/super.js
 /trunk/test/mjsunit/harmony/typedarrays.js
 /trunk/test/mjsunit/mjsunit.status
 /trunk/test/mjsunit/tools/tickprocessor-test.default
 /trunk/test/mjsunit/tools/tickprocessor-test.func-info
 /trunk/test/mjsunit/tools/tickprocessor-test.gc-state
 /trunk/test/mjsunit/tools/tickprocessor-test.ignore-unknown
 /trunk/test/mjsunit/tools/tickprocessor-test.separate-ic
 /trunk/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
 /trunk/test/unittests/compiler/js-typed-lowering-unittest.cc
 /trunk/test/unittests/compiler/simplified-operator-reducer-unittest.cc
 /trunk/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
 /trunk/test/webkit/fast/js/Object-getOwnPropertyNames.js
 /trunk/tools/codemap.js
 /trunk/tools/gyp/v8.gyp
 /trunk/tools/logreader.js
 /trunk/tools/profile.js
 /trunk/tools/tickprocessor.js

=======================================
--- /dev/null
+++ /trunk/src/compiler/control-reducer.cc      Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,122 @@
+// 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/compiler/common-operator.h"
+#include "src/compiler/control-reducer.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+enum VisitState { kUnvisited, kOnStack, kRevisit, kVisited };
+
+#define TRACE(x) \
+  if (FLAG_trace_turbo) PrintF x
+
+class ControlReducerImpl {
+ public:
+  ControlReducerImpl(JSGraph* jsgraph, CommonOperatorBuilder* common)
+      : zone_(jsgraph->zone()->isolate()),
+        jsgraph_(jsgraph),
+        common_(common),
+        state_(jsgraph->graph()->NodeCount(), kUnvisited, &zone_),
+        stack_(&zone_),
+        revisit_(&zone_),
+        dead_(NULL) {}
+
+  Zone zone_;
+  JSGraph* jsgraph_;
+  CommonOperatorBuilder* common_;
+  ZoneVector<VisitState> state_;
+  ZoneDeque<Node*> stack_;
+  ZoneDeque<Node*> revisit_;
+  Node* dead_;
+
+  void Trim() {
+    //  Mark all nodes reachable from end.
+    NodeVector nodes(&zone_);
+    state_.assign(jsgraph_->graph()->NodeCount(), kUnvisited);
+    Push(jsgraph_->graph()->end());
+    while (!stack_.empty()) {
+      Node* node = stack_[stack_.size() - 1];
+      stack_.pop_back();
+      state_[node->id()] = kVisited;
+      nodes.push_back(node);
+      for (InputIter i = node->inputs().begin(); i != node->inputs().end();
+           ++i) {
+        Recurse(*i);  // pushes node onto the stack if necessary.
+      }
+    }
+    // Process cached nodes in the JSGraph too.
+    jsgraph_->GetCachedNodes(&nodes);
+    // Remove dead->live edges.
+    for (size_t j = 0; j < nodes.size(); j++) {
+      Node* node = nodes[j];
+      for (UseIter i = node->uses().begin(); i != node->uses().end();) {
+        size_t id = static_cast<size_t>((*i)->id());
+        if (state_[id] != kVisited) {
+          TRACE(("DeadLink: #%d:%s(%d) -> #%d:%s\n", (*i)->id(),
+                 (*i)->op()->mnemonic(), i.index(), node->id(),
+                 node->op()->mnemonic()));
+          i.UpdateToAndIncrement(NULL);
+        } else {
+          ++i;
+        }
+      }
+    }
+#if DEBUG
+    // Verify that no inputs to live nodes are NULL.
+    for (size_t j = 0; j < nodes.size(); j++) {
+      Node* node = nodes[j];
+      for (InputIter i = node->inputs().begin(); i != node->inputs().end();
+           ++i) {
+        CHECK_NE(NULL, *i);
+      }
+ for (UseIter i = node->uses().begin(); i != node->uses().end(); ++i) {
+        size_t id = static_cast<size_t>((*i)->id());
+        CHECK_EQ(kVisited, state_[id]);
+      }
+    }
+#endif
+  }
+
+  // Push a node onto the stack if its state is {kUnvisited} or {kRevisit}.
+  bool Recurse(Node* node) {
+    size_t id = static_cast<size_t>(node->id());
+    if (id < state_.size()) {
+      if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
+    } else {
+      state_.resize((3 * id) / 2, kUnvisited);
+    }
+    Push(node);
+    return true;
+  }
+
+  void Push(Node* node) {
+    state_[node->id()] = kOnStack;
+    stack_.push_back(node);
+  }
+};
+
+void ControlReducer::ReduceGraph(JSGraph* jsgraph,
+                                 CommonOperatorBuilder* common) {
+  ControlReducerImpl impl(jsgraph, NULL);
+ // Only trim the graph for now. Control reduction can reduce non-terminating
+  // loops to graphs that are unschedulable at the moment.
+  impl.Trim();
+}
+
+
+void ControlReducer::TrimGraph(JSGraph* jsgraph) {
+  ControlReducerImpl impl(jsgraph, NULL);
+  impl.Trim();
+}
+}
+}
+}  // namespace v8::internal::compiler
=======================================
--- /dev/null
+++ /trunk/src/compiler/control-reducer.h       Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,27 @@
+// 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_COMPILER_CONTROL_REDUCER_H_
+#define V8_COMPILER_CONTROL_REDUCER_H_
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class JSGraph;
+class CommonOperatorBuilder;
+
+class ControlReducer {
+ public:
+  // Perform branch folding and dead code elimination on the graph.
+  static void ReduceGraph(JSGraph* graph, CommonOperatorBuilder* builder);
+
+  // Trim nodes in the graph that are not reachable from end.
+  static void TrimGraph(JSGraph* graph);
+};
+}
+}
+}  // namespace v8::internal::compiler
+
+#endif  // V8_COMPILER_CONTROL_REDUCER_H_
=======================================
--- /dev/null
+++ /trunk/test/cctest/compiler/test-control-reducer.cc Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,242 @@
+// 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 "test/cctest/cctest.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/control-reducer.h"
+#include "src/compiler/graph-inl.h"
+#include "src/compiler/js-graph.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+class CTrimTester : HandleAndZoneScope {
+ public:
+  CTrimTester()
+      : isolate(main_isolate()),
+        common(main_zone()),
+        graph(main_zone()),
+        jsgraph(&graph, &common, NULL, NULL),
+        start(graph.NewNode(common.Start(1))),
+        p0(graph.NewNode(common.Parameter(0), start)),
+        one(jsgraph.OneConstant()),
+        half(jsgraph.Constant(0.5)) {
+    graph.SetEnd(start);
+    graph.SetStart(start);
+  }
+
+  Isolate* isolate;
+  CommonOperatorBuilder common;
+  Graph graph;
+  JSGraph jsgraph;
+  Node* start;
+  Node* p0;
+  Node* one;
+  Node* half;
+
+  void Trim() { ControlReducer::TrimGraph(&jsgraph); }
+};
+
+
+bool IsUsedBy(Node* a, Node* b) {
+  for (UseIter i = a->uses().begin(); i != a->uses().end(); ++i) {
+    if (b == *i) return true;
+  }
+  return false;
+}
+
+
+TEST(Trim1_live) {
+  CTrimTester T;
+  CHECK(IsUsedBy(T.start, T.p0));
+  T.graph.SetEnd(T.p0);
+  T.Trim();
+  CHECK(IsUsedBy(T.start, T.p0));
+  CHECK_EQ(T.start, T.p0->InputAt(0));
+}
+
+
+TEST(Trim1_dead) {
+  CTrimTester T;
+  CHECK(IsUsedBy(T.start, T.p0));
+  T.Trim();
+  CHECK(!IsUsedBy(T.start, T.p0));
+  CHECK_EQ(NULL, T.p0->InputAt(0));
+}
+
+
+TEST(Trim2_live) {
+  CTrimTester T;
+  Node* phi =
+ T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+  CHECK(IsUsedBy(T.start, phi));
+  T.graph.SetEnd(phi);
+  T.Trim();
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+  CHECK(IsUsedBy(T.start, phi));
+  CHECK_EQ(T.one, phi->InputAt(0));
+  CHECK_EQ(T.half, phi->InputAt(1));
+  CHECK_EQ(T.start, phi->InputAt(2));
+}
+
+
+TEST(Trim2_dead) {
+  CTrimTester T;
+  Node* phi =
+ T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+  CHECK(IsUsedBy(T.start, phi));
+  T.Trim();
+  CHECK(!IsUsedBy(T.one, phi));
+  CHECK(!IsUsedBy(T.half, phi));
+  CHECK(!IsUsedBy(T.start, phi));
+  CHECK_EQ(NULL, phi->InputAt(0));
+  CHECK_EQ(NULL, phi->InputAt(1));
+  CHECK_EQ(NULL, phi->InputAt(2));
+}
+
+
+TEST(Trim_chain1) {
+  CTrimTester T;
+  const int kDepth = 15;
+  Node* live[kDepth];
+  Node* dead[kDepth];
+  Node* end = T.start;
+  for (int i = 0; i < kDepth; i++) {
+    live[i] = end = T.graph.NewNode(T.common.Merge(1), end);
+    dead[i] = T.graph.NewNode(T.common.Merge(1), end);
+  }
+  // end         -> live[last] ->  live[last-1] -> ... -> start
+  //     dead[last] ^ dead[last-1] ^ ...                  ^
+  T.graph.SetEnd(end);
+  T.Trim();
+  for (int i = 0; i < kDepth; i++) {
+    CHECK(!IsUsedBy(live[i], dead[i]));
+    CHECK_EQ(NULL, dead[i]->InputAt(0));
+    CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
+  }
+}
+
+
+TEST(Trim_chain2) {
+  CTrimTester T;
+  const int kDepth = 15;
+  Node* live[kDepth];
+  Node* dead[kDepth];
+  Node* l = T.start;
+  Node* d = T.start;
+  for (int i = 0; i < kDepth; i++) {
+    live[i] = l = T.graph.NewNode(T.common.Merge(1), l);
+    dead[i] = d = T.graph.NewNode(T.common.Merge(1), d);
+  }
+  // end -> live[last] -> live[last-1] -> ... -> start
+  //        dead[last] -> dead[last-1] -> ... -> start
+  T.graph.SetEnd(l);
+  T.Trim();
+  CHECK(!IsUsedBy(T.start, dead[0]));
+  for (int i = 0; i < kDepth; i++) {
+    CHECK_EQ(i == 0 ? NULL : dead[i - 1], dead[i]->InputAt(0));
+    CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
+  }
+}
+
+
+TEST(Trim_cycle1) {
+  CTrimTester T;
+  Node* loop = T.graph.NewNode(T.common.Loop(1), T.start, T.start);
+  loop->ReplaceInput(1, loop);
+  Node* end = T.graph.NewNode(T.common.End(), loop);
+  T.graph.SetEnd(end);
+
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+
+  T.Trim();
+
+  // nothing should have happened to the loop itself.
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+  CHECK_EQ(T.start, loop->InputAt(0));
+  CHECK_EQ(loop, loop->InputAt(1));
+  CHECK_EQ(loop, end->InputAt(0));
+}
+
+
+TEST(Trim_cycle2) {
+  CTrimTester T;
+  Node* loop = T.graph.NewNode(T.common.Loop(2), T.start, T.start);
+  loop->ReplaceInput(1, loop);
+  Node* end = T.graph.NewNode(T.common.End(), loop);
+  Node* phi =
+ T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, loop);
+  T.graph.SetEnd(end);
+
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+  CHECK(IsUsedBy(loop, phi));
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+
+  T.Trim();
+
+  // nothing should have happened to the loop itself.
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+  CHECK_EQ(T.start, loop->InputAt(0));
+  CHECK_EQ(loop, loop->InputAt(1));
+  CHECK_EQ(loop, end->InputAt(0));
+
+  // phi should have been trimmed away.
+  CHECK(!IsUsedBy(loop, phi));
+  CHECK(!IsUsedBy(T.one, phi));
+  CHECK(!IsUsedBy(T.half, phi));
+  CHECK_EQ(NULL, phi->InputAt(0));
+  CHECK_EQ(NULL, phi->InputAt(1));
+  CHECK_EQ(NULL, phi->InputAt(2));
+}
+
+
+void CheckTrimConstant(CTrimTester* T, Node* k) {
+  Node* phi = T->graph.NewNode(T->common.Phi(kMachInt32, 1), k, T->start);
+  CHECK(IsUsedBy(k, phi));
+  T->Trim();
+  CHECK(!IsUsedBy(k, phi));
+  CHECK_EQ(NULL, phi->InputAt(0));
+  CHECK_EQ(NULL, phi->InputAt(1));
+}
+
+
+TEST(Trim_constants) {
+  CTrimTester T;
+  int32_t int32_constants[] = {
+ 0, -1, -2, 2, 2, 3, 3, 4, 4, 5, 5, 4, 5, 6, 6, 7, 8, 7, 8, 9, + 0, -11, -12, 12, 12, 13, 13, 14, 14, 15, 15, 14, 15, 6, 6, 7, 8, 7, 8, 9};
+
+  for (size_t i = 0; i < arraysize(int32_constants); i++) {
+    CheckTrimConstant(&T, T.jsgraph.Int32Constant(int32_constants[i]));
+    CheckTrimConstant(&T, T.jsgraph.Float64Constant(int32_constants[i]));
+    CheckTrimConstant(&T, T.jsgraph.Constant(int32_constants[i]));
+  }
+
+  Node* other_constants[] = {
+      T.jsgraph.UndefinedConstant(), T.jsgraph.TheHoleConstant(),
+      T.jsgraph.TrueConstant(),      T.jsgraph.FalseConstant(),
+      T.jsgraph.NullConstant(),      T.jsgraph.ZeroConstant(),
+      T.jsgraph.OneConstant(),       T.jsgraph.NaNConstant(),
+      T.jsgraph.Constant(21),        T.jsgraph.Constant(22.2)};
+
+  for (size_t i = 0; i < arraysize(other_constants); i++) {
+    CheckTrimConstant(&T, other_constants[i]);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/test/cctest/types-fuzz.h     Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,317 @@
+// 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.
+
+#ifndef V8_TEST_CCTEST_TYPES_H_
+#define V8_TEST_CCTEST_TYPES_H_
+
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+
+
+template<class Type, class TypeHandle, class Region>
+class Types {
+ public:
+  Types(Region* region, Isolate* isolate)
+      : region_(region), rng_(isolate->random_number_generator()) {
+    #define DECLARE_TYPE(name, value) \
+      name = Type::name(region); \
+      if (SmiValuesAre31Bits() || \
+          (!Type::name(region)->Equals(Type::OtherSigned32()) && \
+           !Type::name(region)->Equals(Type::OtherUnsigned31()))) { \
+        /* Hack: Avoid generating those empty bitset types. */ \
+        types.push_back(name); \
+      }
+    PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
+    #undef DECLARE_TYPE
+
+    object_map = isolate->factory()->NewMap(
+        JS_OBJECT_TYPE, JSObject::kHeaderSize);
+    array_map = isolate->factory()->NewMap(
+        JS_ARRAY_TYPE, JSArray::kSize);
+    number_map = isolate->factory()->NewMap(
+        HEAP_NUMBER_TYPE, HeapNumber::kSize);
+    uninitialized_map = isolate->factory()->uninitialized_map();
+    ObjectClass = Type::Class(object_map, region);
+    ArrayClass = Type::Class(array_map, region);
+    NumberClass = Type::Class(number_map, region);
+    UninitializedClass = Type::Class(uninitialized_map, region);
+
+    maps.push_back(object_map);
+    maps.push_back(array_map);
+    maps.push_back(uninitialized_map);
+    for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
+      types.push_back(Type::Class(*it, region));
+    }
+
+    smi = handle(Smi::FromInt(666), isolate);
+    signed32 = isolate->factory()->NewHeapNumber(0x40000000);
+    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
+    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
+    array = isolate->factory()->NewJSArray(20);
+    uninitialized = isolate->factory()->uninitialized_value();
+    SmiConstant = Type::Constant(smi, region);
+    Signed32Constant = Type::Constant(signed32, region);
+    ObjectConstant1 = Type::Constant(object1, region);
+    ObjectConstant2 = Type::Constant(object2, region);
+    ArrayConstant = Type::Constant(array, region);
+    UninitializedConstant = Type::Constant(uninitialized, region);
+
+    values.push_back(smi);
+    values.push_back(signed32);
+    values.push_back(object1);
+    values.push_back(object2);
+    values.push_back(array);
+    values.push_back(uninitialized);
+ for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
+      types.push_back(Type::Constant(*it, region));
+    }
+
+    integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
+    integers.push_back(isolate->factory()->NewNumber(+V8_INFINITY));
+    integers.push_back(isolate->factory()->NewNumber(-rng_->NextInt(10)));
+    integers.push_back(isolate->factory()->NewNumber(+rng_->NextInt(10)));
+    for (int i = 0; i < 10; ++i) {
+      double x = rng_->NextInt();
+      integers.push_back(isolate->factory()->NewNumber(x));
+      x *= rng_->NextInt();
+ if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
+    }
+
+    NumberArray = Type::Array(Number, region);
+    StringArray = Type::Array(String, region);
+    AnyArray = Type::Array(Any, region);
+
+    SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
+    NumberFunction1 = Type::Function(Number, Number, region);
+    NumberFunction2 = Type::Function(Number, Number, Number, region);
+    MethodFunction = Type::Function(String, Object, 0, region);
+
+    for (int i = 0; i < 30; ++i) {
+      types.push_back(Fuzz());
+    }
+  }
+
+  Handle<i::Map> object_map;
+  Handle<i::Map> array_map;
+  Handle<i::Map> number_map;
+  Handle<i::Map> uninitialized_map;
+
+  Handle<i::Smi> smi;
+  Handle<i::HeapNumber> signed32;
+  Handle<i::JSObject> object1;
+  Handle<i::JSObject> object2;
+  Handle<i::JSArray> array;
+  Handle<i::Oddball> uninitialized;
+
+  #define DECLARE_TYPE(name, value) TypeHandle name;
+  BITSET_TYPE_LIST(DECLARE_TYPE)
+  #undef DECLARE_TYPE
+
+  TypeHandle ObjectClass;
+  TypeHandle ArrayClass;
+  TypeHandle NumberClass;
+  TypeHandle UninitializedClass;
+
+  TypeHandle SmiConstant;
+  TypeHandle Signed32Constant;
+  TypeHandle ObjectConstant1;
+  TypeHandle ObjectConstant2;
+  TypeHandle ArrayConstant;
+  TypeHandle UninitializedConstant;
+
+  TypeHandle NumberArray;
+  TypeHandle StringArray;
+  TypeHandle AnyArray;
+
+  TypeHandle SignedFunction1;
+  TypeHandle NumberFunction1;
+  TypeHandle NumberFunction2;
+  TypeHandle MethodFunction;
+
+  typedef std::vector<TypeHandle> TypeVector;
+  typedef std::vector<Handle<i::Map> > MapVector;
+  typedef std::vector<Handle<i::Object> > ValueVector;
+
+  TypeVector types;
+  MapVector maps;
+  ValueVector values;
+  ValueVector integers;  // "Integer" values used for range limits.
+
+  TypeHandle Of(Handle<i::Object> value) {
+    return Type::Of(value, region_);
+  }
+
+  TypeHandle NowOf(Handle<i::Object> value) {
+    return Type::NowOf(value, region_);
+  }
+
+  TypeHandle Class(Handle<i::Map> map) {
+    return Type::Class(map, region_);
+  }
+
+  TypeHandle Constant(Handle<i::Object> value) {
+    return Type::Constant(value, region_);
+  }
+
+  TypeHandle Range(Handle<i::Object> min, Handle<i::Object> max) {
+    return Type::Range(min, max, region_);
+  }
+
+  TypeHandle Context(TypeHandle outer) {
+    return Type::Context(outer, region_);
+  }
+
+  TypeHandle Array1(TypeHandle element) {
+    return Type::Array(element, region_);
+  }
+
+  TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
+    return Type::Function(result, receiver, 0, region_);
+  }
+
+ TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
+    TypeHandle type = Type::Function(result, receiver, 1, region_);
+    type->AsFunction()->InitParameter(0, arg);
+    return type;
+  }
+
+ TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
+    return Type::Function(result, arg1, arg2, region_);
+  }
+
+  TypeHandle Union(TypeHandle t1, TypeHandle t2) {
+    return Type::Union(t1, t2, region_);
+  }
+  TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
+    return Type::Intersect(t1, t2, region_);
+  }
+
+  template<class Type2, class TypeHandle2>
+  TypeHandle Convert(TypeHandle2 t) {
+    return Type::template Convert<Type2>(t, region_);
+  }
+
+  TypeHandle Random() {
+    return types[rng_->NextInt(static_cast<int>(types.size()))];
+  }
+
+  TypeHandle Fuzz(int depth = 4) {
+    switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
+      case 0: {  // bitset
+        #define COUNT_BITSET_TYPES(type, value) + 1
+        int n = 0 PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES);
+        #undef COUNT_BITSET_TYPES
+        // Pick a bunch of named bitsets and return their intersection.
+        TypeHandle result = Type::Any(region_);
+        for (int i = 0, m = 1 + rng_->NextInt(3); i < m; ++i) {
+          int j = rng_->NextInt(n);
+          #define PICK_BITSET_TYPE(type, value) \
+            if (j-- == 0) { \
+              if (!SmiValuesAre31Bits() && \
+                  (Type::type(region_)->Equals(Type::OtherSigned32()) || \
+ Type::type(region_)->Equals(Type::OtherUnsigned31()))) { \
+                /* Hack: Avoid generating those empty bitset types. */ \
+                continue; \
+              } \
+              TypeHandle tmp = Type::Intersect( \
+                  result, Type::type(region_), region_); \
+              if (tmp->Is(Type::None()) && i != 0) { \
+                break; \
+              } else { \
+                result = tmp; \
+                continue; \
+              } \
+            }
+          PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
+          #undef PICK_BITSET_TYPE
+        }
+        return result;
+      }
+      case 1: {  // class
+        int i = rng_->NextInt(static_cast<int>(maps.size()));
+        return Type::Class(maps[i], region_);
+      }
+      case 2: {  // constant
+        int i = rng_->NextInt(static_cast<int>(values.size()));
+        return Type::Constant(values[i], region_);
+      }
+      case 3: {  // range
+        int i = rng_->NextInt(static_cast<int>(integers.size()));
+        int j = rng_->NextInt(static_cast<int>(integers.size()));
+        i::Handle<i::Object> min = integers[i];
+        i::Handle<i::Object> max = integers[j];
+        if (min->Number() > max->Number()) std::swap(min, max);
+        return Type::Range(min, max, region_);
+      }
+      case 4: {  // context
+        int depth = rng_->NextInt(3);
+        TypeHandle type = Type::Internal(region_);
+ for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
+        return type;
+      }
+      case 5: {  // array
+        TypeHandle element = Fuzz(depth / 2);
+        return Type::Array(element, region_);
+      }
+      case 6:
+      case 7: {  // function
+        TypeHandle result = Fuzz(depth / 2);
+        TypeHandle receiver = Fuzz(depth / 2);
+        int arity = rng_->NextInt(3);
+        TypeHandle type = Type::Function(result, receiver, arity, region_);
+        for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
+          TypeHandle parameter = Fuzz(depth / 2);
+          type->AsFunction()->InitParameter(i, parameter);
+        }
+        return type;
+      }
+      default: {  // union
+        int n = rng_->NextInt(10);
+        TypeHandle type = None;
+        for (int i = 0; i < n; ++i) {
+          TypeHandle operand = Fuzz(depth - 1);
+          type = Type::Union(type, operand, region_);
+        }
+        return type;
+      }
+    }
+    UNREACHABLE();
+  }
+
+  Region* region() { return region_; }
+
+ private:
+  Region* region_;
+  v8::base::RandomNumberGenerator* rng_;
+};
+
+
+} }  // namespace v8::internal
+
+#endif
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Classes/Classes.json Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,12 @@
+{
+  "path": ["."],
+  "main": "run.js",
+  "flags": ["--harmony-classes"],
+  "run_count": 5,
+  "units": "score",
+  "results_regexp": "^%s\\-Classes\\(Score\\): (.+)$",
+  "total": true,
+  "tests": [
+    {"name": "Super"}
+  ]
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Classes/run.js     Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,27 @@
+// 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.
+
+
+load('../base.js');
+load('super.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Classes(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+  PrintResult(name, error);
+  success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+                           NotifyError: PrintError });
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Classes/super.js   Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,59 @@
+// 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.
+'use strict';
+
+var SuperBenchmark = new BenchmarkSuite('Super', [100], [
+     new Benchmark('SuperMethodCall', false, false, 0, SuperMethodCall),
+     new Benchmark('SuperGetterCall', false, false, 0, SuperGetterCall),
+     new Benchmark('SuperSetterCall', false, false, 0, SuperSetterCall),
+]);
+
+
+function Base() { }
+Base.prototype = {
+  constructor: Base,
+  get x() {
+    return this._x++;
+  },
+  set x(v) {
+    this._x += v;
+    return this._x;
+  }
+}
+
+Base.prototype.f = function() {
+  return this._x++;
+}.toMethod(Base.prototype);
+
+function Derived() {
+  this._x = 1;
+}
+Derived.prototype = Object.create(Base.prototype);
+Object.setPrototypeOf(Derived, Base);
+
+Derived.prototype.SuperCall = function() {
+  return super.f();
+}.toMethod(Derived.prototype);
+
+Derived.prototype.GetterCall = function() {
+  return super.x;
+}.toMethod(Derived.prototype);
+
+Derived.prototype.SetterCall = function() {
+  return super.x = 5;
+}.toMethod(Derived.prototype);
+
+var derived = new Derived();
+
+function SuperMethodCall() {
+  return derived.SuperCall();
+}
+
+function SuperGetterCall() {
+  return derived.GetterCall();
+}
+
+function SuperSetterCall() {
+  return derived.SetterCall();
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Iterators/Iterators.json Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,11 @@
+{
+  "path": ["."],
+  "main": "run.js",
+  "run_count": 5,
+  "units": "score",
+  "results_regexp": "^%s\\-Iterators\\(Score\\): (.+)$",
+  "total": true,
+  "tests": [
+    {"name": "ForOf"}
+  ]
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Iterators/forof.js Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,94 @@
+// 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.
+
+new BenchmarkSuite('ForOf', [1000], [
+  new Benchmark('ArrayValues', false, false, 0,
+                ForOf, ForOfArraySetup, ForOfTearDown),
+  new Benchmark('ArrayKeys', false, false, 0,
+                ForOf, ForOfArrayKeysSetup, ForOfTearDown),
+  new Benchmark('ArrayEntries', false, false, 0,
+                ForOf, ForOfArrayEntriesSetup, ForOfTearDown),
+  new Benchmark('Uint8Array', false, false, 0,
+                ForOf, ForOfUint8ArraySetup, ForOfTearDown),
+  new Benchmark('Float64Array', false, false, 0,
+                ForOf, ForOfFloat64ArraySetup, ForOfTearDown),
+  new Benchmark('String', false, false, 0,
+                ForOf, ForOfStringSetup, ForOfTearDown),
+]);
+
+
+var iterable;
+var N = 100;
+var expected, result;
+
+
+function ForOfArraySetupHelper(constructor) {
+  iterable = new constructor(N);
+  for (var i = 0; i < N; i++) iterable[i] = i;
+  expected = N - 1;
+}
+
+
+function ForOfArraySetup() {
+  ForOfArraySetupHelper(Array);
+  // Default iterator is values().
+}
+
+
+function ForOfArrayKeysSetup() {
+  ForOfArraySetupHelper(Array);
+  iterable = iterable.keys();
+}
+
+
+function ForOfArrayEntriesSetup() {
+  ForOfArraySetupHelper(Array);
+  iterable = iterable.entries();
+  expected = [N-1, N-1];
+}
+
+
+function ForOfUint8ArraySetup() {
+  ForOfArraySetupHelper(Uint8Array);
+}
+
+
+function ForOfFloat64ArraySetup() {
+  ForOfArraySetupHelper(Float64Array);
+}
+
+
+function ForOfStringSetup() {
+ iterable = "abcdefhijklmnopqrstuvwxyzABCDEFHIJKLMNOPQRSTUVWXYZ0123456789";
+  expected = "9";
+}
+
+
+function Equals(expected, actual) {
+  if (expected === actual) return true;
+  if (typeof expected !== typeof actual) return false;
+  if (typeof expected !== 'object') return false;
+  for (var k of Object.keys(expected)) {
+    if (!(k in actual)) return false;
+    if (!Equals(expected[k], actual[k])) return false;
+  }
+  for (var k of Object.keys(actual)) {
+    if (!(k in expected)) return false;
+  }
+  return true;
+}
+
+function ForOfTearDown() {
+  iterable = null;
+  if (!Equals(expected, result)) {
+    throw new Error("Bad result: " + result);
+  }
+}
+
+
+function ForOf() {
+  for (var x of iterable) {
+    result = x;
+  }
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Iterators/run.js   Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,27 @@
+// 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.
+
+
+load('../base.js');
+load('forof.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Iterators(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+  PrintResult(name, error);
+  success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+                           NotifyError: PrintError });
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/base.js    Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,367 @@
+// 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.
+
+
+// Performance.now is used in latency benchmarks, the fallback is Date.now.
+var performance = performance || {};
+performance.now = (function() {
+  return performance.now       ||
+         performance.mozNow    ||
+         performance.msNow     ||
+         performance.oNow      ||
+         performance.webkitNow ||
+         Date.now;
+})();
+
+// Simple framework for running the benchmark suites and
+// computing a score based on the timing measurements.
+
+
+// A benchmark has a name (string) and a function that will be run to
+// do the performance measurement. The optional setup and tearDown
+// arguments are functions that will be invoked before and after
+// running the benchmark, but the running time of these functions will
+// not be accounted for in the benchmark score.
+function Benchmark(name, doWarmup, doDeterministic, deterministicIterations,
+                   run, setup, tearDown, rmsResult, minIterations) {
+  this.name = name;
+  this.doWarmup = doWarmup;
+  this.doDeterministic = doDeterministic;
+  this.deterministicIterations = deterministicIterations;
+  this.run = run;
+  this.Setup = setup ? setup : function() { };
+  this.TearDown = tearDown ? tearDown : function() { };
+  this.rmsResult = rmsResult ? rmsResult : null;
+  this.minIterations = minIterations ? minIterations : 32;
+}
+
+
+// Benchmark results hold the benchmark and the measured time used to
+// run the benchmark. The benchmark score is computed later once a
+// full benchmark suite has run to completion. If latency is set to 0
+// then there is no latency score for this benchmark.
+function BenchmarkResult(benchmark, time, latency) {
+  this.benchmark = benchmark;
+  this.time = time;
+  this.latency = latency;
+}
+
+
+// Automatically convert results to numbers. Used by the geometric
+// mean computation.
+BenchmarkResult.prototype.valueOf = function() {
+  return this.time;
+}
+
+
+// Suites of benchmarks consist of a name and the set of benchmarks in
+// addition to the reference timing that the final score will be based
+// on. This way, all scores are relative to a reference run and higher
+// scores implies better performance.
+function BenchmarkSuite(name, reference, benchmarks) {
+  this.name = name;
+  this.reference = reference;
+  this.benchmarks = benchmarks;
+  BenchmarkSuite.suites.push(this);
+}
+
+
+// Keep track of all declared benchmark suites.
+BenchmarkSuite.suites = [];
+
+// Scores are not comparable across versions. Bump the version if
+// you're making changes that will affect that scores, e.g. if you add
+// a new benchmark or change an existing one.
+BenchmarkSuite.version = '1';
+
+
+// Defines global benchsuite running mode that overrides benchmark suite
+// behavior. Intended to be set by the benchmark driver. Undefined
+// values here allow a benchmark to define behaviour itself.
+BenchmarkSuite.config = {
+  doWarmup: undefined,
+  doDeterministic: undefined
+};
+
+
+// Override the alert function to throw an exception instead.
+alert = function(s) {
+  throw "Alert called with argument: " + s;
+};
+
+
+// To make the benchmark results predictable, we replace Math.random
+// with a 100% deterministic alternative.
+BenchmarkSuite.ResetRNG = function() {
+  Math.random = (function() {
+    var seed = 49734321;
+    return function() {
+      // Robert Jenkins' 32 bit integer hash function.
+      seed = ((seed + 0x7ed55d16) + (seed << 12))  & 0xffffffff;
+      seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
+      seed = ((seed + 0x165667b1) + (seed << 5))   & 0xffffffff;
+      seed = ((seed + 0xd3a2646c) ^ (seed << 9))   & 0xffffffff;
+      seed = ((seed + 0xfd7046c5) + (seed << 3))   & 0xffffffff;
+      seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
+      return (seed & 0xfffffff) / 0x10000000;
+    };
+  })();
+}
+
+
+// Runs all registered benchmark suites and optionally yields between
+// each individual benchmark to avoid running for too long in the
+// context of browsers. Once done, the final score is reported to the
+// runner.
+BenchmarkSuite.RunSuites = function(runner, skipBenchmarks) {
+ skipBenchmarks = typeof skipBenchmarks === 'undefined' ? [] : skipBenchmarks;
+  var continuation = null;
+  var suites = BenchmarkSuite.suites;
+  var length = suites.length;
+  BenchmarkSuite.scores = [];
+  var index = 0;
+  function RunStep() {
+    while (continuation || index < length) {
+      if (continuation) {
+        continuation = continuation();
+      } else {
+        var suite = suites[index++];
+        if (runner.NotifyStart) runner.NotifyStart(suite.name);
+        if (skipBenchmarks.indexOf(suite.name) > -1) {
+          suite.NotifySkipped(runner);
+        } else {
+          continuation = suite.RunStep(runner);
+        }
+      }
+ if (continuation && typeof window != 'undefined' && window.setTimeout) {
+        window.setTimeout(RunStep, 25);
+        return;
+      }
+    }
+
+    // show final result
+    if (runner.NotifyScore) {
+      var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores);
+      var formatted = BenchmarkSuite.FormatScore(100 * score);
+      runner.NotifyScore(formatted);
+    }
+  }
+  RunStep();
+}
+
+
+// Counts the total number of registered benchmarks. Useful for
+// showing progress as a percentage.
+BenchmarkSuite.CountBenchmarks = function() {
+  var result = 0;
+  var suites = BenchmarkSuite.suites;
+  for (var i = 0; i < suites.length; i++) {
+    result += suites[i].benchmarks.length;
+  }
+  return result;
+}
+
+
+// Computes the geometric mean of a set of numbers.
+BenchmarkSuite.GeometricMean = function(numbers) {
+  var log = 0;
+  for (var i = 0; i < numbers.length; i++) {
+    log += Math.log(numbers[i]);
+  }
+  return Math.pow(Math.E, log / numbers.length);
+}
+
+
+// Computes the geometric mean of a set of throughput time measurements.
+BenchmarkSuite.GeometricMeanTime = function(measurements) {
+  var log = 0;
+  for (var i = 0; i < measurements.length; i++) {
+    log += Math.log(measurements[i].time);
+  }
+  return Math.pow(Math.E, log / measurements.length);
+}
+
+
+// Computes the geometric mean of a set of rms measurements.
+BenchmarkSuite.GeometricMeanLatency = function(measurements) {
+  var log = 0;
+  var hasLatencyResult = false;
+  for (var i = 0; i < measurements.length; i++) {
+    if (measurements[i].latency != 0) {
+      log += Math.log(measurements[i].latency);
+      hasLatencyResult = true;
+    }
+  }
+  if (hasLatencyResult) {
+    return Math.pow(Math.E, log / measurements.length);
+  } else {
+    return 0;
+  }
+}
+
+
+// Converts a score value to a string with at least three significant
+// digits.
+BenchmarkSuite.FormatScore = function(value) {
+  if (value > 100) {
+    return value.toFixed(0);
+  } else {
+    return value.toPrecision(3);
+  }
+}
+
+// Notifies the runner that we're done running a single benchmark in
+// the benchmark suite. This can be useful to report progress.
+BenchmarkSuite.prototype.NotifyStep = function(result) {
+  this.results.push(result);
+ if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name);
+}
+
+
+// Notifies the runner that we're done with running a suite and that
+// we have a result which can be reported to the user if needed.
+BenchmarkSuite.prototype.NotifyResult = function() {
+  var mean = BenchmarkSuite.GeometricMeanTime(this.results);
+  var score = this.reference[0] / mean;
+  BenchmarkSuite.scores.push(score);
+  if (this.runner.NotifyResult) {
+    var formatted = BenchmarkSuite.FormatScore(100 * score);
+    this.runner.NotifyResult(this.name, formatted);
+  }
+  if (this.reference.length == 2) {
+    var meanLatency = BenchmarkSuite.GeometricMeanLatency(this.results);
+    if (meanLatency != 0) {
+      var scoreLatency = this.reference[1] / meanLatency;
+      BenchmarkSuite.scores.push(scoreLatency);
+      if (this.runner.NotifyResult) {
+ var formattedLatency = BenchmarkSuite.FormatScore(100 * scoreLatency)
+        this.runner.NotifyResult(this.name + "Latency", formattedLatency);
+      }
+    }
+  }
+}
+
+
+BenchmarkSuite.prototype.NotifySkipped = function(runner) {
+  BenchmarkSuite.scores.push(1);  // push default reference score.
+  if (runner.NotifyResult) {
+    runner.NotifyResult(this.name, "Skipped");
+  }
+}
+
+
+// Notifies the runner that running a benchmark resulted in an error.
+BenchmarkSuite.prototype.NotifyError = function(error) {
+  if (this.runner.NotifyError) {
+    this.runner.NotifyError(this.name, error);
+  }
+  if (this.runner.NotifyStep) {
+    this.runner.NotifyStep(this.name);
+  }
+}
+
+
+// Runs a single benchmark for at least a second and computes the
+// average time it takes to run a single iteration.
+BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
+  var config = BenchmarkSuite.config;
+  var doWarmup = config.doWarmup !== undefined
+                 ? config.doWarmup
+                 : benchmark.doWarmup;
+  var doDeterministic = config.doDeterministic !== undefined
+                        ? config.doDeterministic
+                        : benchmark.doDeterministic;
+
+  function Measure(data) {
+    var elapsed = 0;
+    var start = new Date();
+
+  // Run either for 1 second or for the number of iterations specified
+  // by minIterations, depending on the config flag doDeterministic.
+    for (var i = 0; (doDeterministic ?
+      i<benchmark.deterministicIterations : elapsed < 1000); i++) {
+      benchmark.run();
+      elapsed = new Date() - start;
+    }
+    if (data != null) {
+      data.runs += i;
+      data.elapsed += elapsed;
+    }
+  }
+
+  // Sets up data in order to skip or not the warmup phase.
+  if (!doWarmup && data == null) {
+    data = { runs: 0, elapsed: 0 };
+  }
+
+  if (data == null) {
+    Measure(null);
+    return { runs: 0, elapsed: 0 };
+  } else {
+    Measure(data);
+    // If we've run too few iterations, we continue for another second.
+    if (data.runs < benchmark.minIterations) return data;
+    var usec = (data.elapsed * 1000) / data.runs;
+    var rms = (benchmark.rmsResult != null) ? benchmark.rmsResult() : 0;
+    this.NotifyStep(new BenchmarkResult(benchmark, usec, rms));
+    return null;
+  }
+}
+
+
+// This function starts running a suite, but stops between each
+// individual benchmark in the suite and returns a continuation
+// function which can be invoked to run the next benchmark. Once the
+// last benchmark has been executed, null is returned.
+BenchmarkSuite.prototype.RunStep = function(runner) {
+  BenchmarkSuite.ResetRNG();
+  this.results = [];
+  this.runner = runner;
+  var length = this.benchmarks.length;
+  var index = 0;
+  var suite = this;
+  var data;
+
+  // Run the setup, the actual benchmark, and the tear down in three
+  // separate steps to allow the framework to yield between any of the
+  // steps.
+
+  function RunNextSetup() {
+    if (index < length) {
+      try {
+        suite.benchmarks[index].Setup();
+      } catch (e) {
+        suite.NotifyError(e);
+        return null;
+      }
+      return RunNextBenchmark;
+    }
+    suite.NotifyResult();
+    return null;
+  }
+
+  function RunNextBenchmark() {
+    try {
+      data = suite.RunSingleBenchmark(suite.benchmarks[index], data);
+    } catch (e) {
+      suite.NotifyError(e);
+      return null;
+    }
+    // If data is null, we're done with this benchmark.
+    return (data == null) ? RunNextTearDown : RunNextBenchmark();
+  }
+
+  function RunNextTearDown() {
+    try {
+      suite.benchmarks[index++].TearDown();
+    } catch (e) {
+      suite.NotifyError(e);
+      return null;
+    }
+    return RunNextSetup;
+  }
+
+  // Start out running the setup.
+  return RunNextSetup();
+}
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/asm/do-while-false.js   Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,78 @@
+// 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 Module() {
+  "use asm";
+
+  function d0() {
+    do { } while(false);
+    return 110;
+  }
+
+  function d1() {
+    do { return 111; } while(false);
+    return 112;
+  }
+
+  function d2() {
+    do { break; } while(false);
+    return 113;
+  }
+
+  function d3(a) {
+    a = a | 0;
+    do { if (a) return 114; } while(false);
+    return 115;
+  }
+
+  function d4(a) {
+    a = a | 0;
+    do { if (a) return 116; else break; } while(false);
+    return 117;
+  }
+
+  function d5(a) {
+    a = a | 0;
+    do { if (a) return 118; } while(false);
+    return 119;
+  }
+
+  function d6(a) {
+    a = a | 0;
+    do {
+      if (a == 0) return 120;
+      if (a == 1) break;
+      if (a == 2) return 122;
+      if (a == 3) continue;
+      if (a == 4) return 124;
+    } while(false);
+    return 125;
+  }
+
+  return {d0: d0, d1: d1, d2: d2, d3: d3, d4: d4, d5: d5, d6: d6};
+}
+
+var m = Module();
+
+assertEquals(110, m.d0());
+
+assertEquals(111, m.d1());
+
+assertEquals(113, m.d2());
+
+assertEquals(114, m.d3(1));
+assertEquals(115, m.d3(0));
+
+assertEquals(116, m.d4(1));
+assertEquals(117, m.d4(0));
+
+assertEquals(118, m.d5(1));
+assertEquals(119, m.d5(0));
+
+assertEquals(120, m.d6(0));
+assertEquals(125, m.d6(1));
+assertEquals(122, m.d6(2));
+assertEquals(125, m.d6(3));
+assertEquals(124, m.d6(4));
+assertEquals(125, m.d6(5));
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/asm/if-folding.js       Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,100 @@
+// 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 Module() {
+  "use asm";
+
+  function if0() {
+    if (0) return 11;
+    return 12;
+  }
+
+  function if1() {
+    if (1) return 13;
+    return 14;
+  }
+
+  function if2() {
+    if (0) return 15;
+    else return 16;
+  }
+
+  function if3() {
+    if (1) return 17;
+    else return 18;
+  }
+
+  function if4() {
+    return 1 ? 19 : 20;
+  }
+
+  function if5() {
+    return 0 ? 21 : 22;
+  }
+
+  function if6() {
+    var x = 0 ? 23 : 24;
+    return x;
+  }
+
+  function if7() {
+    if (0) { var x = 0 ? 25 : 26; }
+    else { var x = 0 ? 27 : 28; }
+    return x;
+  }
+
+  function if8() {
+    if (0) {
+      if (0) { var x = 0 ? 29 : 30; }
+      else { var x = 0 ? 31 : 32; }
+    } else {
+      if (0) { var x = 0 ? 33 : 34; }
+      else { var x = 0 ? 35 : 36; }
+    }
+    return x;
+  }
+
+ return {if0: if0, if1: if1, if2: if2, if3: if3, if4: if4, if5: if5, if6: if6, if7: if7, if8: if8 };
+}
+
+var m = Module();
+assertEquals(12, m.if0());
+assertEquals(13, m.if1());
+assertEquals(16, m.if2());
+assertEquals(17, m.if3());
+assertEquals(19, m.if4());
+assertEquals(22, m.if5());
+assertEquals(24, m.if6());
+assertEquals(28, m.if7());
+assertEquals(36, m.if8());
+
+
+function Spec(a,b,c) {
+  "use asm";
+
+  var xx = a | 0;
+  var yy = b | 0;
+  var zz = c | 0;
+
+  function f() {
+    if (xx) {
+      if (yy) { var x = zz ? 29 : 30; }
+      else { var x = zz ? 31 : 32; }
+    } else {
+      if (yy) { var x = zz ? 33 : 34; }
+      else { var x = zz ? 35 : 36; }
+    }
+    return x;
+  }
+  return {f: f};
+}
+
+assertEquals(36, Spec(0,0,0).f());
+assertEquals(35, Spec(0,0,1).f());
+assertEquals(34, Spec(0,1,0).f());
+assertEquals(33, Spec(0,1,1).f());
+assertEquals(32, Spec(1,0,0).f());
+assertEquals(31, Spec(1,0,1).f());
+assertEquals(30, Spec(1,1,0).f());
+assertEquals(29, Spec(1,1,1).f());
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/asm/if-reduction.js     Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,111 @@
+// 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 Module() {
+  "use asm";
+
+  function if0() {
+    var x = 0 ? 11 : 12;
+    return (x == 11) | 0;
+  }
+
+  function if1() {
+    var x = 1 ? 13 : 14;
+    return (x == 13) | 0;
+  }
+
+  function if2() {
+    var x = 0 ? 15 : 16;
+    return (x != 15) | 0;
+  }
+
+  function if3() {
+    var x = 1 ? 17 : 18;
+    return (x != 17) | 0;
+  }
+
+  function if4() {
+    var x = 0 ? 19 : 20;
+    var y = (x == 19) ? 21 : 22;
+    return y;
+  }
+
+  function if5() {
+    var x = 1 ? 23 : 24;
+    var y = (x == 23) ? 25 : 26;
+    return y;
+  }
+
+  function if6() {
+    var x = 0 ? 27 : 28;
+    var y = (x == 27) ? 29 : 30;
+    var z = (y == 29) ? 31 : 32;
+    return z;
+  }
+
+  function if7() {
+    var x = 1 ? 33 : 34;
+    var y = (x == 33) ? 35 : 36;
+    var z = (y == 35) ? 37 : 38;
+    var w = (z == 37) ? 39 : 40;
+    return w;
+  }
+
+  function if8() {
+    if (0) {
+      var x = 0 ? 43 : 44;
+      var y = (x == 43) ? 45 : 46;
+      var z = (y == 45) ? 47 : 48;
+      var w = (z == 47) ? 49 : 50;
+    } else {
+      var x = 1 ? 53 : 54;
+      var y = (x == 53) ? 55 : 56;
+      var z = (y == 55) ? 57 : 58;
+      var w = (z == 57) ? 59 : 60;
+    }
+    return w;
+  }
+
+ return {if0: if0, if1: if1, if2: if2, if3: if3, if4: if4, if5: if5, if6: if6, if7: if7, if8: if8 };
+}
+
+var m = Module();
+assertEquals(0, m.if0());
+assertEquals(1, m.if1());
+assertEquals(1, m.if2());
+assertEquals(0, m.if3());
+assertEquals(22, m.if4());
+assertEquals(25, m.if5());
+assertEquals(32, m.if6());
+assertEquals(39, m.if7());
+assertEquals(59, m.if8());
+
+
+function Spec(a,b) {
+  "use asm";
+
+  var xx = a | 0;
+  var yy = b | 0;
+
+  function f() {
+    if (xx) {
+      var x = yy ? 43 : 44;
+      var y = (x == 43) ? 45 : 46;
+      var z = (y == 45) ? 47 : 48;
+      var w = (z == 47) ? 49 : 50;
+    } else {
+      var x = yy ? 53 : 54;
+      var y = (x == 53) ? 55 : 56;
+      var z = (y == 55) ? 57 : 58;
+      var w = (z == 57) ? 59 : 60;
+    }
+    return w;
+  }
+  return {f: f};
+}
+
+assertEquals(60, Spec(0,0).f());
+assertEquals(59, Spec(0,1).f());
+assertEquals(50, Spec(1,0).f());
+assertEquals(49, Spec(1,1).f());
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/asm/infinite-loops-taken.js Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,41 @@
+// 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 error = "error";
+function counter(x) {
+  return (function() { if (x-- == 0) throw error;});
+}
+
+function Module() {
+  "use asm";
+
+  function w0(f) {
+    while (1) f();
+    return 108;
+  }
+
+  function w1(f) {
+    if (1) while (1) f();
+    return 109;
+  }
+
+  function w2(f) {
+    if (1) while (1) f();
+    else while (1) f();
+    return 110;
+  }
+
+  function w3(f) {
+    if (0) while (1) f();
+    return 111;
+  }
+
+  return { w0: w0, w1: w1, w2: w2, w3: w3 };
+}
+
+var m = Module();
+assertThrows(function() { m.w0(counter(5)) }, error);
+assertThrows(function() { m.w1(counter(5)) }, error);
+assertThrows(function() { m.w2(counter(5)) }, error);
+assertEquals(111, m.w3(counter(5)));
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/asm/infinite-loops.js   Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,53 @@
+// 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 Module() {
+  "use asm";
+
+  function w0(a) {
+    a = a | 0;
+    if (a) while (1);
+    return 42;
+  }
+
+  function w1(a) {
+    a = a | 0;
+    while (1) return 42;
+    return 106;
+  }
+
+  function d0(a) {
+    a = a | 0;
+    if (a) do ; while(1);
+    return 42;
+  }
+
+  function d1(a) {
+    a = a | 0;
+    do return 42; while(1);
+    return 107;
+  }
+
+  function f0(a) {
+    a = a | 0;
+    if (a) for (;;) ;
+    return 42;
+  }
+
+  function f1(a) {
+    a = a | 0;
+    for(;;) return 42;
+    return 108;
+  }
+
+  return { w0: w0, w1: w1, d0: d0, d1: d1, f0: f0, f1: f1 };
+}
+
+var m = Module();
+assertEquals(42, m.w0(0));
+assertEquals(42, m.w1(0));
+assertEquals(42, m.d0(0));
+assertEquals(42, m.d1(0));
+assertEquals(42, m.f0(0));
+assertEquals(42, m.f1(0));
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/asm/int32array-constant-key.js Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,32 @@
+// 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 Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Int32Array(heap);
+  function load0() {
+    return MEM32[0];
+  }
+  function load4() {
+    return MEM32[4];
+  }
+  function store0(v) {
+    MEM32[0] = v;
+  }
+  function store4(v) {
+    MEM32[4] = v;
+  }
+  return { load0: load0, store0: store0, load4: load4, store4: store4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(4));
+
+assertEquals(0, m.load0());
+assertEquals(undefined, m.load4());
+m.store0(0x12345678);
+assertEquals(0x12345678, m.load0());
+assertEquals(undefined, m.load4());
+m.store4(43);
+assertEquals(0x12345678, m.load0());
+assertEquals(undefined, m.load4());
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/asm/word32and.js        Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,29 @@
+// 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 stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+function Word32And(rhs) {
+  var name = "and_0x" + Number(rhs).toString(16);
+  var m = eval("function Module(stdlib, foreign, heap) {\n"
+      + " \"use asm\";\n"
+      + " function " + name + "(lhs) {\n"
+      + "  return (lhs | 0) & 0x" + Number(rhs).toString(16) + ";\n"
+      + " }\n"
+      + " return { f: " + name + "}\n"
+      + "}; Module");
+  return m(stdlib, foreign, heap).f;
+}
+
+var masks = [0xffffffff, 0xf0f0f0f0, 0x80ffffff, 0x07f77f0f, 0xdeadbeef,
+             0x0fffff00, 0x0ff0, 0xff, 0x00];
+for (var i in masks) {
+  var rhs = masks[i];
+  var and = Word32And(rhs);
+  for (var lhs = -2147483648; lhs < 2147483648; lhs += 3999773) {
+    assertEquals(lhs & rhs, and(lhs));
+  }
+}
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-419663.js Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,37 @@
+// Copyright 2012 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.
+
+// Flags: --expose-debug-as debug
+
+var o = {
+  f: function(x) {
+    var a = x + 1;
+    o = 1;
+  }
+}
+
+function sentinel() {}
+
+var Debug = debug.Debug;
+
+Debug.setListener(function() {});
+
+var script = Debug.findScript(sentinel);
+
+// Used in Debug.setScriptBreakPointById.
+var p = Debug.findScriptSourcePosition(script, 9, 0);
+var q = Debug.setBreakPointByScriptIdAndPosition(script.id, p).actual_position; +var r = Debug.setBreakPointByScriptIdAndPosition(script.id, q).actual_position;
+
+assertEquals(q, r);
+
+function assertLocation(p, l, c) {
+  var location = script.locationFromPosition(p, false);
+  assertEquals(l, location.line);
+  assertEquals(c, location.column);
+}
+
+assertLocation(p, 9, 0);
+assertLocation(q, 9, 4);
+assertLocation(r, 9, 4);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/unused-context-in-with.js Fri Oct 17 20:38:26 2014 UTC
@@ -0,0 +1,13 @@
+// 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 x = 1;
+function foo(object) {
+  with(object) {
+    x;
+  }
+  return 100;
+}
+
+assertEquals(100,foo("str"));
=======================================
--- /trunk/test/js-perf-test/Collections/base.js Fri Oct 10 00:05:16 2014 UTC
+++ /dev/null
@@ -1,367 +0,0 @@
-// 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.
-
-
-// Performance.now is used in latency benchmarks, the fallback is Date.now.
-var performance = performance || {};
-performance.now = (function() {
-  return performance.now       ||
-         performance.mozNow    ||
-         performance.msNow     ||
-         performance.oNow      ||
-         performance.webkitNow ||
-         Date.now;
-})();
-
-// Simple framework for running the benchmark suites and
-// computing a score based on the timing measurements.
-
-
-// A benchmark has a name (string) and a function that will be run to
-// do the performance measurement. The optional setup and tearDown
-// arguments are functions that will be invoked before and after
-// running the benchmark, but the running time of these functions will
-// not be accounted for in the benchmark score.
-function Benchmark(name, doWarmup, doDeterministic, deterministicIterations,
-                   run, setup, tearDown, rmsResult, minIterations) {
-  this.name = name;
-  this.doWarmup = doWarmup;
-  this.doDeterministic = doDeterministic;
-  this.deterministicIterations = deterministicIterations;
-  this.run = run;
-  this.Setup = setup ? setup : function() { };
-  this.TearDown = tearDown ? tearDown : function() { };
-  this.rmsResult = rmsResult ? rmsResult : null;
-  this.minIterations = minIterations ? minIterations : 32;
-}
-
-
-// Benchmark results hold the benchmark and the measured time used to
-// run the benchmark. The benchmark score is computed later once a
-// full benchmark suite has run to completion. If latency is set to 0
-// then there is no latency score for this benchmark.
-function BenchmarkResult(benchmark, time, latency) {
-  this.benchmark = benchmark;
-  this.time = time;
-  this.latency = latency;
-}
-
-
-// Automatically convert results to numbers. Used by the geometric
-// mean computation.
-BenchmarkResult.prototype.valueOf = function() {
-  return this.time;
-}
-
-
-// Suites of benchmarks consist of a name and the set of benchmarks in
-// addition to the reference timing that the final score will be based
-// on. This way, all scores are relative to a reference run and higher
-// scores implies better performance.
-function BenchmarkSuite(name, reference, benchmarks) {
-  this.name = name;
-  this.reference = reference;
-  this.benchmarks = benchmarks;
-  BenchmarkSuite.suites.push(this);
-}
-
-
-// Keep track of all declared benchmark suites.
-BenchmarkSuite.suites = [];
-
-// Scores are not comparable across versions. Bump the version if
-// you're making changes that will affect that scores, e.g. if you add
-// a new benchmark or change an existing one.
-BenchmarkSuite.version = '1';
-
-
-// Defines global benchsuite running mode that overrides benchmark suite
-// behavior. Intended to be set by the benchmark driver. Undefined
-// values here allow a benchmark to define behaviour itself.
-BenchmarkSuite.config = {
-  doWarmup: undefined,
-  doDeterministic: undefined
-};
-
-
-// Override the alert function to throw an exception instead.
-alert = function(s) {
-  throw "Alert called with argument: " + s;
-};
-
-
-// To make the benchmark results predictable, we replace Math.random
-// with a 100% deterministic alternative.
-BenchmarkSuite.ResetRNG = function() {
-  Math.random = (function() {
-    var seed = 49734321;
-    return function() {
-      // Robert Jenkins' 32 bit integer hash function.
-      seed = ((seed + 0x7ed55d16) + (seed << 12))  & 0xffffffff;
-      seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
-      seed = ((seed + 0x165667b1) + (seed << 5))   & 0xffffffff;
-      seed = ((seed + 0xd3a2646c) ^ (seed << 9))   & 0xffffffff;
-      seed = ((seed + 0xfd7046c5) + (seed << 3))   & 0xffffffff;
-      seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
-      return (seed & 0xfffffff) / 0x10000000;
-    };
-  })();
-}
-
-
-// Runs all registered benchmark suites and optionally yields between
-// each individual benchmark to avoid running for too long in the
-// context of browsers. Once done, the final score is reported to the
-// runner.
-BenchmarkSuite.RunSuites = function(runner, skipBenchmarks) {
- skipBenchmarks = typeof skipBenchmarks === 'undefined' ? [] : skipBenchmarks;
-  var continuation = null;
-  var suites = BenchmarkSuite.suites;
-  var length = suites.length;
-  BenchmarkSuite.scores = [];
-  var index = 0;
-  function RunStep() {
-    while (continuation || index < length) {
-      if (continuation) {
-        continuation = continuation();
-      } else {
-        var suite = suites[index++];
-        if (runner.NotifyStart) runner.NotifyStart(suite.name);
-        if (skipBenchmarks.indexOf(suite.name) > -1) {
-          suite.NotifySkipped(runner);
-        } else {
-          continuation = suite.RunStep(runner);
-        }
-      }
- if (continuation && typeof window != 'undefined' && window.setTimeout) {
-        window.setTimeout(RunStep, 25);
-        return;
-      }
-    }
-
-    // show final result
-    if (runner.NotifyScore) {
-      var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores);
-      var formatted = BenchmarkSuite.FormatScore(100 * score);
-      runner.NotifyScore(formatted);
-    }
-  }
-  RunStep();
-}
-
-
-// Counts the total number of registered benchmarks. Useful for
-// showing progress as a percentage.
-BenchmarkSuite.CountBenchmarks = function() {
-  var result = 0;
-  var suites = BenchmarkSuite.suites;
-  for (var i = 0; i < suites.length; i++) {
-    result += suites[i].benchmarks.length;
-  }
-  return result;
-}
-
-
-// Computes the geometric mean of a set of numbers.
-BenchmarkSuite.GeometricMean = function(numbers) {
-  var log = 0;
-  for (var i = 0; i < numbers.length; i++) {
-    log += Math.log(numbers[i]);
-  }
-  return Math.pow(Math.E, log / numbers.length);
-}
-
-
-// Computes the geometric mean of a set of throughput time measurements.
-BenchmarkSuite.GeometricMeanTime = function(measurements) {
-  var log = 0;
-  for (var i = 0; i < measurements.length; i++) {
-    log += Math.log(measurements[i].time);
-  }
-  return Math.pow(Math.E, log / measurements.length);
-}
-
-
-// Computes the geometric mean of a set of rms measurements.
-BenchmarkSuite.GeometricMeanLatency = function(measurements) {
-  var log = 0;
-  var hasLatencyResult = false;
-  for (var i = 0; i < measurements.length; i++) {
-    if (measurements[i].latency != 0) {
-      log += Math.log(measurements[i].latency);
-      hasLatencyResult = true;
-    }
-  }
-  if (hasLatencyResult) {
-    return Math.pow(Math.E, log / measurements.length);
-  } else {
-    return 0;
-  }
-}
-
-
-// Converts a score value to a string with at least three significant
-// digits.
-BenchmarkSuite.FormatScore = function(value) {
-  if (value > 100) {
-    return value.toFixed(0);
-  } else {
-    return value.toPrecision(3);
-  }
-}
-
-// Notifies the runner that we're done running a single benchmark in
-// the benchmark suite. This can be useful to report progress.
-BenchmarkSuite.prototype.NotifyStep = function(result) {
-  this.results.push(result);
- if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name);
-}
-
-
-// Notifies the runner that we're done with running a suite and that
-// we have a result which can be reported to the user if needed.
-BenchmarkSuite.prototype.NotifyResult = function() {
-  var mean = BenchmarkSuite.GeometricMeanTime(this.results);
-  var score = this.reference[0] / mean;
-  BenchmarkSuite.scores.push(score);
-  if (this.runner.NotifyResult) {
-    var formatted = BenchmarkSuite.FormatScore(100 * score);
-    this.runner.NotifyResult(this.name, formatted);
-  }
-  if (this.reference.length == 2) {
-    var meanLatency = BenchmarkSuite.GeometricMeanLatency(this.results);
-    if (meanLatency != 0) {
-      var scoreLatency = this.reference[1] / meanLatency;
-      BenchmarkSuite.scores.push(scoreLatency);
-      if (this.runner.NotifyResult) {
- var formattedLatency = BenchmarkSuite.FormatScore(100 * scoreLatency)
-        this.runner.NotifyResult(this.name + "Latency", formattedLatency);
-      }
-    }
-  }
-}
-
-
-BenchmarkSuite.prototype.NotifySkipped = function(runner) {
-  BenchmarkSuite.scores.push(1);  // push default reference score.
-  if (runner.NotifyResult) {
-    runner.NotifyResult(this.name, "Skipped");
-  }
-}
-
-
-// Notifies the runner that running a benchmark resulted in an error.
-BenchmarkSuite.prototype.NotifyError = function(error) {
-  if (this.runner.NotifyError) {
-    this.runner.NotifyError(this.name, error);
-  }
-  if (this.runner.NotifyStep) {
-    this.runner.NotifyStep(this.name);
-  }
-}
-
-
-// Runs a single benchmark for at least a second and computes the
-// average time it takes to run a single iteration.
-BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
-  var config = BenchmarkSuite.config;
-  var doWarmup = config.doWarmup !== undefined
-                 ? config.doWarmup
-                 : benchmark.doWarmup;
-  var doDeterministic = config.doDeterministic !== undefined
-                        ? config.doDeterministic
-                        : benchmark.doDeterministic;
-
-  function Measure(data) {
-    var elapsed = 0;
-    var start = new Date();
-
-  // Run either for 1 second or for the number of iterations specified
-  // by minIterations, depending on the config flag doDeterministic.
-    for (var i = 0; (doDeterministic ?
-      i<benchmark.deterministicIterations : elapsed < 1000); i++) {
-      benchmark.run();
-      elapsed = new Date() - start;
-    }
-    if (data != null) {
-      data.runs += i;
-      data.elapsed += elapsed;
-    }
-  }
-
-  // Sets up data in order to skip or not the warmup phase.
-  if (!doWarmup && data == null) {
-    data = { runs: 0, elapsed: 0 };
-  }
-
-  if (data == null) {
-    Measure(null);
-    return { runs: 0, elapsed: 0 };
-  } else {
-    Measure(data);
-    // If we've run too few iterations, we continue for another second.
-    if (data.runs < benchmark.minIterations) return data;
-    var usec = (data.elapsed * 1000) / data.runs;
-    var rms = (benchmark.rmsResult != null) ? benchmark.rmsResult() : 0;
-    this.NotifyStep(new BenchmarkResult(benchmark, usec, rms));
-    return null;
-  }
-}
-
-
-// This function starts running a suite, but stops between each
-// individual benchmark in the suite and returns a continuation
-// function which can be invoked to run the next benchmark. Once the
-// last benchmark has been executed, null is returned.
-BenchmarkSuite.prototype.RunStep = function(runner) {
-  BenchmarkSuite.ResetRNG();
-  this.results = [];
-  this.runner = runner;
-  var length = this.benchmarks.length;
-  var index = 0;
-  var suite = this;
-  var data;
-
-  // Run the setup, the actual benchmark, and the tear down in three
-  // separate steps to allow the framework to yield between any of the
-  // steps.
-
-  function RunNextSetup() {
-    if (index < length) {
-      try {
-        suite.benchmarks[index].Setup();
-      } catch (e) {
-        suite.NotifyError(e);
-        return null;
-      }
-      return RunNextBenchmark;
-    }
-    suite.NotifyResult();
-    return null;
-  }
-
-  function RunNextBenchmark() {
-    try {
-      data = suite.RunSingleBenchmark(suite.benchmarks[index], data);
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    // If data is null, we're done with this benchmark.
-    return (data == null) ? RunNextTearDown : RunNextBenchmark();
-  }
-
-  function RunNextTearDown() {
-    try {
-      suite.benchmarks[index++].TearDown();
-    } catch (e) {
-      suite.NotifyError(e);
-      return null;
-    }
-    return RunNextSetup;
-  }
-
-  // Start out running the setup.
-  return RunNextSetup();
-}
=======================================
--- /trunk/AUTHORS      Fri Oct 10 00:05:16 2014 UTC
+++ /trunk/AUTHORS      Fri Oct 17 20:38:26 2014 UTC
@@ -39,6 +39,7 @@
 Filipe David Manana <[email protected]>
 Haitao Feng <[email protected]>
 Ioseb Dzmanashvili <[email protected]>
+Isiah Meadows <[email protected]>
 Jacob Bramley <[email protected]>
 Jan de Mooij <[email protected]>
 Jay Freeman <[email protected]>
=======================================
--- /trunk/BUILD.gn     Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/BUILD.gn     Fri Oct 17 20:38:26 2014 UTC
@@ -487,6 +487,8 @@
     "src/compiler/common-operator.h",
     "src/compiler/control-builders.cc",
     "src/compiler/control-builders.h",
+    "src/compiler/control-reducer.cc",
+    "src/compiler/control-reducer.h",
     "src/compiler/frame.h",
     "src/compiler/gap-resolver.cc",
     "src/compiler/gap-resolver.h",
=======================================
--- /trunk/ChangeLog    Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/ChangeLog    Fri Oct 17 20:38:26 2014 UTC
@@ -1,3 +1,15 @@
+2014-10-17: Version 3.30.13
+
+ Don't expose Array.prototype.values as it breaks webcompat (Chromium
+        issue 409858).
+
+        Fix break location calculation (Chromium issue 419663).
+
+        Enable libstdc++ debug mode in debug builds (issue 3638).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-10-17: Version 3.30.12

         Implement .forEach() on typed arrays (issue 3578).
=======================================
--- /trunk/build/standalone.gypi        Thu Oct  9 00:05:16 2014 UTC
+++ /trunk/build/standalone.gypi        Fri Oct 17 20:38:26 2014 UTC
@@ -136,6 +136,14 @@
     'configurations': {
       'DebugBaseCommon': {
         'cflags': [ '-g', '-O0' ],
+        'conditions': [
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
+            OS=="qnx"', {
+            'defines': [
+              '_GLIBCXX_DEBUG'
+            ],
+          }],
+        ],
       },
       'Optdebug': {
         'inherit_from': [ 'DebugBaseCommon', 'DebugBase2' ],
=======================================
--- /trunk/include/v8.h Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/include/v8.h Fri Oct 17 20:38:26 2014 UTC
@@ -5295,6 +5295,13 @@
    */
   static void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor);

+  /**
+ * Iterates through all the persistent handles in isolate's heap that have
+   * class_ids.
+   */
+  static void VisitHandlesWithClassIds(
+      Isolate* isolate, PersistentHandleVisitor* visitor);
+
   /**
* Iterates through all the persistent handles in the current isolate's heap * that have class_ids and are candidates to be marked as partially dependent
=======================================
--- /trunk/src/api.cc   Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/src/api.cc   Fri Oct 17 20:38:26 2014 UTC
@@ -5113,6 +5113,16 @@
  private:
   PersistentHandleVisitor* visitor_;
 };
+
+
+void v8::V8::VisitHandlesWithClassIds(v8::Isolate* exported_isolate,
+    PersistentHandleVisitor* visitor) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
+  i::DisallowHeapAllocation no_allocation;
+
+  VisitorAdapter visitor_adapter(visitor);
+  isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
+}


 void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
@@ -6089,79 +6099,23 @@
   return static_cast<size_t>(obj->length()->Number());
 }

-
-static inline void SetupArrayBufferView(
-    i::Isolate* isolate,
-    i::Handle<i::JSArrayBufferView> obj,
-    i::Handle<i::JSArrayBuffer> buffer,
-    size_t byte_offset,
-    size_t byte_length) {
-  DCHECK(byte_offset + byte_length <=
-         static_cast<size_t>(buffer->byte_length()->Number()));
-
-  obj->set_buffer(*buffer);
-
-  obj->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*obj);
-
-  i::Handle<i::Object> byte_offset_object =
-      isolate->factory()->NewNumberFromSize(byte_offset);
-  obj->set_byte_offset(*byte_offset_object);
-
-  i::Handle<i::Object> byte_length_object =
-      isolate->factory()->NewNumberFromSize(byte_length);
-  obj->set_byte_length(*byte_length_object);
-}
-
-template<typename ElementType,
-         ExternalArrayType array_type,
-         i::ElementsKind elements_kind>
-i::Handle<i::JSTypedArray> NewTypedArray(
-    i::Isolate* isolate,
-    Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
-  i::Handle<i::JSTypedArray> obj =
-      isolate->factory()->NewJSTypedArray(array_type);
-  i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
-
-  DCHECK(byte_offset % sizeof(ElementType) == 0);
-
- CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
-  CHECK(length <= static_cast<size_t>(i::Smi::kMaxValue));
-  size_t byte_length = length * sizeof(ElementType);
-  SetupArrayBufferView(
-      isolate, obj, buffer, byte_offset, byte_length);
-
-  i::Handle<i::Object> length_object =
-      isolate->factory()->NewNumberFromSize(length);
-  obj->set_length(*length_object);
-
-  i::Handle<i::ExternalArray> elements =
-      isolate->factory()->NewExternalArray(
-          static_cast<int>(length), array_type,
-          static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
-  i::Handle<i::Map> map =
-      i::JSObject::GetElementsTransitionMap(obj, elements_kind);
-  i::JSObject::SetMapAndElements(obj, map, elements);
-  return obj;
-}
-

#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \ Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \ - size_t byte_offset, size_t length) { \ + size_t byte_offset, size_t length) { \ i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \ LOG_API(isolate, \ - "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \ + "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \ ENTER_V8(isolate); \ if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \ - "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \ - "length exceeds max allowed value")) { \ - return Local<Type##Array>(); \ + "v8::" #Type \ + "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \ + "length exceeds max allowed value")) { \ + return Local<Type##Array>(); \ } \ - i::Handle<i::JSTypedArray> obj = \ - NewTypedArray<ctype, v8::kExternal##Type##Array, \ - i::EXTERNAL_##TYPE##_ELEMENTS>( \ - isolate, array_buffer, byte_offset, length); \ + i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \ + i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \ + v8::kExternal##Type##Array, buffer, byte_offset, length); \ return Utils::ToLocal##Type##Array(obj); \
   }

@@ -6175,9 +6129,8 @@
   i::Isolate* isolate = buffer->GetIsolate();
   LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
   ENTER_V8(isolate);
-  i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
-  SetupArrayBufferView(
-      isolate, obj, buffer, byte_offset, byte_length);
+  i::Handle<i::JSDataView> obj =
+      isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
   return Utils::ToLocal(obj);
 }

@@ -6704,8 +6657,8 @@
 void Isolate::GetStackSample(const RegisterState& state, void** frames,
size_t frames_limit, SampleInfo* sample_info) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  i::TickSample::GetStackSample(isolate, state, frames, frames_limit,
-                                sample_info);
+ i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame,
+                                frames, frames_limit, sample_info);
 }


=======================================
--- /trunk/src/arm/code-stubs-arm.cc    Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/src/arm/code-stubs-arm.cc    Fri Oct 17 20:38:26 2014 UTC
@@ -3167,8 +3167,8 @@
   // r2: length
   // r3: from index (untagged)
   __ SmiTag(r3, r3);
-  StringCharAtGenerator generator(
- r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER); + StringCharAtGenerator generator(r0, r3, r2, r0, &runtime, &runtime, &runtime, + STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ Drop(3);
   __ Ret();
=======================================
--- /trunk/src/arm/disasm-arm.cc        Wed Oct 15 00:05:09 2014 UTC
+++ /trunk/src/arm/disasm-arm.cc        Fri Oct 17 20:38:26 2014 UTC
@@ -148,7 +148,7 @@

// These condition names are defined in a way to match the native disassembler
 // formatting. See for example the command "objdump -d <binary file>".
-static const char* cond_names[kNumberOfConditions] = {
+static const char* const cond_names[kNumberOfConditions] = {
   "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
   "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
 };
=======================================
--- /trunk/src/arm/full-codegen-arm.cc  Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/src/arm/full-codegen-arm.cc  Fri Oct 17 20:38:26 2014 UTC
@@ -3076,6 +3076,15 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    DCHECK(super_ref != NULL);
+    __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    __ Push(r0);
+    __ CallRuntime(Runtime::kGetPrototype, 1);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
=======================================
--- /trunk/src/arm64/code-stubs-arm64.cc        Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/src/arm64/code-stubs-arm64.cc        Fri Oct 17 20:38:26 2014 UTC
@@ -3812,9 +3812,9 @@
   // x12: input_type
   // x15: from (untagged)
   __ SmiTag(from);
-  StringCharAtGenerator generator(
-      input_string, from, result_length, x0,
-      &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(input_string, from, result_length, x0,
+                                  &runtime, &runtime, &runtime,
+ STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ Drop(3);
   __ Ret();
=======================================
--- /trunk/src/arm64/disasm-arm64.cc    Thu Sep 11 00:05:22 2014 UTC
+++ /trunk/src/arm64/disasm-arm64.cc    Fri Oct 17 20:38:26 2014 UTC
@@ -1695,7 +1695,7 @@
   DCHECK(format[0] == 'M');
   USE(format);

-  static const char* options[4][4] = {
+  static const char* const options[4][4] = {
     { "sy (0b0000)", "oshld", "oshst", "osh" },
     { "sy (0b0100)", "nshld", "nshst", "nsh" },
     { "sy (0b1000)", "ishld", "ishst", "ish" },
=======================================
--- /trunk/src/arm64/full-codegen-arm64.cc      Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/src/arm64/full-codegen-arm64.cc      Fri Oct 17 20:38:26 2014 UTC
@@ -2741,6 +2741,15 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    DCHECK(super_ref != NULL);
+    __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    __ Push(x0);
+    __ CallRuntime(Runtime::kGetPrototype, 1);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
=======================================
--- /trunk/src/array-iterator.js        Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/array-iterator.js        Fri Oct 17 20:38:26 2014 UTC
@@ -120,8 +120,8 @@
   %CheckIsBootstrapping();

   InstallFunctions($Array.prototype, DONT_ENUM, $Array(
+    // No 'values' since it breaks webcompat: http://crbug.com/409858
     'entries', ArrayEntries,
-    'values', ArrayValues,
     'keys', ArrayKeys
   ));

=======================================
--- /trunk/src/array.js Wed Oct 15 13:35:30 2014 UTC
+++ /trunk/src/array.js Fri Oct 17 20:38:26 2014 UTC
@@ -1499,7 +1499,6 @@
     find: true,
     findIndex: true,
     keys: true,
-    values: true,
   };
   %AddNamedProperty($Array.prototype, symbolUnscopables, unscopables,
       DONT_ENUM | READ_ONLY);
=======================================
--- /trunk/src/ast.cc   Wed Oct 15 13:35:30 2014 UTC
+++ /trunk/src/ast.cc   Fri Oct 17 20:38:26 2014 UTC
@@ -580,6 +580,8 @@
       return LOOKUP_SLOT_CALL;
     }
   }
+
+  if (expression()->AsSuperReference() != NULL) return SUPER_CALL;

   Property* property = expression()->AsProperty();
   return property != NULL ? PROPERTY_CALL : OTHER_CALL;
=======================================
--- /trunk/src/ast.h    Wed Oct 15 13:35:30 2014 UTC
+++ /trunk/src/ast.h    Fri Oct 17 20:38:26 2014 UTC
@@ -1851,6 +1851,7 @@
     GLOBAL_CALL,
     LOOKUP_SLOT_CALL,
     PROPERTY_CALL,
+    SUPER_CALL,
     OTHER_CALL
   };

@@ -3474,16 +3475,7 @@
   Call* NewCall(Expression* expression,
                 ZoneList<Expression*>* arguments,
                 int pos) {
-    SuperReference* super_ref = expression->AsSuperReference();
-    Call* call;
-    if (super_ref != NULL) {
-      Literal* constructor =
-          NewStringLiteral(ast_value_factory_->constructor_string(), pos);
- Property* superConstructor = NewProperty(super_ref, constructor, pos); - call = new (zone_) Call(zone_, superConstructor, arguments, pos, id_gen_);
-    } else {
-      call = new (zone_) Call(zone_, expression, arguments, pos, id_gen_);
-    }
+ Call* call = new (zone_) Call(zone_, expression, arguments, pos, id_gen_);
     VISIT_AND_RETURN(Call, call)
   }

=======================================
--- /trunk/src/code-stubs.h     Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/src/code-stubs.h     Fri Oct 17 20:38:26 2014 UTC
@@ -1803,7 +1803,7 @@
                         ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
: char_code_at_generator_(object, index, scratch, receiver_not_string,
                                 index_not_number, index_out_of_range,
-                                index_flags),
+                                index_flags, check_mode),
         char_from_code_generator_(scratch, result) {}

   // Generates the fast case code. On the fallthrough path |result|
=======================================
--- /trunk/src/compiler/arm/instruction-selector-arm.cc Wed Oct 15 13:35:30 2014 UTC +++ /trunk/src/compiler/arm/instruction-selector-arm.cc Fri Oct 17 20:38:26 2014 UTC
@@ -22,6 +22,14 @@
     }
     return UseRegister(node);
   }
+
+  bool CanBeImmediate(int32_t value) const {
+    return Assembler::ImmediateFitsAddrMode1Instruction(value);
+  }
+
+  bool CanBeImmediate(uint32_t value) const {
+    return CanBeImmediate(bit_cast<int32_t>(value));
+  }

   bool CanBeImmediate(Node* node, InstructionCode opcode) {
     Int32Matcher m(node);
@@ -32,22 +40,20 @@
       case kArmMov:
       case kArmMvn:
       case kArmBic:
-        return ImmediateFitsAddrMode1Instruction(value) ||
-               ImmediateFitsAddrMode1Instruction(~value);
+        return CanBeImmediate(value) || CanBeImmediate(~value);

       case kArmAdd:
       case kArmSub:
       case kArmCmp:
       case kArmCmn:
-        return ImmediateFitsAddrMode1Instruction(value) ||
-               ImmediateFitsAddrMode1Instruction(-value);
+        return CanBeImmediate(value) || CanBeImmediate(-value);

       case kArmTst:
       case kArmTeq:
       case kArmOrr:
       case kArmEor:
       case kArmRsb:
-        return ImmediateFitsAddrMode1Instruction(value);
+        return CanBeImmediate(value);

       case kArmVldrF32:
       case kArmVstrF32:
@@ -106,11 +112,6 @@
     UNREACHABLE();
     return false;
   }
-
- private:
-  bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
-    return Assembler::ImmediateFitsAddrMode1Instruction(imm);
-  }
 };


@@ -417,7 +418,8 @@
     }
   }
   if (IsSupported(ARMv7) && m.right().HasValue()) {
-    uint32_t value = m.right().Value();
+    // Try to interpret this AND as UBFX.
+    uint32_t const value = m.right().Value();
     uint32_t width = base::bits::CountPopulation32(value);
     uint32_t msb = base::bits::CountLeadingZeros32(value);
     if (width != 0 && msb + width == 32) {
@@ -435,6 +437,15 @@
            g.TempImmediate(0), g.TempImmediate(width));
       return;
     }
+
+    // Try to interpret this AND as BIC.
+    if (g.CanBeImmediate(~value)) {
+      Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.TempImmediate(~value));
+      return;
+    }
+
     // Try to interpret this AND as BFC.
     width = 32 - width;
     msb = base::bits::CountLeadingZeros32(~value);
@@ -857,8 +868,10 @@
   opcode |= MiscField::encode(descriptor->flags());

   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
buffer.instruction_args.size(), &buffer.instruction_args.front());
   call_instr->MarkAsCall();
 }
=======================================
--- /trunk/src/compiler/arm64/instruction-selector-arm64.cc Wed Oct 15 13:35:30 2014 UTC +++ /trunk/src/compiler/arm64/instruction-selector-arm64.cc Fri Oct 17 20:38:26 2014 UTC
@@ -954,8 +954,10 @@
   opcode |= MiscField::encode(descriptor->flags());

   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
buffer.instruction_args.size(), &buffer.instruction_args.front());
   call_instr->MarkAsCall();
 }
=======================================
--- /trunk/src/compiler/ast-graph-builder.cc    Mon Oct 13 00:05:20 2014 UTC
+++ /trunk/src/compiler/ast-graph-builder.cc    Fri Oct 17 20:38:26 2014 UTC
@@ -1261,6 +1261,11 @@
       flags = CALL_AS_METHOD;
       break;
     }
+    case Call::SUPER_CALL: {
+      // todo(dslomov): implement super calls in turbofan.
+      UNIMPLEMENTED();
+      break;
+    }
     case Call::POSSIBLY_EVAL_CALL:
       possibly_eval = true;
     // Fall through.
=======================================
--- /trunk/src/compiler/ia32/instruction-selector-ia32.cc Wed Oct 15 13:35:30 2014 UTC +++ /trunk/src/compiler/ia32/instruction-selector-ia32.cc Fri Oct 17 20:38:26 2014 UTC
@@ -638,8 +638,10 @@
   opcode |= MiscField::encode(descriptor->flags());

   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
buffer.instruction_args.size(), &buffer.instruction_args.front());
   call_instr->MarkAsCall();
 }
=======================================
--- /trunk/src/compiler/mips/instruction-selector-mips.cc Wed Oct 15 13:35:30 2014 UTC +++ /trunk/src/compiler/mips/instruction-selector-mips.cc Fri Oct 17 20:38:26 2014 UTC
@@ -451,8 +451,10 @@
   opcode |= MiscField::encode(descriptor->flags());

   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
buffer.instruction_args.size(), &buffer.instruction_args.front());
   call_instr->MarkAsCall();
 }
=======================================
--- /trunk/src/compiler/node-matchers.h Wed Oct  8 00:05:11 2014 UTC
+++ /trunk/src/compiler/node-matchers.h Fri Oct 17 20:38:26 2014 UTC
@@ -96,6 +96,42 @@
 typedef FloatMatcher<double, IrOpcode::kNumberConstant> NumberMatcher;


+// A pattern matcher for any numberic constant.
+struct NumericValueMatcher : public NodeMatcher {
+  explicit NumericValueMatcher(Node* const node) : NodeMatcher(node) {
+    switch (opcode()) {
+      case IrOpcode::kInt32Constant:
+        has_value_ = true;
+        value_ = OpParameter<int32_t>(node);
+        break;
+      case IrOpcode::kFloat32Constant:
+        has_value_ = true;
+        value_ = OpParameter<float>(node);
+        break;
+      case IrOpcode::kFloat64Constant:
+      case IrOpcode::kNumberConstant:
+        has_value_ = true;
+        value_ = OpParameter<double>(node);
+        break;
+      default:
+        has_value_ = false;
+        value_ = 0;  // Make the compiler happy.
+        break;
+    }
+  }
+
+  bool HasValue() const { return has_value_; }
+  double Value() const {
+    DCHECK(HasValue());
+    return value_;
+  }
+
+ private:
+  double value_;
+  bool has_value_;
+};
+
+
 // A pattern matcher for heap object constants.
 template <typename T>
 struct HeapObjectMatcher FINAL
=======================================
--- /trunk/src/compiler/pipeline.cc     Fri Oct 17 11:41:30 2014 UTC
+++ /trunk/src/compiler/pipeline.cc     Fri Oct 17 20:38:26 2014 UTC
@@ -11,6 +11,7 @@
 #include "src/compiler/basic-block-instrumentor.h"
 #include "src/compiler/change-lowering.h"
 #include "src/compiler/code-generator.h"
+#include "src/compiler/control-reducer.h"
 #include "src/compiler/graph-replay.h"
 #include "src/compiler/graph-visualizer.h"
 #include "src/compiler/instruction.h"
@@ -301,9 +302,13 @@
                                 "typed lowering");
       SourcePositionTable::Scope pos(&source_positions,
                                      SourcePosition::Unknown());
+      ValueNumberingReducer vn_reducer(zone());
       JSTypedLowering lowering(&jsgraph);
+      SimplifiedOperatorReducer simple_reducer(&jsgraph);
       GraphReducer graph_reducer(&graph);
+      graph_reducer.AddReducer(&vn_reducer);
       graph_reducer.AddReducer(&lowering);
+      graph_reducer.AddReducer(&simple_reducer);
       graph_reducer.ReduceGraph();

       VerifyAndPrintGraph(&graph, "Lowered typed");
@@ -347,6 +352,16 @@
       // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
       VerifyAndPrintGraph(&graph, "Lowered changes", true);
     }
+
+    {
+      SourcePositionTable::Scope pos(&source_positions,
+                                     SourcePosition::Unknown());
+      PhaseStats control_reducer_stats(info(), PhaseStats::CREATE_GRAPH,
+                                       "control reduction");
+      ControlReducer::ReduceGraph(&jsgraph, &common);
+
+      VerifyAndPrintGraph(&graph, "Control reduced");
+    }
   }

   {
=======================================
--- /trunk/src/compiler/simplified-operator-reducer.cc Wed Sep 17 00:05:08 2014 UTC +++ /trunk/src/compiler/simplified-operator-reducer.cc Fri Oct 17 20:38:26 2014 UTC
@@ -12,6 +12,10 @@
 namespace internal {
 namespace compiler {

+SimplifiedOperatorReducer::SimplifiedOperatorReducer(JSGraph* jsgraph)
+    : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
+
+
 SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}


@@ -95,6 +99,38 @@
       if (m.HasValue()) return ReplaceNumber(FastUI2D(m.Value()));
       break;
     }
+    case IrOpcode::kLoadElement: {
+      ElementAccess access = ElementAccessOf(node->op());
+      if (access.bounds_check == kTypedArrayBoundsCheck) {
+        NumericValueMatcher mkey(node->InputAt(1));
+        NumericValueMatcher mlength(node->InputAt(2));
+        if (mkey.HasValue() && mlength.HasValue()) {
+ // Skip the typed array bounds check if key and length are constant.
+          if (mkey.Value() < mlength.Value()) {
+            access.bounds_check = kNoBoundsCheck;
+            node->set_op(simplified()->LoadElement(access));
+            return Changed(node);
+          }
+        }
+      }
+      break;
+    }
+    case IrOpcode::kStoreElement: {
+      ElementAccess access = ElementAccessOf(node->op());
+      if (access.bounds_check == kTypedArrayBoundsCheck) {
+        NumericValueMatcher mkey(node->InputAt(1));
+        NumericValueMatcher mlength(node->InputAt(2));
+        if (mkey.HasValue() && mlength.HasValue()) {
+ // Skip the typed array bounds check if key and length are constant.
+          if (mkey.Value() < mlength.Value()) {
+            access.bounds_check = kNoBoundsCheck;
+            node->set_op(simplified()->StoreElement(access));
+            return Changed(node);
+          }
+        }
+      }
+      break;
+    }
     default:
       break;
   }
=======================================
--- /trunk/src/compiler/simplified-operator-reducer.h Wed Sep 17 00:05:08 2014 UTC +++ /trunk/src/compiler/simplified-operator-reducer.h Fri Oct 17 20:38:26 2014 UTC
@@ -6,6 +6,7 @@
 #define V8_COMPILER_SIMPLIFIED_OPERATOR_REDUCER_H_

 #include "src/compiler/graph-reducer.h"
+#include "src/compiler/simplified-operator.h"

 namespace v8 {
 namespace internal {
@@ -21,7 +22,7 @@

 class SimplifiedOperatorReducer FINAL : public Reducer {
  public:
- explicit SimplifiedOperatorReducer(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
+  explicit SimplifiedOperatorReducer(JSGraph* jsgraph);
   virtual ~SimplifiedOperatorReducer();

   virtual Reduction Reduce(Node* node) OVERRIDE;
@@ -40,8 +41,10 @@
   Factory* factory() const;
   JSGraph* jsgraph() const { return jsgraph_; }
   MachineOperatorBuilder* machine() const;
+  SimplifiedOperatorBuilder* simplified() { return &simplified_; }

   JSGraph* jsgraph_;
+  SimplifiedOperatorBuilder simplified_;

   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorReducer);
 };
=======================================
--- /trunk/src/compiler/x64/code-generator-x64.cc Fri Oct 17 11:41:30 2014 UTC +++ /trunk/src/compiler/x64/code-generator-x64.cc Fri Oct 17 20:38:26 2014 UTC
@@ -896,22 +896,22 @@
       }
     } else if (src.type() == Constant::kFloat32) {
       // TODO(turbofan): Can we do better here?
- __ movl(kScratchRegister, Immediate(bit_cast<int32_t>(src.ToFloat32())));
+      uint32_t src_const = bit_cast<uint32_t>(src.ToFloat32());
       if (destination->IsDoubleRegister()) {
-        XMMRegister dst = g.ToDoubleRegister(destination);
-        __ movq(dst, kScratchRegister);
+        __ Move(g.ToDoubleRegister(destination), src_const);
       } else {
         DCHECK(destination->IsDoubleStackSlot());
         Operand dst = g.ToOperand(destination);
-        __ movl(dst, kScratchRegister);
+        __ movl(dst, Immediate(src_const));
       }
     } else {
       DCHECK_EQ(Constant::kFloat64, src.type());
-      __ movq(kScratchRegister, bit_cast<int64_t>(src.ToFloat64()));
+      uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64());
       if (destination->IsDoubleRegister()) {
-        __ movq(g.ToDoubleRegister(destination), kScratchRegister);
+        __ Move(g.ToDoubleRegister(destination), src_const);
       } else {
         DCHECK(destination->IsDoubleStackSlot());
+        __ movq(kScratchRegister, src_const);
         __ movq(g.ToOperand(destination), kScratchRegister);
       }
     }
=======================================
***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