Revision: 24504
Author:   [email protected]
Date:     Fri Oct 10 00:05:16 2014 UTC
Log:      Version 3.30.7 (based on bleeding_edge revision r24503)

Fix computation of UTC time from local time at DST change points (issue 3116, Chromium issues 415424, 417640).

Convert `obj` ToObject in Object.keys() (issue 3587).

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

Added:
 /trunk/test/js-perf-test
 /trunk/test/js-perf-test/Collections
 /trunk/test/js-perf-test/Collections/Collections.json
 /trunk/test/js-perf-test/Collections/base.js
 /trunk/test/js-perf-test/Collections/map.js
 /trunk/test/js-perf-test/Collections/run.js
 /trunk/test/js-perf-test/Collections/set.js
 /trunk/test/js-perf-test/Collections/weakmap.js
 /trunk/test/js-perf-test/Collections/weakset.js
 /trunk/test/mjsunit/regress/regress-3116.js
 /trunk/tools/sanitizers
 /trunk/tools/sanitizers/tsan_suppressions.txt
Deleted:
 /trunk/test/perf-test/Collections/Collections.json
 /trunk/test/perf-test/Collections/base.js
 /trunk/test/perf-test/Collections/map.js
 /trunk/test/perf-test/Collections/run.js
 /trunk/test/perf-test/Collections/set.js
 /trunk/test/perf-test/Collections/weakmap.js
 /trunk/test/perf-test/Collections/weakset.js
Modified:
 /trunk/AUTHORS
 /trunk/ChangeLog
 /trunk/build/toolchain.gypi
 /trunk/include/v8-platform.h
 /trunk/src/arm/codegen-arm.cc
 /trunk/src/arm/full-codegen-arm.cc
 /trunk/src/arm64/codegen-arm64.cc
 /trunk/src/arm64/full-codegen-arm64.cc
 /trunk/src/ast.h
 /trunk/src/base/bits.h
 /trunk/src/base/cpu.cc
 /trunk/src/base/utils/random-number-generator.cc
 /trunk/src/base/utils/random-number-generator.h
 /trunk/src/builtins.cc
 /trunk/src/builtins.h
 /trunk/src/compiler/arm64/code-generator-arm64.cc
 /trunk/src/compiler/arm64/instruction-codes-arm64.h
 /trunk/src/compiler/arm64/instruction-selector-arm64.cc
 /trunk/src/compiler/ia32/code-generator-ia32.cc
 /trunk/src/compiler/machine-operator-reducer.cc
 /trunk/src/compiler/machine-operator.cc
 /trunk/src/compiler/machine-operator.h
 /trunk/src/date.h
 /trunk/src/flag-definitions.h
 /trunk/src/full-codegen.h
 /trunk/src/heap/mark-compact.cc
 /trunk/src/ia32/assembler-ia32.cc
 /trunk/src/ia32/assembler-ia32.h
 /trunk/src/ia32/codegen-ia32.cc
 /trunk/src/ia32/disasm-ia32.cc
 /trunk/src/ia32/full-codegen-ia32.cc
 /trunk/src/ia32/macro-assembler-ia32.cc
 /trunk/src/ia32/macro-assembler-ia32.h
 /trunk/src/ic/arm/ic-arm.cc
 /trunk/src/ic/arm64/ic-arm64.cc
 /trunk/src/ic/ia32/ic-ia32.cc
 /trunk/src/ic/ic.cc
 /trunk/src/ic/ic.h
 /trunk/src/ic/mips/ic-mips.cc
 /trunk/src/ic/mips64/ic-mips64.cc
 /trunk/src/ic/x64/ic-x64.cc
 /trunk/src/ic/x64/stub-cache-x64.cc
 /trunk/src/log.cc
 /trunk/src/mips/codegen-mips.cc
 /trunk/src/mips/constants-mips.h
 /trunk/src/mips/full-codegen-mips.cc
 /trunk/src/mips64/codegen-mips64.cc
 /trunk/src/mips64/full-codegen-mips64.cc
 /trunk/src/mips64/macro-assembler-mips64.cc
 /trunk/src/mips64/simulator-mips64.cc
 /trunk/src/optimizing-compiler-thread.cc
 /trunk/src/optimizing-compiler-thread.h
 /trunk/src/parser.cc
 /trunk/src/parser.h
 /trunk/src/preparser.cc
 /trunk/src/preparser.h
 /trunk/src/runtime/runtime-classes.cc
 /trunk/src/runtime/runtime-test.cc
 /trunk/src/runtime/runtime.h
 /trunk/src/v8natives.js
 /trunk/src/version.cc
 /trunk/src/x64/codegen-x64.cc
 /trunk/src/x64/full-codegen-x64.cc
 /trunk/src/x87/builtins-x87.cc
 /trunk/src/x87/debug-x87.cc
 /trunk/src/x87/full-codegen-x87.cc
 /trunk/test/mjsunit/harmony/super.js
 /trunk/test/mjsunit/third_party/object-keys.js
 /trunk/test/test262/test262.status
 /trunk/test/unittests/base/bits-unittest.cc
 /trunk/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
 /trunk/test/unittests/compiler/change-lowering-unittest.cc
 /trunk/test/unittests/compiler/graph-unittest.cc
 /trunk/test/unittests/compiler/graph-unittest.h
 /trunk/test/unittests/compiler/machine-operator-reducer-unittest.cc
 /trunk/tools/run-llprof.sh
 /trunk/tools/run-tests.py

=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Collections/Collections.json Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,15 @@
+{
+  "path": ["."],
+  "main": "run.js",
+  "flags": ["--harmony-collections"],
+  "run_count": 5,
+  "units": "score",
+  "results_regexp": "^%s\\-Collections\\(Score\\): (.+)$",
+  "total": true,
+  "tests": [
+    {"name": "Map"},
+    {"name": "Set"},
+    {"name": "WeakMap"},
+    {"name": "WeakSet"}
+  ]
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Collections/base.js Fri Oct 10 00:05:16 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/js-perf-test/Collections/map.js Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,81 @@
+// 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 MapBenchmark = new BenchmarkSuite('Map', [1000], [
+  new Benchmark('Set', false, false, 0, MapSet),
+  new Benchmark('Has', false, false, 0, MapHas, MapSetup, MapTearDown),
+  new Benchmark('Get', false, false, 0, MapGet, MapSetup, MapTearDown),
+ new Benchmark('Delete', false, false, 0, MapDelete, MapSetup, MapTearDown), + new Benchmark('ForEach', false, false, 0, MapForEach, MapSetup, MapTearDown),
+]);
+
+
+var map;
+var N = 10;
+
+
+function MapSetup() {
+  map = new Map;
+  for (var i = 0; i < N; i++) {
+    map.set(i, i);
+  }
+}
+
+
+function MapTearDown() {
+  map = null;
+}
+
+
+function MapSet() {
+  MapSetup();
+  MapTearDown();
+}
+
+
+function MapHas() {
+  for (var i = 0; i < N; i++) {
+    if (!map.has(i)) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.has(i)) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapGet() {
+  for (var i = 0; i < N; i++) {
+    if (map.get(i) !== i) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.get(i) !== undefined) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapDelete() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    map.delete(i);
+  }
+}
+
+
+function MapForEach() {
+  map.forEach(function(v, k) {
+    if (v !== k) {
+      throw new Error();
+    }
+  });
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Collections/run.js Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,30 @@
+// 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('map.js');
+load('set.js');
+load('weakmap.js');
+load('weakset.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Collections(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/Collections/set.js Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,66 @@
+// 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 SetBenchmark = new BenchmarkSuite('Set', [1000], [
+  new Benchmark('Add', false, false, 0, SetAdd),
+  new Benchmark('Has', false, false, 0, SetHas, SetSetup, SetTearDown),
+ new Benchmark('Delete', false, false, 0, SetDelete, SetSetup, SetTearDown), + new Benchmark('ForEach', false, false, 0, SetForEach, SetSetup, SetTearDown),
+]);
+
+
+var set;
+var N = 10;
+
+
+function SetSetup() {
+  set = new Set;
+  for (var i = 0; i < N; i++) {
+    set.add(i);
+  }
+}
+
+
+function SetTearDown() {
+  map = null;
+}
+
+
+function SetAdd() {
+  SetSetup();
+  SetTearDown();
+}
+
+
+function SetHas() {
+  for (var i = 0; i < N; i++) {
+    if (!set.has(i)) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (set.has(i)) {
+      throw new Error();
+    }
+  }
+}
+
+
+function SetDelete() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    set.delete(i);
+  }
+}
+
+
+function SetForEach() {
+  set.forEach(function(v, k) {
+    if (v !== k) {
+      throw new Error();
+    }
+  });
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Collections/weakmap.js Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,80 @@
+// 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 MapBenchmark = new BenchmarkSuite('WeakMap', [1000], [
+  new Benchmark('Set', false, false, 0, WeakMapSet),
+  new Benchmark('Has', false, false, 0, WeakMapHas, WeakMapSetup,
+      WeakMapTearDown),
+  new Benchmark('Get', false, false, 0, WeakMapGet, WeakMapSetup,
+      WeakMapTearDown),
+  new Benchmark('Delete', false, false, 0, WeakMapDelete, WeakMapSetup,
+      WeakMapTearDown),
+]);
+
+
+var wm;
+var N = 10;
+var keys = [];
+
+
+for (var i = 0; i < N * 2; i++) {
+  keys[i] = {};
+}
+
+
+function WeakMapSetup() {
+  wm = new WeakMap;
+  for (var i = 0; i < N; i++) {
+    wm.set(keys[i], i);
+  }
+}
+
+
+function WeakMapTearDown() {
+  wm = null;
+}
+
+
+function WeakMapSet() {
+  WeakMapSetup();
+  WeakMapTearDown();
+}
+
+
+function WeakMapHas() {
+  for (var i = 0; i < N; i++) {
+    if (!wm.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (wm.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function WeakMapGet() {
+  for (var i = 0; i < N; i++) {
+    if (wm.get(keys[i]) !== i) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (wm.get(keys[i]) !== undefined) {
+      throw new Error();
+    }
+  }
+}
+
+
+function WeakMapDelete() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    wm.delete(keys[i]);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/test/js-perf-test/Collections/weakset.js Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,64 @@
+// 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 SetBenchmark = new BenchmarkSuite('WeakSet', [1000], [
+  new Benchmark('Add', false, false, 0, WeakSetAdd),
+  new Benchmark('Has', false, false, 0, WeakSetHas, WeakSetSetup,
+      WeakSetTearDown),
+  new Benchmark('Delete', false, false, 0, WeakSetDelete, WeakSetSetup,
+      WeakSetTearDown),
+]);
+
+
+var ws;
+var N = 10;
+var keys = [];
+
+
+for (var i = 0; i < N * 2; i++) {
+  keys[i] = {};
+}
+
+
+function WeakSetSetup() {
+  ws = new WeakSet;
+  for (var i = 0; i < N; i++) {
+    ws.add(keys[i]);
+  }
+}
+
+
+function WeakSetTearDown() {
+  ws = null;
+}
+
+
+function WeakSetAdd() {
+  WeakSetSetup();
+  WeakSetTearDown();
+}
+
+
+function WeakSetHas() {
+  for (var i = 0; i < N; i++) {
+    if (!ws.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (ws.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function WeakSetDelete() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    ws.delete(keys[i]);
+  }
+}
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-3116.js Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,314 @@
+// 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 timezone(tz) {
+  var str = (new Date(2014, 0, 10)).toString();
+  if (tz == "CET") {
+    return str == "Fri Jan 10 2014 00:00:00 GMT+0100 (CET)";
+  }
+  if (tz == "BRT") {
+    return str == "Fri Jan 10 2014 00:00:00 GMT-0200 (BRST)";
+  }
+  if (tz == "PST") {
+    return str == "Fri Jan 10 2014 00:00:00 GMT-0800 (PST)";
+  }
+  return false;
+}
+
+if (timezone("CET")) {
+  assertEquals("Sat Mar 29 2014 22:59:00 GMT+0100 (CET)",
+               (new Date(2014, 2, 29, 22, 59)).toString());
+  assertEquals("Sat, 29 Mar 2014 21:59:00 GMT",
+               (new Date(2014, 2, 29, 22, 59)).toUTCString());
+  assertEquals("Sat Mar 29 2014 23:00:00 GMT+0100 (CET)",
+               (new Date(2014, 2, 29, 23, 0)).toString());
+  assertEquals("Sat, 29 Mar 2014 22:00:00 GMT",
+               (new Date(2014, 2, 29, 23, 0)).toUTCString());
+  assertEquals("Sat Mar 29 2014 23:59:00 GMT+0100 (CET)",
+               (new Date(2014, 2, 29, 23, 59)).toString());
+  assertEquals("Sat, 29 Mar 2014 22:59:00 GMT",
+               (new Date(2014, 2, 29, 23, 59)).toUTCString());
+  assertEquals("Sun Mar 30 2014 00:00:00 GMT+0100 (CET)",
+               (new Date(2014, 2, 30, 0, 0)).toString());
+  assertEquals("Sat, 29 Mar 2014 23:00:00 GMT",
+               (new Date(2014, 2, 30, 0, 0)).toUTCString());
+  assertEquals("Sun Mar 30 2014 00:59:00 GMT+0100 (CET)",
+               (new Date(2014, 2, 30, 0, 59)).toString());
+  assertEquals("Sat, 29 Mar 2014 23:59:00 GMT",
+               (new Date(2014, 2, 30, 0, 59)).toUTCString());
+  assertEquals("Sun Mar 30 2014 01:00:00 GMT+0100 (CET)",
+               (new Date(2014, 2, 30, 1, 0)).toString());
+  assertEquals("Sun, 30 Mar 2014 00:00:00 GMT",
+               (new Date(2014, 2, 30, 1, 0)).toUTCString());
+  assertEquals("Sun Mar 30 2014 01:59:00 GMT+0100 (CET)",
+               (new Date(2014, 2, 30, 1, 59)).toString());
+  assertEquals("Sun, 30 Mar 2014 00:59:00 GMT",
+               (new Date(2014, 2, 30, 1, 59)).toUTCString());
+  assertEquals("Sun Mar 30 2014 03:00:00 GMT+0200 (CEST)",
+               (new Date(2014, 2, 30, 2, 0)).toString());
+  assertEquals("Sun, 30 Mar 2014 01:00:00 GMT",
+               (new Date(2014, 2, 30, 2, 0)).toUTCString());
+  assertEquals("Sun Mar 30 2014 03:59:00 GMT+0200 (CEST)",
+               (new Date(2014, 2, 30, 2, 59)).toString());
+  assertEquals("Sun, 30 Mar 2014 01:59:00 GMT",
+               (new Date(2014, 2, 30, 2, 59)).toUTCString());
+  assertEquals("Sun Mar 30 2014 03:00:00 GMT+0200 (CEST)",
+               (new Date(2014, 2, 30, 3, 0)).toString());
+  assertEquals("Sun, 30 Mar 2014 01:00:00 GMT",
+               (new Date(2014, 2, 30, 3, 0)).toUTCString());
+  assertEquals("Sun Mar 30 2014 03:59:00 GMT+0200 (CEST)",
+               (new Date(2014, 2, 30, 3, 59)).toString());
+  assertEquals("Sun, 30 Mar 2014 01:59:00 GMT",
+               (new Date(2014, 2, 30, 3, 59)).toUTCString());
+  assertEquals("Sun Mar 30 2014 04:00:00 GMT+0200 (CEST)",
+               (new Date(2014, 2, 30, 4, 0)).toString());
+  assertEquals("Sun, 30 Mar 2014 02:00:00 GMT",
+               (new Date(2014, 2, 30, 4, 0)).toUTCString());
+  assertEquals("Sat Oct 25 2014 22:59:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 25, 22, 59)).toString());
+  assertEquals("Sat, 25 Oct 2014 20:59:00 GMT",
+               (new Date(2014, 9, 25, 22, 59)).toUTCString());
+  assertEquals("Sat Oct 25 2014 23:00:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 25, 23, 0)).toString());
+  assertEquals("Sat, 25 Oct 2014 21:00:00 GMT",
+               (new Date(2014, 9, 25, 23, 0)).toUTCString());
+  assertEquals("Sat Oct 25 2014 23:59:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 25, 23, 59)).toString());
+  assertEquals("Sat, 25 Oct 2014 21:59:00 GMT",
+               (new Date(2014, 9, 25, 23, 59)).toUTCString());
+  assertEquals("Sun Oct 26 2014 00:00:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 26, 0, 0)).toString());
+  assertEquals("Sat, 25 Oct 2014 22:00:00 GMT",
+               (new Date(2014, 9, 26, 0, 0)).toUTCString());
+  assertEquals("Sun Oct 26 2014 00:59:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 26, 0, 59)).toString());
+  assertEquals("Sat, 25 Oct 2014 22:59:00 GMT",
+               (new Date(2014, 9, 26, 0, 59)).toUTCString());
+  assertEquals("Sun Oct 26 2014 01:00:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 26, 1, 0)).toString());
+  assertEquals("Sat, 25 Oct 2014 23:00:00 GMT",
+               (new Date(2014, 9, 26, 1, 0)).toUTCString());
+  assertEquals("Sun Oct 26 2014 01:59:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 26, 1, 59)).toString());
+  assertEquals("Sat, 25 Oct 2014 23:59:00 GMT",
+               (new Date(2014, 9, 26, 1, 59)).toUTCString());
+  assertEquals("Sun Oct 26 2014 02:00:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 26, 2, 0)).toString());
+  assertEquals("Sun, 26 Oct 2014 00:00:00 GMT",
+               (new Date(2014, 9, 26, 2, 0)).toUTCString());
+  assertEquals("Sun Oct 26 2014 02:59:00 GMT+0200 (CEST)",
+               (new Date(2014, 9, 26, 2, 59)).toString());
+  assertEquals("Sun, 26 Oct 2014 00:59:00 GMT",
+               (new Date(2014, 9, 26, 2, 59)).toUTCString());
+  assertEquals("Sun Oct 26 2014 03:00:00 GMT+0100 (CET)",
+               (new Date(2014, 9, 26, 3, 0)).toString());
+  assertEquals("Sun, 26 Oct 2014 02:00:00 GMT",
+               (new Date(2014, 9, 26, 3, 0)).toUTCString());
+  assertEquals("Sun Oct 26 2014 03:59:00 GMT+0100 (CET)",
+               (new Date(2014, 9, 26, 3, 59)).toString());
+  assertEquals("Sun, 26 Oct 2014 02:59:00 GMT",
+               (new Date(2014, 9, 26, 3, 59)).toUTCString());
+  assertEquals("Sun Oct 26 2014 04:00:00 GMT+0100 (CET)",
+               (new Date(2014, 9, 26, 4, 0)).toString());
+  assertEquals("Sun, 26 Oct 2014 03:00:00 GMT",
+               (new Date(2014, 9, 26, 4, 0)).toUTCString());
+}
+
+if (timezone("BRT")) {
+  assertEquals("Sat Oct 18 2014 22:59:00 GMT-0300 (BRT)",
+               (new Date(2014, 9, 18, 22, 59)).toString());
+  assertEquals("Sun, 19 Oct 2014 01:59:00 GMT",
+               (new Date(2014, 9, 18, 22, 59)).toUTCString());
+  assertEquals("Sat Oct 18 2014 23:00:00 GMT-0300 (BRT)",
+               (new Date(2014, 9, 18, 23, 0)).toString());
+  assertEquals("Sun, 19 Oct 2014 02:00:00 GMT",
+               (new Date(2014, 9, 18, 23, 0)).toUTCString());
+  assertEquals("Sat Oct 18 2014 23:59:00 GMT-0300 (BRT)",
+               (new Date(2014, 9, 18, 23, 59)).toString());
+  assertEquals("Sun, 19 Oct 2014 02:59:00 GMT",
+               (new Date(2014, 9, 18, 23, 59)).toUTCString());
+  assertEquals("Sun Oct 19 2014 01:00:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 0, 0)).toString());
+  assertEquals("Sun, 19 Oct 2014 03:00:00 GMT",
+               (new Date(2014, 9, 19, 0, 0)).toUTCString());
+  assertEquals("Sun Oct 19 2014 01:59:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 0, 59)).toString());
+  assertEquals("Sun, 19 Oct 2014 03:59:00 GMT",
+               (new Date(2014, 9, 19, 0, 59)).toUTCString());
+  assertEquals("Sun Oct 19 2014 01:00:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 1, 0)).toString());
+  assertEquals("Sun, 19 Oct 2014 03:00:00 GMT",
+               (new Date(2014, 9, 19, 1, 0)).toUTCString());
+  assertEquals("Sun Oct 19 2014 01:59:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 1, 59)).toString());
+  assertEquals("Sun, 19 Oct 2014 03:59:00 GMT",
+               (new Date(2014, 9, 19, 1, 59)).toUTCString());
+  assertEquals("Sun Oct 19 2014 02:00:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 2, 0)).toString());
+  assertEquals("Sun, 19 Oct 2014 04:00:00 GMT",
+               (new Date(2014, 9, 19, 2, 0)).toUTCString());
+  assertEquals("Sun Oct 19 2014 02:59:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 2, 59)).toString());
+  assertEquals("Sun, 19 Oct 2014 04:59:00 GMT",
+               (new Date(2014, 9, 19, 2, 59)).toUTCString());
+  assertEquals("Sun Oct 19 2014 03:00:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 3, 0)).toString());
+  assertEquals("Sun, 19 Oct 2014 05:00:00 GMT",
+               (new Date(2014, 9, 19, 3, 0)).toUTCString());
+  assertEquals("Sun Oct 19 2014 03:59:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 3, 59)).toString());
+  assertEquals("Sun, 19 Oct 2014 05:59:00 GMT",
+               (new Date(2014, 9, 19, 3, 59)).toUTCString());
+  assertEquals("Sun Oct 19 2014 04:00:00 GMT-0200 (BRST)",
+               (new Date(2014, 9, 19, 4, 0)).toString());
+  assertEquals("Sun, 19 Oct 2014 06:00:00 GMT",
+               (new Date(2014, 9, 19, 4, 0)).toUTCString());
+  assertEquals("Sat Feb 15 2014 22:59:00 GMT-0200 (BRST)",
+               (new Date(2014, 1, 15, 22, 59)).toString());
+  assertEquals("Sun, 16 Feb 2014 00:59:00 GMT",
+               (new Date(2014, 1, 15, 22, 59)).toUTCString());
+  assertEquals("Sat Feb 15 2014 23:00:00 GMT-0200 (BRST)",
+               (new Date(2014, 1, 15, 23, 0)).toString());
+  assertEquals("Sun, 16 Feb 2014 01:00:00 GMT",
+               (new Date(2014, 1, 15, 23, 0)).toUTCString());
+  assertEquals("Sat Feb 15 2014 23:59:00 GMT-0200 (BRST)",
+               (new Date(2014, 1, 15, 23, 59)).toString());
+  assertEquals("Sun, 16 Feb 2014 01:59:00 GMT",
+               (new Date(2014, 1, 15, 23, 59)).toUTCString());
+  assertEquals("Sun Feb 16 2014 00:00:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 0, 0)).toString());
+  assertEquals("Sun, 16 Feb 2014 03:00:00 GMT",
+               (new Date(2014, 1, 16, 0, 0)).toUTCString());
+  assertEquals("Sun Feb 16 2014 00:59:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 0, 59)).toString());
+  assertEquals("Sun, 16 Feb 2014 03:59:00 GMT",
+               (new Date(2014, 1, 16, 0, 59)).toUTCString());
+  assertEquals("Sun Feb 16 2014 01:00:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 1, 0)).toString());
+  assertEquals("Sun, 16 Feb 2014 04:00:00 GMT",
+               (new Date(2014, 1, 16, 1, 0)).toUTCString());
+  assertEquals("Sun Feb 16 2014 01:59:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 1, 59)).toString());
+  assertEquals("Sun, 16 Feb 2014 04:59:00 GMT",
+               (new Date(2014, 1, 16, 1, 59)).toUTCString());
+  assertEquals("Sun Feb 16 2014 02:00:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 2, 0)).toString());
+  assertEquals("Sun, 16 Feb 2014 05:00:00 GMT",
+               (new Date(2014, 1, 16, 2, 0)).toUTCString());
+  assertEquals("Sun Feb 16 2014 02:59:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 2, 59)).toString());
+  assertEquals("Sun, 16 Feb 2014 05:59:00 GMT",
+               (new Date(2014, 1, 16, 2, 59)).toUTCString());
+  assertEquals("Sun Feb 16 2014 03:00:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 3, 0)).toString());
+  assertEquals("Sun, 16 Feb 2014 06:00:00 GMT",
+               (new Date(2014, 1, 16, 3, 0)).toUTCString());
+  assertEquals("Sun Feb 16 2014 03:59:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 3, 59)).toString());
+  assertEquals("Sun, 16 Feb 2014 06:59:00 GMT",
+               (new Date(2014, 1, 16, 3, 59)).toUTCString());
+  assertEquals("Sun Feb 16 2014 04:00:00 GMT-0300 (BRT)",
+               (new Date(2014, 1, 16, 4, 0)).toString());
+  assertEquals("Sun, 16 Feb 2014 07:00:00 GMT",
+               (new Date(2014, 1, 16, 4, 0)).toUTCString());
+}
+
+if (timezone("PST")) {
+  assertEquals("Sat Mar 08 2014 22:59:00 GMT-0800 (PST)",
+               (new Date(2014, 2, 8, 22, 59)).toString());
+  assertEquals("Sun, 09 Mar 2014 06:59:00 GMT",
+               (new Date(2014, 2, 8, 22, 59)).toUTCString());
+  assertEquals("Sat Mar 08 2014 23:00:00 GMT-0800 (PST)",
+               (new Date(2014, 2, 8, 23, 0)).toString());
+  assertEquals("Sun, 09 Mar 2014 07:00:00 GMT",
+               (new Date(2014, 2, 8, 23, 0)).toUTCString());
+  assertEquals("Sat Mar 08 2014 23:59:00 GMT-0800 (PST)",
+               (new Date(2014, 2, 8, 23, 59)).toString());
+  assertEquals("Sun, 09 Mar 2014 07:59:00 GMT",
+               (new Date(2014, 2, 8, 23, 59)).toUTCString());
+  assertEquals("Sun Mar 09 2014 00:00:00 GMT-0800 (PST)",
+               (new Date(2014, 2, 9, 0, 0)).toString());
+  assertEquals("Sun, 09 Mar 2014 08:00:00 GMT",
+               (new Date(2014, 2, 9, 0, 0)).toUTCString());
+  assertEquals("Sun Mar 09 2014 00:59:00 GMT-0800 (PST)",
+               (new Date(2014, 2, 9, 0, 59)).toString());
+  assertEquals("Sun, 09 Mar 2014 08:59:00 GMT",
+               (new Date(2014, 2, 9, 0, 59)).toUTCString());
+  assertEquals("Sun Mar 09 2014 01:00:00 GMT-0800 (PST)",
+               (new Date(2014, 2, 9, 1, 0)).toString());
+  assertEquals("Sun, 09 Mar 2014 09:00:00 GMT",
+               (new Date(2014, 2, 9, 1, 0)).toUTCString());
+  assertEquals("Sun Mar 09 2014 01:59:00 GMT-0800 (PST)",
+               (new Date(2014, 2, 9, 1, 59)).toString());
+  assertEquals("Sun, 09 Mar 2014 09:59:00 GMT",
+               (new Date(2014, 2, 9, 1, 59)).toUTCString());
+  assertEquals("Sun Mar 09 2014 03:00:00 GMT-0700 (PDT)",
+               (new Date(2014, 2, 9, 2, 0)).toString());
+  assertEquals("Sun, 09 Mar 2014 10:00:00 GMT",
+               (new Date(2014, 2, 9, 2, 0)).toUTCString());
+  assertEquals("Sun Mar 09 2014 03:59:00 GMT-0700 (PDT)",
+               (new Date(2014, 2, 9, 2, 59)).toString());
+  assertEquals("Sun, 09 Mar 2014 10:59:00 GMT",
+               (new Date(2014, 2, 9, 2, 59)).toUTCString());
+  assertEquals("Sun Mar 09 2014 03:00:00 GMT-0700 (PDT)",
+               (new Date(2014, 2, 9, 3, 0)).toString());
+  assertEquals("Sun, 09 Mar 2014 10:00:00 GMT",
+               (new Date(2014, 2, 9, 3, 0)).toUTCString());
+  assertEquals("Sun Mar 09 2014 03:59:00 GMT-0700 (PDT)",
+               (new Date(2014, 2, 9, 3, 59)).toString());
+  assertEquals("Sun, 09 Mar 2014 10:59:00 GMT",
+               (new Date(2014, 2, 9, 3, 59)).toUTCString());
+  assertEquals("Sun Mar 09 2014 04:00:00 GMT-0700 (PDT)",
+               (new Date(2014, 2, 9, 4, 0)).toString());
+  assertEquals("Sun, 09 Mar 2014 11:00:00 GMT",
+               (new Date(2014, 2, 9, 4, 0)).toUTCString());
+  assertEquals("Sat Nov 01 2014 22:59:00 GMT-0700 (PDT)",
+               (new Date(2014, 10, 1, 22, 59)).toString());
+  assertEquals("Sun, 02 Nov 2014 05:59:00 GMT",
+               (new Date(2014, 10, 1, 22, 59)).toUTCString());
+  assertEquals("Sat Nov 01 2014 23:00:00 GMT-0700 (PDT)",
+               (new Date(2014, 10, 1, 23, 0)).toString());
+  assertEquals("Sun, 02 Nov 2014 06:00:00 GMT",
+               (new Date(2014, 10, 1, 23, 0)).toUTCString());
+  assertEquals("Sat Nov 01 2014 23:59:00 GMT-0700 (PDT)",
+               (new Date(2014, 10, 1, 23, 59)).toString());
+  assertEquals("Sun, 02 Nov 2014 06:59:00 GMT",
+               (new Date(2014, 10, 1, 23, 59)).toUTCString());
+  assertEquals("Sun Nov 02 2014 00:00:00 GMT-0700 (PDT)",
+               (new Date(2014, 10, 2, 0, 0)).toString());
+  assertEquals("Sun, 02 Nov 2014 07:00:00 GMT",
+               (new Date(2014, 10, 2, 0, 0)).toUTCString());
+  assertEquals("Sun Nov 02 2014 00:59:00 GMT-0700 (PDT)",
+               (new Date(2014, 10, 2, 0, 59)).toString());
+  assertEquals("Sun, 02 Nov 2014 07:59:00 GMT",
+               (new Date(2014, 10, 2, 0, 59)).toUTCString());
+  assertEquals("Sun Nov 02 2014 01:00:00 GMT-0700 (PDT)",
+               (new Date(2014, 10, 2, 1, 0)).toString());
+  assertEquals("Sun, 02 Nov 2014 08:00:00 GMT",
+               (new Date(2014, 10, 2, 1, 0)).toUTCString());
+  assertEquals("Sun Nov 02 2014 01:59:00 GMT-0700 (PDT)",
+               (new Date(2014, 10, 2, 1, 59)).toString());
+  assertEquals("Sun, 02 Nov 2014 08:59:00 GMT",
+               (new Date(2014, 10, 2, 1, 59)).toUTCString());
+  assertEquals("Sun Nov 02 2014 02:00:00 GMT-0800 (PST)",
+               (new Date(2014, 10, 2, 2, 0)).toString());
+  assertEquals("Sun, 02 Nov 2014 10:00:00 GMT",
+               (new Date(2014, 10, 2, 2, 0)).toUTCString());
+  assertEquals("Sun Nov 02 2014 02:59:00 GMT-0800 (PST)",
+               (new Date(2014, 10, 2, 2, 59)).toString());
+  assertEquals("Sun, 02 Nov 2014 10:59:00 GMT",
+               (new Date(2014, 10, 2, 2, 59)).toUTCString());
+  assertEquals("Sun Nov 02 2014 03:00:00 GMT-0800 (PST)",
+               (new Date(2014, 10, 2, 3, 0)).toString());
+  assertEquals("Sun, 02 Nov 2014 11:00:00 GMT",
+               (new Date(2014, 10, 2, 3, 0)).toUTCString());
+  assertEquals("Sun Nov 02 2014 03:59:00 GMT-0800 (PST)",
+               (new Date(2014, 10, 2, 3, 59)).toString());
+  assertEquals("Sun, 02 Nov 2014 11:59:00 GMT",
+               (new Date(2014, 10, 2, 3, 59)).toUTCString());
+  assertEquals("Sun Nov 02 2014 04:00:00 GMT-0800 (PST)",
+               (new Date(2014, 10, 2, 4, 0)).toString());
+  assertEquals("Sun, 02 Nov 2014 12:00:00 GMT",
+               (new Date(2014, 10, 2, 4, 0)).toUTCString());
+}
=======================================
--- /dev/null
+++ /trunk/tools/sanitizers/tsan_suppressions.txt Fri Oct 10 00:05:16 2014 UTC
@@ -0,0 +1,6 @@
+# Suppressions for TSan v2
+# https://code.google.com/p/thread-sanitizer/wiki/Suppressions
+
+# Incorrectly detected lock cycles in test-lockers
+# https://code.google.com/p/thread-sanitizer/issues/detail?id=81
+deadlock:LockAndUnlockDifferentIsolatesThread::Run
=======================================
--- /trunk/test/perf-test/Collections/Collections.json Tue Sep 2 12:59:15 2014 UTC
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "path": ["."],
-  "main": "run.js",
-  "flags": ["--harmony-collections"],
-  "run_count": 5,
-  "units": "score",
-  "results_regexp": "^%s\\-Collections\\(Score\\): (.+)$",
-  "total": true,
-  "tests": [
-    {"name": "Map"},
-    {"name": "Set"},
-    {"name": "WeakMap"},
-    {"name": "WeakSet"}
-  ]
-}
=======================================
--- /trunk/test/perf-test/Collections/base.js   Tue Sep  2 12:59:15 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/test/perf-test/Collections/map.js    Tue Sep  2 12:59:15 2014 UTC
+++ /dev/null
@@ -1,81 +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.
-
-
-var MapBenchmark = new BenchmarkSuite('Map', [1000], [
-  new Benchmark('Set', false, false, 0, MapSet),
-  new Benchmark('Has', false, false, 0, MapHas, MapSetup, MapTearDown),
-  new Benchmark('Get', false, false, 0, MapGet, MapSetup, MapTearDown),
- new Benchmark('Delete', false, false, 0, MapDelete, MapSetup, MapTearDown), - new Benchmark('ForEach', false, false, 0, MapForEach, MapSetup, MapTearDown),
-]);
-
-
-var map;
-var N = 10;
-
-
-function MapSetup() {
-  map = new Map;
-  for (var i = 0; i < N; i++) {
-    map.set(i, i);
-  }
-}
-
-
-function MapTearDown() {
-  map = null;
-}
-
-
-function MapSet() {
-  MapSetup();
-  MapTearDown();
-}
-
-
-function MapHas() {
-  for (var i = 0; i < N; i++) {
-    if (!map.has(i)) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (map.has(i)) {
-      throw new Error();
-    }
-  }
-}
-
-
-function MapGet() {
-  for (var i = 0; i < N; i++) {
-    if (map.get(i) !== i) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (map.get(i) !== undefined) {
-      throw new Error();
-    }
-  }
-}
-
-
-function MapDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    map.delete(i);
-  }
-}
-
-
-function MapForEach() {
-  map.forEach(function(v, k) {
-    if (v !== k) {
-      throw new Error();
-    }
-  });
-}
=======================================
--- /trunk/test/perf-test/Collections/run.js    Tue Sep  2 12:59:15 2014 UTC
+++ /dev/null
@@ -1,30 +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.
-
-
-load('base.js');
-load('map.js');
-load('set.js');
-load('weakmap.js');
-load('weakset.js');
-
-
-var success = true;
-
-function PrintResult(name, result) {
-  print(name + '-Collections(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 });
=======================================
--- /trunk/test/perf-test/Collections/set.js    Tue Sep  2 12:59:15 2014 UTC
+++ /dev/null
@@ -1,66 +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.
-
-
-var SetBenchmark = new BenchmarkSuite('Set', [1000], [
-  new Benchmark('Add', false, false, 0, SetAdd),
-  new Benchmark('Has', false, false, 0, SetHas, SetSetup, SetTearDown),
- new Benchmark('Delete', false, false, 0, SetDelete, SetSetup, SetTearDown), - new Benchmark('ForEach', false, false, 0, SetForEach, SetSetup, SetTearDown),
-]);
-
-
-var set;
-var N = 10;
-
-
-function SetSetup() {
-  set = new Set;
-  for (var i = 0; i < N; i++) {
-    set.add(i);
-  }
-}
-
-
-function SetTearDown() {
-  map = null;
-}
-
-
-function SetAdd() {
-  SetSetup();
-  SetTearDown();
-}
-
-
-function SetHas() {
-  for (var i = 0; i < N; i++) {
-    if (!set.has(i)) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (set.has(i)) {
-      throw new Error();
-    }
-  }
-}
-
-
-function SetDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    set.delete(i);
-  }
-}
-
-
-function SetForEach() {
-  set.forEach(function(v, k) {
-    if (v !== k) {
-      throw new Error();
-    }
-  });
-}
=======================================
--- /trunk/test/perf-test/Collections/weakmap.js Tue Sep 2 12:59:15 2014 UTC
+++ /dev/null
@@ -1,80 +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.
-
-
-var MapBenchmark = new BenchmarkSuite('WeakMap', [1000], [
-  new Benchmark('Set', false, false, 0, WeakMapSet),
-  new Benchmark('Has', false, false, 0, WeakMapHas, WeakMapSetup,
-      WeakMapTearDown),
-  new Benchmark('Get', false, false, 0, WeakMapGet, WeakMapSetup,
-      WeakMapTearDown),
-  new Benchmark('Delete', false, false, 0, WeakMapDelete, WeakMapSetup,
-      WeakMapTearDown),
-]);
-
-
-var wm;
-var N = 10;
-var keys = [];
-
-
-for (var i = 0; i < N * 2; i++) {
-  keys[i] = {};
-}
-
-
-function WeakMapSetup() {
-  wm = new WeakMap;
-  for (var i = 0; i < N; i++) {
-    wm.set(keys[i], i);
-  }
-}
-
-
-function WeakMapTearDown() {
-  wm = null;
-}
-
-
-function WeakMapSet() {
-  WeakMapSetup();
-  WeakMapTearDown();
-}
-
-
-function WeakMapHas() {
-  for (var i = 0; i < N; i++) {
-    if (!wm.has(keys[i])) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (wm.has(keys[i])) {
-      throw new Error();
-    }
-  }
-}
-
-
-function WeakMapGet() {
-  for (var i = 0; i < N; i++) {
-    if (wm.get(keys[i]) !== i) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (wm.get(keys[i]) !== undefined) {
-      throw new Error();
-    }
-  }
-}
-
-
-function WeakMapDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    wm.delete(keys[i]);
-  }
-}
=======================================
--- /trunk/test/perf-test/Collections/weakset.js Tue Sep 2 12:59:15 2014 UTC
+++ /dev/null
@@ -1,64 +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.
-
-
-var SetBenchmark = new BenchmarkSuite('WeakSet', [1000], [
-  new Benchmark('Add', false, false, 0, WeakSetAdd),
-  new Benchmark('Has', false, false, 0, WeakSetHas, WeakSetSetup,
-      WeakSetTearDown),
-  new Benchmark('Delete', false, false, 0, WeakSetDelete, WeakSetSetup,
-      WeakSetTearDown),
-]);
-
-
-var ws;
-var N = 10;
-var keys = [];
-
-
-for (var i = 0; i < N * 2; i++) {
-  keys[i] = {};
-}
-
-
-function WeakSetSetup() {
-  ws = new WeakSet;
-  for (var i = 0; i < N; i++) {
-    ws.add(keys[i]);
-  }
-}
-
-
-function WeakSetTearDown() {
-  ws = null;
-}
-
-
-function WeakSetAdd() {
-  WeakSetSetup();
-  WeakSetTearDown();
-}
-
-
-function WeakSetHas() {
-  for (var i = 0; i < N; i++) {
-    if (!ws.has(keys[i])) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (ws.has(keys[i])) {
-      throw new Error();
-    }
-  }
-}
-
-
-function WeakSetDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    ws.delete(keys[i]);
-  }
-}
=======================================
--- /trunk/AUTHORS      Wed Oct  1 00:05:35 2014 UTC
+++ /trunk/AUTHORS      Fri Oct 10 00:05:16 2014 UTC
@@ -27,6 +27,7 @@
 Baptiste Afsa <[email protected]>
 Bert Belder <[email protected]>
 Burcu Dogan <[email protected]>
+Caitlin Potter <[email protected]>
 Craig Schlenter <[email protected]>
 Chunyang Dai <[email protected]>
 Daniel Andersson <[email protected]>
=======================================
--- /trunk/ChangeLog    Thu Oct  9 00:05:16 2014 UTC
+++ /trunk/ChangeLog    Fri Oct 10 00:05:16 2014 UTC
@@ -1,3 +1,13 @@
+2014-10-10: Version 3.30.7
+
+ Fix computation of UTC time from local time at DST change points (issue
+        3116, Chromium issues 415424, 417640).
+
+        Convert `obj` ToObject in Object.keys() (issue 3587).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-10-09: Version 3.30.6

         Update unicode to 7.0.0 (issue 2892).
=======================================
--- /trunk/build/toolchain.gypi Thu Oct  9 00:05:16 2014 UTC
+++ /trunk/build/toolchain.gypi Fri Oct 10 00:05:16 2014 UTC
@@ -302,7 +302,7 @@
                     'cflags': ['-mfp32'],
                   }],
                   ['mips_arch_variant=="r6"', {
-                    'cflags!': ['-mfp32'],
+                    'cflags!': ['-mfp32', '-mfpxx'],
                     'cflags': ['-mips32r6', '-Wa,-mips32r6'],
                     'ldflags': [
                       '-mips32r6',
@@ -312,14 +312,17 @@
                   }],
                   ['mips_arch_variant=="r2"', {
                     'cflags': ['-mips32r2', '-Wa,-mips32r2'],
+                    'ldflags': ['-mips32r2'],
                   }],
                   ['mips_arch_variant=="r1"', {
-                    'cflags!': ['-mfp64'],
+                    'cflags!': ['-mfp64', '-mfpxx'],
                     'cflags': ['-mips32', '-Wa,-mips32'],
+                    'ldflags': ['-mips32'],
                   }],
                   ['mips_arch_variant=="rx"', {
-                    'cflags!': ['-mfp64'],
-                    'cflags': ['-mips32', '-Wa,-mips32'],
+                    'cflags!': ['-mfp64', '-mfp32'],
+                    'cflags': ['-mips32', '-Wa,-mips32', '-mfpxx'],
+                    'ldflags': ['-mips32'],
                   }],
                 ],
               }],
@@ -400,7 +403,7 @@
                     'cflags': ['-mfp32'],
                   }],
                   ['mips_arch_variant=="r6"', {
-                    'cflags!': ['-mfp32'],
+                    'cflags!': ['-mfp32', '-mfpxx'],
                     'cflags': ['-mips32r6', '-Wa,-mips32r6'],
                     'ldflags': [
                       '-mips32r6',
@@ -410,17 +413,20 @@
                   }],
                   ['mips_arch_variant=="r2"', {
                     'cflags': ['-mips32r2', '-Wa,-mips32r2'],
+                    'ldflags': ['-mips32r2'],
                   }],
                   ['mips_arch_variant=="r1"', {
-                    'cflags!': ['-mfp64'],
+                    'cflags!': ['-mfp64', '-mfpxx'],
                     'cflags': ['-mips32', '-Wa,-mips32'],
+                    'ldflags': ['-mips32'],
                   }],
                   ['mips_arch_variant=="rx"', {
-                    'cflags!': ['-mfp64'],
-                    'cflags': ['-mips32', '-Wa,-mips32'],
+                    'cflags!': ['-mfp64', '-mfp32'],
+                    'cflags': ['-mips32', '-Wa,-mips32', '-mfpxx'],
+                    'ldflags': ['-mips32'],
                   }],
                   ['mips_arch_variant=="loongson"', {
-                    'cflags!': ['-mfp64'],
+                    'cflags!': ['-mfp64', '-mfp32', '-mfpxx'],
                     'cflags': ['-mips3', '-Wa,-mips3'],
                   }],
                 ],
=======================================
--- /trunk/include/v8-platform.h        Wed Oct  8 00:05:11 2014 UTC
+++ /trunk/include/v8-platform.h        Fri Oct 10 00:05:16 2014 UTC
@@ -56,7 +56,6 @@
    */
   virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0;

-
   /**
* Monotonically increasing time in seconds from an arbitrary fixed point in
    * the past. This function is expected to return at least
@@ -64,11 +63,7 @@
    * it is recommended that the fixed point be no further in the past than
    * the epoch.
    **/
-  virtual double MonotonicallyIncreasingTime() {
-    // TODO(rmcilroy): Remove this default implementation when Chromium
-    // change has landed.
-    return 0;
-  }
+  virtual double MonotonicallyIncreasingTime() = 0;
 };

 }  // namespace v8
=======================================
--- /trunk/src/arm/codegen-arm.cc       Thu Sep 11 00:05:22 2014 UTC
+++ /trunk/src/arm/codegen-arm.cc       Fri Oct 10 00:05:16 2014 UTC
@@ -604,8 +604,22 @@
   __ add(src_elements, elements,
          Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
   __ add(dst_elements, array, Operand(FixedArray::kHeaderSize));
-  __ add(array, array, Operand(kHeapObjectTag));
   __ add(dst_end, dst_elements, Operand(length, LSL, 1));
+
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+  __ b(&initialization_loop_entry);
+  __ bind(&initialization_loop);
+  __ str(scratch, MemOperand(dst_elements, kPointerSize, PostIndex));
+  __ bind(&initialization_loop_entry);
+  __ cmp(dst_elements, dst_end);
+  __ b(lt, &initialization_loop);
+
+  __ add(dst_elements, array, Operand(FixedArray::kHeaderSize));
+  __ add(array, array, Operand(kHeapObjectTag));
   __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
   // Using offsetted addresses in src_elements to fully take advantage of
   // post-indexing.
=======================================
--- /trunk/src/arm/full-codegen-arm.cc  Thu Oct  9 00:05:16 2014 UTC
+++ /trunk/src/arm/full-codegen-arm.cc  Fri Oct 10 00:05:16 2014 UTC
@@ -1889,22 +1889,8 @@

   Comment cmnt(masm_, "[ Assignment");

- // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind {
-    VARIABLE,
-    NAMED_PROPERTY,
-    KEYED_PROPERTY,
-    NAMED_SUPER_PROPERTY
-  };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-                      ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
-                                                   : NAMED_PROPERTY)
-                      : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);

   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1930,6 +1916,21 @@
         __ Push(scratch);
         __ Push(result_register());
       }
+      break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch = r1;
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ Push(result_register());
+      }
       break;
     case KEYED_PROPERTY:
       if (expr->is_compound()) {
@@ -1962,6 +1963,10 @@
           EmitNamedSuperPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -2012,6 +2017,10 @@
       EmitNamedSuperPropertyStore(property);
       context()->Plug(r0);
       break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(r0);
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2657,12 +2666,25 @@
   Literal* key = prop->key()->AsLiteral();
   DCHECK(key != NULL);

-  __ Push(r0);
   __ Push(key->value());
+  __ Push(r0);
   __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
                                           : Runtime::kStoreToSuper_Sloppy),
                  4);
 }
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // r0 : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(r0);
+ __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict + : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}


 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
@@ -4436,24 +4458,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());

-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind {
-    VARIABLE,
-    NAMED_PROPERTY,
-    KEYED_PROPERTY,
-    NAMED_SUPER_PROPERTY
-  };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName())
- ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
-            : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);

   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4466,27 +4472,55 @@
       __ mov(ip, Operand(Smi::FromInt(0)));
       __ push(ip);
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else if (assign_type == NAMED_SUPER_PROPERTY) {
-      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
-      EmitLoadHomeObject(prop->obj()->AsSuperReference());
-      __ Push(result_register());
-      const Register scratch = r1;
-      __ ldr(scratch, MemOperand(sp, kPointerSize));
-      __ Push(scratch);
-      __ Push(result_register());
-      EmitNamedSuperPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ ldr(LoadDescriptor::ReceiverRegister(),
-             MemOperand(sp, 1 * kPointerSize));
-      __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        const Register scratch = r1;
+        __ ldr(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch);
+        __ Push(result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(result_register());
+        const Register scratch = r1;
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ Push(result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ ldr(LoadDescriptor::ReceiverRegister(),
+               MemOperand(sp, 1 * kPointerSize));
+        __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }

@@ -4526,6 +4560,9 @@
           case KEYED_PROPERTY:
             __ str(r0, MemOperand(sp, 2 * kPointerSize));
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ str(r0, MemOperand(sp, 3 * kPointerSize));
+            break;
         }
       }
     }
@@ -4559,6 +4596,9 @@
         case KEYED_PROPERTY:
           __ str(r0, MemOperand(sp, 2 * kPointerSize));
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ str(r0, MemOperand(sp, 3 * kPointerSize));
+          break;
       }
     }
   }
@@ -4620,6 +4660,17 @@
         if (!context()->IsEffect()) {
           context()->PlugTOS();
         }
+      } else {
+        context()->Plug(r0);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
       } else {
         context()->Plug(r0);
       }
=======================================
--- /trunk/src/arm64/codegen-arm64.cc   Thu Sep 11 00:05:22 2014 UTC
+++ /trunk/src/arm64/codegen-arm64.cc   Fri Oct 10 00:05:16 2014 UTC
@@ -290,15 +290,28 @@
   Register src_elements = x10;
   Register dst_elements = x11;
   Register dst_end = x12;
+  Register the_hole = x14;
+  __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
   __ Add(src_elements, elements,
          FixedDoubleArray::kHeaderSize - kHeapObjectTag);
+  __ Add(dst_elements, array, FixedArray::kHeaderSize);
+  __ Add(dst_end, dst_elements, Operand(length, LSL, kPointerSizeLog2));
+
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ B(&initialization_loop_entry);
+  __ bind(&initialization_loop);
+  __ Str(the_hole, MemOperand(dst_elements, kPointerSize, PostIndex));
+  __ bind(&initialization_loop_entry);
+  __ Cmp(dst_elements, dst_end);
+  __ B(lt, &initialization_loop);
+
   __ Add(dst_elements, array, FixedArray::kHeaderSize);
   __ Add(array, array, kHeapObjectTag);
-  __ Add(dst_end, dst_elements, Operand(length, LSL, kPointerSizeLog2));

-  Register the_hole = x14;
   Register heap_num_map = x15;
-  __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
   __ LoadRoot(heap_num_map, Heap::kHeapNumberMapRootIndex);

   Label entry;
=======================================
--- /trunk/src/arm64/full-codegen-arm64.cc      Thu Oct  9 00:05:16 2014 UTC
+++ /trunk/src/arm64/full-codegen-arm64.cc      Fri Oct 10 00:05:16 2014 UTC
@@ -1868,22 +1868,8 @@

   Comment cmnt(masm_, "[ Assignment");

- // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind {
-    VARIABLE,
-    NAMED_PROPERTY,
-    KEYED_PROPERTY,
-    NAMED_SUPER_PROPERTY
-  };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-                      ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
-                                                   : NAMED_PROPERTY)
-                      : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);

   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1908,6 +1894,20 @@
         __ Peek(scratch, kPointerSize);
         __ Push(scratch, result_register());
       }
+      break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch1 = x10;
+        const Register scratch2 = x11;
+        __ Peek(scratch1, 2 * kPointerSize);
+        __ Peek(scratch2, kPointerSize);
+        __ Push(scratch1, scratch2, result_register());
+      }
       break;
     case KEYED_PROPERTY:
       if (expr->is_compound()) {
@@ -1939,6 +1939,10 @@
           EmitNamedSuperPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1989,6 +1993,10 @@
       EmitNamedSuperPropertyStore(property);
       context()->Plug(x0);
       break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(x0);
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2320,12 +2328,25 @@
   Literal* key = prop->key()->AsLiteral();
   DCHECK(key != NULL);

+  __ Push(key->value());
   __ Push(x0);
-  __ Push(key->value());
   __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
                                           : Runtime::kStoreToSuper_Sloppy),
                  4);
 }
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // x0 : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(x0);
+ __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict + : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}


 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
@@ -4101,24 +4122,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());

-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind {
-    VARIABLE,
-    NAMED_PROPERTY,
-    KEYED_PROPERTY,
-    NAMED_SUPER_PROPERTY
-  };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName())
- ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
-            : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);

   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4130,26 +4135,52 @@
     if (expr->is_postfix() && !context()->IsEffect()) {
       __ Push(xzr);
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ Peek(LoadDescriptor::ReceiverRegister(), 0);
-      EmitNamedPropertyLoad(prop);
-    } else if (assign_type == NAMED_SUPER_PROPERTY) {
-      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
-      EmitLoadHomeObject(prop->obj()->AsSuperReference());
-      __ Push(result_register());
-      const Register scratch = x10;
-      __ Peek(scratch, kPointerSize);
-      __ Push(scratch, result_register());
-      EmitNamedSuperPropertyLoad(prop);
-    } else {
-      // KEYED_PROPERTY
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
-      __ Peek(LoadDescriptor::NameRegister(), 0);
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ Peek(LoadDescriptor::ReceiverRegister(), 0);
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        const Register scratch = x10;
+        __ Peek(scratch, kPointerSize);
+        __ Push(scratch, result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(result_register());
+        const Register scratch1 = x10;
+        const Register scratch2 = x11;
+        __ Peek(scratch1, 2 * kPointerSize);
+        __ Peek(scratch2, kPointerSize);
+        __ Push(scratch1, scratch2, result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
+        __ Peek(LoadDescriptor::NameRegister(), 0);
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }

@@ -4189,6 +4220,9 @@
           case KEYED_PROPERTY:
             __ Poke(x0, kPointerSize * 2);
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ Poke(x0, kPointerSize * 3);
+            break;
         }
       }
     }
@@ -4222,6 +4256,9 @@
         case KEYED_PROPERTY:
           __ Poke(x0, 2 * kXRegSize);
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ Poke(x0, 3 * kXRegSize);
+          break;
       }
     }
   }
@@ -4285,6 +4322,17 @@
         if (!context()->IsEffect()) {
           context()->PlugTOS();
         }
+      } else {
+        context()->Plug(x0);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
       } else {
         context()->Plug(x0);
       }
=======================================
--- /trunk/src/ast.h    Thu Oct  9 00:05:16 2014 UTC
+++ /trunk/src/ast.h    Fri Oct 10 00:05:16 2014 UTC
@@ -184,7 +184,7 @@
   // For generating IDs for AstNodes.
   class IdGen {
    public:
-    explicit IdGen(int id = 0) : id_(id) {}
+    IdGen() : id_(BailoutId::FirstUsable().ToInt()) {}

     int GetNextId() { return ReserveIdRange(1); }
     int ReserveIdRange(int n) {
@@ -195,6 +195,8 @@

    private:
     int id_;
+
+    DISALLOW_COPY_AND_ASSIGN(IdGen);
   };

 #define DECLARE_TYPE_ENUM(type) k##type,
=======================================
--- /trunk/src/base/bits.h      Thu Sep 11 00:05:22 2014 UTC
+++ /trunk/src/base/bits.h      Fri Oct 10 00:05:16 2014 UTC
@@ -19,7 +19,7 @@
 namespace bits {

 // CountPopulation32(value) returns the number of bits set in |value|.
-inline uint32_t CountPopulation32(uint32_t value) {
+inline unsigned CountPopulation32(uint32_t value) {
 #if V8_HAS_BUILTIN_POPCOUNT
   return __builtin_popcount(value);
 #else
@@ -28,20 +28,31 @@
   value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f);
   value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff);
   value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff);
-  return value;
+  return static_cast<unsigned>(value);
 #endif
 }
+
+
+// CountPopulation64(value) returns the number of bits set in |value|.
+inline unsigned CountPopulation64(uint64_t value) {
+#if V8_HAS_BUILTIN_POPCOUNT
+  return __builtin_popcountll(value);
+#else
+  return CountPopulation32(static_cast<uint32_t>(value)) +
+         CountPopulation32(static_cast<uint32_t>(value >> 32));
+#endif
+}


// CountLeadingZeros32(value) returns the number of zero bits following the most // significant 1 bit in |value| if |value| is non-zero, otherwise it returns 32.
-inline uint32_t CountLeadingZeros32(uint32_t value) {
+inline unsigned CountLeadingZeros32(uint32_t value) {
 #if V8_HAS_BUILTIN_CLZ
   return value ? __builtin_clz(value) : 32;
 #elif V8_CC_MSVC
   unsigned long result;  // NOLINT(runtime/int)
   if (!_BitScanReverse(&result, value)) return 32;
-  return static_cast<uint32_t>(31 - result);
+  return static_cast<unsigned>(31 - result);
 #else
   value = value | (value >> 1);
   value = value | (value >> 2);
@@ -51,18 +62,35 @@
   return CountPopulation32(~value);
 #endif
 }
+
+
+// CountLeadingZeros64(value) returns the number of zero bits following the most +// significant 1 bit in |value| if |value| is non-zero, otherwise it returns 64.
+inline unsigned CountLeadingZeros64(uint64_t value) {
+#if V8_HAS_BUILTIN_CLZ
+  return value ? __builtin_clzll(value) : 64;
+#else
+  value = value | (value >> 1);
+  value = value | (value >> 2);
+  value = value | (value >> 4);
+  value = value | (value >> 8);
+  value = value | (value >> 16);
+  value = value | (value >> 32);
+  return CountPopulation64(~value);
+#endif
+}


// CountTrailingZeros32(value) returns the number of zero bits preceding the
 // least significant 1 bit in |value| if |value| is non-zero, otherwise it
 // returns 32.
-inline uint32_t CountTrailingZeros32(uint32_t value) {
+inline unsigned CountTrailingZeros32(uint32_t value) {
 #if V8_HAS_BUILTIN_CTZ
   return value ? __builtin_ctz(value) : 32;
 #elif V8_CC_MSVC
   unsigned long result;  // NOLINT(runtime/int)
   if (!_BitScanForward(&result, value)) return 32;
-  return static_cast<uint32_t>(result);
+  return static_cast<unsigned>(result);
 #else
   if (value == 0) return 32;
   unsigned count = 0;
@@ -71,6 +99,22 @@
   return count;
 #endif
 }
+
+
+// CountTrailingZeros64(value) returns the number of zero bits preceding the
+// least significant 1 bit in |value| if |value| is non-zero, otherwise it
+// returns 64.
+inline unsigned CountTrailingZeros64(uint64_t value) {
+#if V8_HAS_BUILTIN_CTZ
+  return value ? __builtin_ctzll(value) : 64;
+#else
+  if (value == 0) return 64;
+  unsigned count = 0;
+  for (value ^= value - 1; value >>= 1; ++count)
+    ;
+  return count;
+#endif
+}


 // Returns true iff |value| is a power of 2.
=======================================
--- /trunk/src/base/cpu.cc      Wed Oct  8 00:05:11 2014 UTC
+++ /trunk/src/base/cpu.cc      Fri Oct 10 00:05:16 2014 UTC
@@ -121,13 +121,18 @@
 int __detect_fp64_mode(void) {
   double result = 0;
   // Bit representation of (double)1 is 0x3FF0000000000000.
-  asm(
-    "lui $t0, 0x3FF0\n\t"
-    "ldc1 $f0, %0\n\t"
-    "mtc1 $t0, $f1\n\t"
-    "sdc1 $f0, %0\n\t"
-    : "+m" (result)
-    : : "t0", "$f0", "$f1", "memory");
+  __asm__ volatile(
+      ".set push\n\t"
+      ".set noreorder\n\t"
+      ".set oddspreg\n\t"
+      "lui $t0, 0x3FF0\n\t"
+      "ldc1 $f0, %0\n\t"
+      "mtc1 $t0, $f1\n\t"
+      "sdc1 $f0, %0\n\t"
+      ".set pop\n\t"
+      : "+m"(result)
+      :
+      : "t0", "$f0", "$f1", "memory");

   return !(result == 1);
 }
@@ -135,9 +140,22 @@

 int __detect_mips_arch_revision(void) {
// TODO(dusmil): Do the specific syscall as soon as it is implemented in mips
-  // kernel. Currently fail-back to the least common denominator which is
-  // mips32 revision 1.
-  return 1;
+  // kernel.
+  uint32_t result = 0;
+  __asm__ volatile(
+      "move $v0, $zero\n\t"
+      // Encoding for "addi $v0, $v0, 1" on non-r6,
+      // which is encoding for "bovc $v0, %v0, 1" on r6.
+ // Use machine code directly to avoid compilation errors with different
+      // toolchains and maintain compatibility.
+      ".word 0x20420001\n\t"
+      "sw $v0, %0\n\t"
+      : "=m"(result)
+      :
+      : "v0", "memory");
+  // Result is 0 on r6 architectures, 1 on other architecture revisions.
+  // Fall-back to the least common denominator which is mips32 revision 1.
+  return result ? 1 : 6;
 }
 #endif

=======================================
--- /trunk/src/base/utils/random-number-generator.cc Fri Sep 26 00:05:23 2014 UTC +++ /trunk/src/base/utils/random-number-generator.cc Fri Oct 10 00:05:16 2014 UTC
@@ -100,6 +100,13 @@
   return ((static_cast<int64_t>(Next(26)) << 27) + Next(27)) /
       static_cast<double>(static_cast<int64_t>(1) << 53);
 }
+
+
+int64_t RandomNumberGenerator::NextInt64() {
+  uint64_t lo = bit_cast<unsigned>(Next(32));
+  uint64_t hi = bit_cast<unsigned>(Next(32));
+  return lo | (hi << 32);
+}


 void RandomNumberGenerator::NextBytes(void* buffer, size_t buflen) {
=======================================
--- /trunk/src/base/utils/random-number-generator.h Tue Sep 23 08:38:19 2014 UTC +++ /trunk/src/base/utils/random-number-generator.h Fri Oct 10 00:05:16 2014 UTC
@@ -68,6 +68,13 @@
   // (exclusive), is pseudorandomly generated and returned.
   double NextDouble() WARN_UNUSED_RESULT;

+ // Returns the next pseudorandom, uniformly distributed int64 value from this + // random number generator's sequence. The general contract of | NextInt64()|
+  // is that one 64-bit int value is pseudorandomly generated and returned.
+ // All 2^64 possible integer values are produced with (approximately) equal
+  // probability.
+  int64_t NextInt64() WARN_UNUSED_RESULT;
+
   // Fills the elements of a specified array of bytes with random numbers.
   void NextBytes(void* buffer, size_t buflen);

=======================================
--- /trunk/src/builtins.cc      Tue Sep 30 00:05:10 2014 UTC
+++ /trunk/src/builtins.cc      Fri Oct 10 00:05:16 2014 UTC
@@ -1312,15 +1312,25 @@
 static void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
   NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
 }
+
+
+static void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) {
+  KeyedStoreIC::GenerateGeneric(masm, SLOPPY, kMissOnMissingHandler);
+}
+
+
+static void Generate_KeyedStoreIC_Megamorphic_Strict(MacroAssembler* masm) {
+  KeyedStoreIC::GenerateGeneric(masm, STRICT, kMissOnMissingHandler);
+}


 static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateGeneric(masm, SLOPPY);
+ KeyedStoreIC::GenerateGeneric(masm, SLOPPY, kCallRuntimeOnMissingHandler);
 }


 static void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) {
-  KeyedStoreIC::GenerateGeneric(masm, STRICT);
+ KeyedStoreIC::GenerateGeneric(masm, STRICT, kCallRuntimeOnMissingHandler);
 }


=======================================
--- /trunk/src/builtins.h       Wed Sep 24 00:05:07 2014 UTC
+++ /trunk/src/builtins.h       Fri Oct 10 00:05:16 2014 UTC
@@ -95,12 +95,15 @@
V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED, kNoExtraICState) \ V(KeyedStoreIC_PreMonomorphic, KEYED_STORE_IC, PREMONOMORPHIC, \ kNoExtraICState) \ + V(KeyedStoreIC_Megamorphic, KEYED_STORE_IC, MEGAMORPHIC, kNoExtraICState) \ V(KeyedStoreIC_Generic, KEYED_STORE_IC, GENERIC, kNoExtraICState) \ \ V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED, \ StoreIC::kStrictModeState) \ V(KeyedStoreIC_PreMonomorphic_Strict, KEYED_STORE_IC, PREMONOMORPHIC, \ StoreIC::kStrictModeState) \ + V(KeyedStoreIC_Megamorphic_Strict, KEYED_STORE_IC, MEGAMORPHIC, \ + StoreIC::kStrictModeState) \ V(KeyedStoreIC_Generic_Strict, KEYED_STORE_IC, GENERIC, \ StoreIC::kStrictModeState) \ V(KeyedStoreIC_SloppyArguments, KEYED_STORE_IC, MONOMORPHIC, \
=======================================
--- /trunk/src/compiler/arm64/code-generator-arm64.cc Thu Oct 2 00:05:29 2014 UTC +++ /trunk/src/compiler/arm64/code-generator-arm64.cc Fri Oct 10 00:05:16 2014 UTC
@@ -319,22 +319,22 @@
__ Sub(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
       }
       break;
-    case kArm64Shl:
+    case kArm64Lsl:
       ASSEMBLE_SHIFT(Lsl, 64);
       break;
-    case kArm64Shl32:
+    case kArm64Lsl32:
       ASSEMBLE_SHIFT(Lsl, 32);
       break;
-    case kArm64Shr:
+    case kArm64Lsr:
       ASSEMBLE_SHIFT(Lsr, 64);
       break;
-    case kArm64Shr32:
+    case kArm64Lsr32:
       ASSEMBLE_SHIFT(Lsr, 32);
       break;
-    case kArm64Sar:
+    case kArm64Asr:
       ASSEMBLE_SHIFT(Asr, 64);
       break;
-    case kArm64Sar32:
+    case kArm64Asr32:
       ASSEMBLE_SHIFT(Asr, 32);
       break;
     case kArm64Ror:
@@ -349,6 +349,14 @@
     case kArm64Sxtw:
       __ Sxtw(i.OutputRegister(), i.InputRegister32(0));
       break;
+    case kArm64Ubfx:
+      __ Ubfx(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+              i.InputInt8(2));
+      break;
+    case kArm64Ubfx32:
+      __ Ubfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt8(1),
+              i.InputInt8(2));
+      break;
     case kArm64Claim: {
       int words = MiscField::decode(instr->opcode());
       __ Claim(words);
=======================================
--- /trunk/src/compiler/arm64/instruction-codes-arm64.h Tue Sep 30 00:05:10 2014 UTC +++ /trunk/src/compiler/arm64/instruction-codes-arm64.h Fri Oct 10 00:05:16 2014 UTC
@@ -54,16 +54,18 @@
   V(Arm64Not32)                    \
   V(Arm64Neg)                      \
   V(Arm64Neg32)                    \
-  V(Arm64Shl)                      \
-  V(Arm64Shl32)                    \
-  V(Arm64Shr)                      \
-  V(Arm64Shr32)                    \
-  V(Arm64Sar)                      \
-  V(Arm64Sar32)                    \
+  V(Arm64Lsl)                      \
+  V(Arm64Lsl32)                    \
+  V(Arm64Lsr)                      \
+  V(Arm64Lsr32)                    \
+  V(Arm64Asr)                      \
+  V(Arm64Asr32)                    \
   V(Arm64Ror)                      \
   V(Arm64Ror32)                    \
   V(Arm64Mov32)                    \
   V(Arm64Sxtw)                     \
+  V(Arm64Ubfx)                     \
+  V(Arm64Ubfx32)                   \
   V(Arm64Claim)                    \
   V(Arm64Poke)                     \
   V(Arm64PokePairZero)             \
=======================================
--- /trunk/src/compiler/arm64/instruction-selector-arm64.cc Wed Oct 8 00:05:11 2014 UTC +++ /trunk/src/compiler/arm64/instruction-selector-arm64.cc Fri Oct 10 00:05:16 2014 UTC
@@ -355,7 +355,29 @@


 void InstructionSelector::VisitWord32And(Node* node) {
+  Arm64OperandGenerator g(this);
   Int32BinopMatcher m(node);
+  if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
+      m.right().HasValue()) {
+    uint32_t mask = m.right().Value();
+    uint32_t mask_width = base::bits::CountPopulation32(mask);
+    uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+    if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
+ // The mask must be contiguous, and occupy the least-significant bits.
+      DCHECK_EQ(0, base::bits::CountTrailingZeros32(mask));
+
+ // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
+      // significant bits.
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsInRange(0, 31)) {
+        Emit(kArm64Ubfx32, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()),
+ g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
+        return;
+      }
+      // Other cases fall through to the normal And operation.
+    }
+  }
   VisitLogical<Int32BinopMatcher>(
       this, node, &m, kArm64And32, CanCover(node, m.left().node()),
       CanCover(node, m.right().node()), kLogical32Imm);
@@ -363,7 +385,29 @@


 void InstructionSelector::VisitWord64And(Node* node) {
+  Arm64OperandGenerator g(this);
   Int64BinopMatcher m(node);
+  if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) &&
+      m.right().HasValue()) {
+    uint64_t mask = m.right().Value();
+    uint64_t mask_width = base::bits::CountPopulation64(mask);
+    uint64_t mask_msb = base::bits::CountLeadingZeros64(mask);
+    if ((mask_width != 0) && (mask_msb + mask_width == 64)) {
+ // The mask must be contiguous, and occupy the least-significant bits.
+      DCHECK_EQ(0, base::bits::CountTrailingZeros64(mask));
+
+ // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
+      // significant bits.
+      Int64BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsInRange(0, 63)) {
+        Emit(kArm64Ubfx, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()),
+ g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
+        return;
+      }
+      // Other cases fall through to the normal And operation.
+    }
+  }
   VisitLogical<Int64BinopMatcher>(
       this, node, &m, kArm64And, CanCover(node, m.left().node()),
       CanCover(node, m.right().node()), kLogical64Imm);
@@ -403,32 +447,72 @@


 void InstructionSelector::VisitWord32Shl(Node* node) {
-  VisitRRO(this, kArm64Shl32, node, kShift32Imm);
+  VisitRRO(this, kArm64Lsl32, node, kShift32Imm);
 }


 void InstructionSelector::VisitWord64Shl(Node* node) {
-  VisitRRO(this, kArm64Shl, node, kShift64Imm);
+  VisitRRO(this, kArm64Lsl, node, kShift64Imm);
 }


 void InstructionSelector::VisitWord32Shr(Node* node) {
-  VisitRRO(this, kArm64Shr32, node, kShift32Imm);
+  Arm64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) {
+    int32_t lsb = m.right().Value();
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      uint32_t mask = (mleft.right().Value() >> lsb) << lsb;
+      uint32_t mask_width = base::bits::CountPopulation32(mask);
+      uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+ // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is
+      // shifted into the least-significant bits.
+      if ((mask_msb + mask_width + lsb) == 32) {
+        DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask));
+        Emit(kArm64Ubfx32, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+    }
+  }
+  VisitRRO(this, kArm64Lsr32, node, kShift32Imm);
 }


 void InstructionSelector::VisitWord64Shr(Node* node) {
-  VisitRRO(this, kArm64Shr, node, kShift64Imm);
+  Arm64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) {
+    int64_t lsb = m.right().Value();
+    Int64BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+ // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is
+      // shifted into the least-significant bits.
+      uint64_t mask = (mleft.right().Value() >> lsb) << lsb;
+      uint64_t mask_width = base::bits::CountPopulation64(mask);
+      uint64_t mask_msb = base::bits::CountLeadingZeros64(mask);
+      if ((mask_msb + mask_width + lsb) == 64) {
+        DCHECK_EQ(lsb, base::bits::CountTrailingZeros64(mask));
+        Emit(kArm64Ubfx, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+    }
+  }
+  VisitRRO(this, kArm64Lsr, node, kShift64Imm);
 }


 void InstructionSelector::VisitWord32Sar(Node* node) {
-  VisitRRO(this, kArm64Sar32, node, kShift32Imm);
+  VisitRRO(this, kArm64Asr32, node, kShift32Imm);
 }


 void InstructionSelector::VisitWord64Sar(Node* node) {
-  VisitRRO(this, kArm64Sar, node, kShift64Imm);
+  VisitRRO(this, kArm64Asr, node, kShift64Imm);
 }


=======================================
--- /trunk/src/compiler/ia32/code-generator-ia32.cc Thu Oct 9 00:05:16 2014 UTC +++ /trunk/src/compiler/ia32/code-generator-ia32.cc Fri Oct 10 00:05:16 2014 UTC
@@ -249,7 +249,7 @@
       __ idiv(i.InputOperand(1));
       break;
     case kIA32Udiv:
-      __ xor_(edx, edx);
+      __ Move(edx, Immediate(0));
       __ div(i.InputOperand(1));
       break;
     case kIA32Not:
@@ -552,7 +552,7 @@
   switch (condition) {
     case kUnorderedEqual:
       __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(0));
+      __ Move(reg, Immediate(0));
       __ jmp(&done, Label::kNear);
     // Fall through.
     case kEqual:
@@ -580,7 +580,7 @@
       break;
     case kUnorderedLessThan:
       __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(0));
+      __ Move(reg, Immediate(0));
       __ jmp(&done, Label::kNear);
     // Fall through.
     case kUnsignedLessThan:
@@ -596,7 +596,7 @@
       break;
     case kUnorderedLessThanOrEqual:
       __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(0));
+      __ Move(reg, Immediate(0));
       __ jmp(&done, Label::kNear);
     // Fall through.
     case kUnsignedLessThanOrEqual:
@@ -626,7 +626,7 @@
     // Emit a branch to set a register to either 1 or 0.
     Label set;
     __ j(cc, &set, Label::kNear);
-    __ mov(reg, Immediate(0));
+    __ Move(reg, Immediate(0));
     __ jmp(&done, Label::kNear);
     __ bind(&set);
     __ mov(reg, Immediate(1));
@@ -899,38 +899,35 @@
       }
     } else if (destination->IsRegister()) {
       Register dst = g.ToRegister(destination);
-      __ mov(dst, g.ToImmediate(source));
+      __ Move(dst, g.ToImmediate(source));
     } else if (destination->IsStackSlot()) {
       Operand dst = g.ToOperand(destination);
-      __ mov(dst, g.ToImmediate(source));
+      __ Move(dst, g.ToImmediate(source));
     } else if (src_constant.type() == Constant::kFloat32) {
       // TODO(turbofan): Can we do better here?
-      Immediate src(bit_cast<int32_t>(src_constant.ToFloat32()));
+      uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32());
       if (destination->IsDoubleRegister()) {
         XMMRegister dst = g.ToDoubleRegister(destination);
-        __ push(Immediate(src));
-        __ movss(dst, Operand(esp, 0));
-        __ add(esp, Immediate(kDoubleSize / 2));
+        __ Move(dst, src);
       } else {
         DCHECK(destination->IsDoubleStackSlot());
         Operand dst = g.ToOperand(destination);
-        __ mov(dst, src);
+        __ Move(dst, Immediate(src));
       }
     } else {
       DCHECK_EQ(Constant::kFloat64, src_constant.type());
-      double v = src_constant.ToFloat64();
-      uint64_t int_val = bit_cast<uint64_t, double>(v);
-      int32_t lower = static_cast<int32_t>(int_val);
-      int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt);
+      uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
+      uint32_t lower = static_cast<uint32_t>(src);
+      uint32_t upper = static_cast<uint32_t>(src >> 32);
       if (destination->IsDoubleRegister()) {
         XMMRegister dst = g.ToDoubleRegister(destination);
-        __ Move(dst, v);
+        __ Move(dst, src);
       } else {
         DCHECK(destination->IsDoubleStackSlot());
         Operand dst0 = g.ToOperand(destination);
         Operand dst1 = g.HighOperand(destination);
-        __ mov(dst0, Immediate(lower));
-        __ mov(dst1, Immediate(upper));
+        __ Move(dst0, Immediate(lower));
+        __ Move(dst1, Immediate(upper));
       }
     }
   } else if (source->IsDoubleRegister()) {
=======================================
--- /trunk/src/compiler/machine-operator-reducer.cc Thu Oct 2 00:05:29 2014 UTC +++ /trunk/src/compiler/machine-operator-reducer.cc Fri Oct 10 00:05:16 2014 UTC
@@ -473,6 +473,22 @@
if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0));
       break;
     }
+    case IrOpcode::kStore: {
+      Node* const value = node->InputAt(2);
+      // TODO(turbofan): Extend to 64-bit?
+      if (value->opcode() == IrOpcode::kWord32And) {
+        MachineType const rep = static_cast<MachineType>(
+            StoreRepresentationOf(node->op()).machine_type() & kRepMask);
+        Uint32BinopMatcher m(value);
+        if (m.right().HasValue() &&
+            ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
+ (rep == kRepWord16 && (m.right().Value() & 0xffff) == 0xffff))) {
+          node->ReplaceInput(2, m.left().node());
+          return Changed(node);
+        }
+      }
+      break;
+    }
     default:
       break;
   }
=======================================
--- /trunk/src/compiler/machine-operator.cc     Wed Oct  8 00:05:11 2014 UTC
+++ /trunk/src/compiler/machine-operator.cc     Fri Oct 10 00:05:16 2014 UTC
@@ -44,6 +44,12 @@
return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
             << ")";
 }
+
+
+StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kStore, op->opcode());
+  return OpParameter<StoreRepresentation>(op);
+}


#define PURE_OP_LIST(V) \
=======================================
--- /trunk/src/compiler/machine-operator.h      Wed Oct  8 00:05:11 2014 UTC
+++ /trunk/src/compiler/machine-operator.h      Fri Oct 10 00:05:16 2014 UTC
@@ -49,6 +49,8 @@

 std::ostream& operator<<(std::ostream&, StoreRepresentation);

+StoreRepresentation const& StoreRepresentationOf(Operator const*);
+

 // Interface for building machine-level operators. These operators are
// machine-level but machine-independent and thus define a language suitable
=======================================
--- /trunk/src/date.h   Wed Sep  3 08:32:14 2014 UTC
+++ /trunk/src/date.h   Fri Oct 10 00:05:16 2014 UTC
@@ -104,21 +104,51 @@

   // ECMA 262 - 15.9.1.9
   // LocalTime(t) = t + LocalTZA + DaylightSavingTA(t)
-  // ECMA 262 assumes that DaylightSavingTA is computed using UTC time,
-  // but we fetch DST from OS using local time, therefore we need:
-  // LocalTime(t) = t + LocalTZA + DaylightSavingTA(t + LocalTZA).
   int64_t ToLocal(int64_t time_ms) {
-    time_ms += LocalOffsetInMs();
-    return time_ms + DaylightSavingsOffsetInMs(time_ms);
+ return time_ms + LocalOffsetInMs() + DaylightSavingsOffsetInMs(time_ms);
   }

   // ECMA 262 - 15.9.1.9
   // UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)
-  // ECMA 262 assumes that DaylightSavingTA is computed using UTC time,
-  // but we fetch DST from OS using local time, therefore we need:
-  // UTC(t) = t - LocalTZA - DaylightSavingTA(t).
   int64_t ToUTC(int64_t time_ms) {
- return time_ms - LocalOffsetInMs() - DaylightSavingsOffsetInMs(time_ms); + // We need to compute UTC time that corresponds to the given local time.
+    // Literally following spec here leads to incorrect time computation at
+    // the points were we transition to and from DST.
+    //
+ // The following shows that using DST for (t - LocalTZA - hour) produces
+    // correct conversion.
+    //
+    // Consider transition to DST at local time L1.
+    // Let L0 = L1 - hour, L2 = L1 + hour,
+    //     U1 = UTC time that corresponds to L1,
+    //     U0 = U1 - hour.
+    // Transitioning to DST moves local clock one hour forward L1 => L2, so
+    // U0 = UTC time that corresponds to L0 = L0 - LocalTZA,
+    // U1 = UTC time that corresponds to L1 = L1 - LocalTZA,
+    // U1 = UTC time that corresponds to L2 = L2 - LocalTZA - hour.
+    // Note that DST(U0 - hour) = 0, DST(U0) = 0, DST(U1) = 1.
+    // U0 = L0 - LocalTZA - DST(L0 - LocalTZA - hour),
+    // U1 = L1 - LocalTZA - DST(L1 - LocalTZA - hour),
+    // U1 = L2 - LocalTZA - DST(L2 - LocalTZA - hour).
+    //
+    // Consider transition from DST at local time L1.
+    // Let L0 = L1 - hour,
+    //     U1 = UTC time that corresponds to L1,
+    //     U0 = U1 - hour, U2 = U1 + hour.
+    // Transitioning from DST moves local clock one hour back L1 => L0, so
+    // U0 = UTC time that corresponds to L0 (before transition)
+    //    = L0 - LocalTZA - hour.
+    // U1 = UTC time that corresponds to L0 (after transition)
+    //    = L0 - LocalTZA = L1 - LocalTZA - hour
+    // U2 = UTC time that corresponds to L1 = L1 - LocalTZA.
+    // Note that DST(U0) = 1, DST(U1) = 0, DST(U2) = 0.
+ // U0 = L0 - LocalTZA - DST(L0 - LocalTZA - hour) = L0 - LocalTZA - DST(U0). + // U2 = L1 - LocalTZA - DST(L1 - LocalTZA - hour) = L1 - LocalTZA - DST(U1).
+    // It is impossible to get U1 from local time.
+
+    const int kMsPerHour = 3600 * 1000;
+    time_ms -= LocalOffsetInMs();
+    return time_ms - DaylightSavingsOffsetInMs(time_ms - kMsPerHour);
   }


=======================================
--- /trunk/src/flag-definitions.h       Wed Oct  8 00:05:11 2014 UTC
+++ /trunk/src/flag-definitions.h       Fri Oct 10 00:05:16 2014 UTC
@@ -731,8 +731,6 @@
 DEFINE_BOOL(gc_verbose, false, "print stuff during garbage collection")
DEFINE_BOOL(heap_stats, false, "report heap statistics before and after GC")
 DEFINE_BOOL(code_stats, false, "report code statistics after GC")
-DEFINE_BOOL(verify_native_context_separation, false,
- "verify that code holds on to at most one native context after GC")
 DEFINE_BOOL(print_handles, false, "report handles after GC")
 DEFINE_BOOL(print_global_handles, false, "report global handles after GC")

=======================================
--- /trunk/src/full-codegen.h   Wed Oct  8 00:05:11 2014 UTC
+++ /trunk/src/full-codegen.h   Fri Oct 10 00:05:16 2014 UTC
@@ -517,6 +517,24 @@
   void EmitNewClosure(Handle<SharedFunctionInfo> info, bool pretenure);

   // Platform-specific support for compiling assignments.
+
+ // Left-hand side can only be a property, a global or a (parameter or local)
+  // slot.
+  enum LhsKind {
+    VARIABLE,
+    NAMED_PROPERTY,
+    KEYED_PROPERTY,
+    NAMED_SUPER_PROPERTY,
+    KEYED_SUPER_PROPERTY
+  };
+
+  static LhsKind GetAssignType(Property* property) {
+    if (property == NULL) return VARIABLE;
+    bool super_access = property->IsSuperAccess();
+    return (property->key()->IsPropertyName())
+               ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
+               : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
+  }

   // Load a value from a named property.
   // The receiver is left on the stack by the IC.
@@ -569,6 +587,10 @@
   // is expected in accumulator.
   void EmitNamedSuperPropertyStore(Property* prop);

+  // Complete a super named property assignment. The right-hand-side value
+  // is expected in accumulator.
+  void EmitKeyedSuperPropertyStore(Property* prop);
+
   // Complete a keyed property assignment.  The receiver and key are
   // expected on top of the stack and the right-hand-side value in the
   // accumulator.
=======================================
--- /trunk/src/heap/mark-compact.cc     Fri Oct  3 00:04:58 2014 UTC
+++ /trunk/src/heap/mark-compact.cc     Fri Oct 10 00:05:16 2014 UTC
@@ -227,103 +227,6 @@
 #endif  // VERIFY_HEAP


-#ifdef DEBUG
-class VerifyNativeContextSeparationVisitor : public ObjectVisitor {
- public:
-  VerifyNativeContextSeparationVisitor() : current_native_context_(NULL) {}
-
-  void VisitPointers(Object** start, Object** end) {
-    for (Object** current = start; current < end; current++) {
-      if ((*current)->IsHeapObject()) {
-        HeapObject* object = HeapObject::cast(*current);
-        if (object->IsString()) continue;
-        switch (object->map()->instance_type()) {
-          case JS_FUNCTION_TYPE:
-            CheckContext(JSFunction::cast(object)->context());
-            break;
-          case JS_GLOBAL_PROXY_TYPE:
-            CheckContext(JSGlobalProxy::cast(object)->native_context());
-            break;
-          case JS_GLOBAL_OBJECT_TYPE:
-          case JS_BUILTINS_OBJECT_TYPE:
-            CheckContext(GlobalObject::cast(object)->native_context());
-            break;
-          case JS_ARRAY_TYPE:
-          case JS_DATE_TYPE:
-          case JS_OBJECT_TYPE:
-          case JS_REGEXP_TYPE:
- VisitPointer(HeapObject::RawField(object, JSObject::kMapOffset));
-            break;
-          case MAP_TYPE:
- VisitPointer(HeapObject::RawField(object, Map::kPrototypeOffset)); - VisitPointer(HeapObject::RawField(object, Map::kConstructorOffset));
-            break;
-          case FIXED_ARRAY_TYPE:
-            if (object->IsContext()) {
-              CheckContext(object);
-            } else {
-              FixedArray* array = FixedArray::cast(object);
-              int length = array->length();
-              // Set array length to zero to prevent cycles while iterating
-              // over array bodies, this is easier than intrusive marking.
-              array->set_length(0);
- array->IterateBody(FIXED_ARRAY_TYPE, FixedArray::SizeFor(length),
-                                 this);
-              array->set_length(length);
-            }
-            break;
-          case CELL_TYPE:
-          case JS_PROXY_TYPE:
-          case JS_VALUE_TYPE:
-          case TYPE_FEEDBACK_INFO_TYPE:
-            object->Iterate(this);
-            break;
-          case DECLARED_ACCESSOR_INFO_TYPE:
-          case EXECUTABLE_ACCESSOR_INFO_TYPE:
-          case BYTE_ARRAY_TYPE:
-          case CALL_HANDLER_INFO_TYPE:
-          case CODE_TYPE:
-          case FIXED_DOUBLE_ARRAY_TYPE:
-          case HEAP_NUMBER_TYPE:
-          case MUTABLE_HEAP_NUMBER_TYPE:
-          case INTERCEPTOR_INFO_TYPE:
-          case ODDBALL_TYPE:
-          case SCRIPT_TYPE:
-          case SHARED_FUNCTION_INFO_TYPE:
-            break;
-          default:
-            UNREACHABLE();
-        }
-      }
-    }
-  }
-
- private:
-  void CheckContext(Object* context) {
-    if (!context->IsContext()) return;
-    Context* native_context = Context::cast(context)->native_context();
-    if (current_native_context_ == NULL) {
-      current_native_context_ = native_context;
-    } else {
-      CHECK_EQ(current_native_context_, native_context);
-    }
-  }
-
-  Context* current_native_context_;
-};
-
-
-static void VerifyNativeContextSeparation(Heap* heap) {
-  HeapObjectIterator it(heap->code_space());
-
-  for (Object* object = it.Next(); object != NULL; object = it.Next()) {
-    VerifyNativeContextSeparationVisitor visitor;
-    Code::cast(object)->CodeIterateBody(&visitor);
-  }
-}
-#endif
-
-
 void MarkCompactCollector::SetUp() {
   free_list_old_data_space_.Reset(new FreeList(heap_->old_data_space()));
free_list_old_pointer_space_.Reset(new FreeList(heap_->old_pointer_space()));
@@ -405,12 +308,6 @@

   SweepSpaces();

-#ifdef DEBUG
-  if (FLAG_verify_native_context_separation) {
-    VerifyNativeContextSeparation(heap_);
-  }
-#endif
-
 #ifdef VERIFY_HEAP
   if (heap()->weak_embedded_objects_verification_enabled()) {
     VerifyWeakEmbeddedObjectsInCode();
=======================================
--- /trunk/src/ia32/assembler-ia32.cc   Fri Oct  3 00:04:58 2014 UTC
+++ /trunk/src/ia32/assembler-ia32.cc   Fri Oct 10 00:05:16 2014 UTC
@@ -2379,6 +2379,26 @@
   EMIT(0x17);
   emit_sse_operand(dst, src);
 }
+
+
+void Assembler::pslld(XMMRegister reg, int8_t shift) {
+  EnsureSpace ensure_space(this);
+  EMIT(0x66);
+  EMIT(0x0F);
+  EMIT(0x72);
+  emit_sse_operand(esi, reg);  // esi == 6
+  EMIT(shift);
+}
+
+
+void Assembler::psrld(XMMRegister reg, int8_t shift) {
+  EnsureSpace ensure_space(this);
+  EMIT(0x66);
+  EMIT(0x0F);
+  EMIT(0x72);
+  emit_sse_operand(edx, reg);  // edx == 2
+  EMIT(shift);
+}


 void Assembler::psllq(XMMRegister reg, int8_t shift) {
=======================================
--- /trunk/src/ia32/assembler-ia32.h    Fri Oct  3 00:04:58 2014 UTC
+++ /trunk/src/ia32/assembler-ia32.h    Fri Oct 10 00:05:16 2014 UTC
@@ -1024,6 +1024,8 @@
   void por(XMMRegister dst, XMMRegister src);
   void ptest(XMMRegister dst, XMMRegister src);

+  void pslld(XMMRegister reg, int8_t shift);
+  void psrld(XMMRegister reg, int8_t shift);
   void psllq(XMMRegister reg, int8_t shift);
   void psllq(XMMRegister dst, XMMRegister src);
   void psrlq(XMMRegister reg, int8_t shift);
=======================================
--- /trunk/src/ia32/codegen-ia32.cc     Thu Sep 11 00:05:22 2014 UTC
+++ /trunk/src/ia32/codegen-ia32.cc     Fri Oct 10 00:05:16 2014 UTC
@@ -720,6 +720,19 @@
   __ mov(FieldOperand(eax, FixedArray::kLengthOffset), ebx);
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));

+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ jmp(&initialization_loop_entry, Label::kNear);
+  __ bind(&initialization_loop);
+  __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize),
+         masm->isolate()->factory()->the_hole_value());
+  __ bind(&initialization_loop_entry);
+  __ sub(ebx, Immediate(Smi::FromInt(1)));
+  __ j(not_sign, &initialization_loop);
+
+  __ mov(ebx, FieldOperand(edi, FixedDoubleArray::kLengthOffset));
   __ jmp(&entry);

   // ebx: target map
=======================================
--- /trunk/src/ia32/disasm-ia32.cc      Thu Aug  7 08:39:21 2014 UTC
+++ /trunk/src/ia32/disasm-ia32.cc      Fri Oct 10 00:05:16 2014 UTC
@@ -1386,6 +1386,15 @@
                            NameOfXMMRegister(regop),
                            NameOfXMMRegister(rm));
             data++;
+          } else if (*data == 0x72) {
+            data++;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            int8_t imm8 = static_cast<int8_t>(data[1]);
+            DCHECK(regop == esi || regop == edx);
+            AppendToBuffer("%s %s,%d", (regop == esi) ? "pslld" : "psrld",
+                           NameOfXMMRegister(rm), static_cast<int>(imm8));
+            data += 2;
           } else if (*data == 0x73) {
             data++;
             int mod, regop, rm;
=======================================
--- /trunk/src/ia32/full-codegen-ia32.cc        Thu Oct  9 00:05:16 2014 UTC
+++ /trunk/src/ia32/full-codegen-ia32.cc        Fri Oct 10 00:05:16 2014 UTC
@@ -1820,22 +1820,8 @@

   Comment cmnt(masm_, "[ Assignment");

- // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind {
-    VARIABLE,
-    NAMED_PROPERTY,
-    KEYED_PROPERTY,
-    NAMED_SUPER_PROPERTY
-  };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-                      ? (property->IsSuperAccess() ? NAMED_SUPER_PROPERTY
-                                                   : NAMED_PROPERTY)
-                      : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);

   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1859,6 +1845,18 @@
       } else {
         VisitForStackValue(property->obj());
       }
+      break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(result_register());
+      }
       break;
     case KEYED_PROPERTY: {
       if (expr->is_compound()) {
@@ -1892,6 +1890,10 @@
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1939,7 +1941,11 @@
       break;
     case NAMED_SUPER_PROPERTY:
       EmitNamedSuperPropertyStore(property);
-      context()->Plug(eax);
+      context()->Plug(result_register());
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(result_register());
       break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
@@ -2574,12 +2580,24 @@
   Literal* key = prop->key()->AsLiteral();
   DCHECK(key != NULL);

+  __ push(Immediate(key->value()));
   __ push(eax);
-  __ push(Immediate(key->value()));
   __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
                                           : Runtime::kStoreToSuper_Sloppy),
                  4);
 }
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // eax : value
+  // stack : receiver ('this'), home_object, key
+
+  __ push(eax);
+ __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict + : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}


 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
@@ -4391,24 +4409,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());

-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind {
-    VARIABLE,
-    NAMED_PROPERTY,
-    KEYED_PROPERTY,
-    NAMED_SUPER_PROPERTY
-  };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName())
- ? (prop->IsSuperAccess() ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
-            : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);

   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4420,25 +4422,50 @@
     if (expr->is_postfix() && !context()->IsEffect()) {
       __ push(Immediate(Smi::FromInt(0)));
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else if (assign_type == NAMED_SUPER_PROPERTY) {
-      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
-      EmitLoadHomeObject(prop->obj()->AsSuperReference());
-      __ push(result_register());
-      __ push(MemOperand(esp, kPointerSize));
-      __ push(result_register());
-      EmitNamedSuperPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ mov(LoadDescriptor::ReceiverRegister(),
-             Operand(esp, kPointerSize));                       // Object.
-      __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));  // Key.
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ push(result_register());
+        __ push(MemOperand(esp, kPointerSize));
+        __ push(result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ push(result_register());
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ mov(LoadDescriptor::ReceiverRegister(),
+ Operand(esp, kPointerSize)); // Object.
+        __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));  // Key.
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }

@@ -4476,6 +4503,9 @@
           case KEYED_PROPERTY:
             __ mov(Operand(esp, 2 * kPointerSize), eax);
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ mov(Operand(esp, 3 * kPointerSize), eax);
+            break;
         }
       }
     }
@@ -4517,6 +4547,9 @@
         case KEYED_PROPERTY:
           __ mov(Operand(esp, 2 * kPointerSize), eax);
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ mov(Operand(esp, 3 * kPointerSize), eax);
+          break;
       }
     }
   }
@@ -4579,6 +4612,17 @@
         if (!context()->IsEffect()) {
           context()->PlugTOS();
         }
+      } else {
+        context()->Plug(eax);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
       } else {
         context()->Plug(eax);
       }
=======================================
***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