Revision: 24890
Author:   [email protected]
Date:     Mon Oct 27 07:54:22 2014 UTC
Log:      Version 3.30.19 (based on bleeding_edge revision r24889)

Check string literals with escapes in PreParserTraits::GetSymbol() (issue 3606).

only define ARRAYSIZE_UNSAFE for NaCl builds (Chromium issue 405225).

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

Added:
 /trunk/test/mjsunit/es6/json.js
 /trunk/test/mjsunit/es6/math.js
 /trunk/test/mjsunit/regress/regress-3643.js
 /trunk/test/mjsunit/regress/regress-shift-enumerable.js
Modified:
 /trunk/ChangeLog
 /trunk/src/arm/full-codegen-arm.cc
 /trunk/src/arm/simulator-arm.cc
 /trunk/src/arm64/full-codegen-arm64.cc
 /trunk/src/array-iterator.js
 /trunk/src/array.js
 /trunk/src/ast-value-factory.cc
 /trunk/src/ast-value-factory.h
 /trunk/src/ast.h
 /trunk/src/base/bits.cc
 /trunk/src/base/bits.h
 /trunk/src/base/flags.h
 /trunk/src/base/macros.h
 /trunk/src/collection-iterator.js
 /trunk/src/compiler/arm/instruction-selector-arm.cc
 /trunk/src/compiler/arm64/instruction-selector-arm64.cc
 /trunk/src/compiler/ast-graph-builder.cc
 /trunk/src/compiler/common-operator.h
 /trunk/src/compiler/ia32/instruction-selector-ia32.cc
 /trunk/src/compiler/instruction-selector-impl.h
 /trunk/src/compiler/instruction-selector.cc
 /trunk/src/compiler/instruction-selector.h
 /trunk/src/compiler/js-generic-lowering.cc
 /trunk/src/compiler/js-operator.h
 /trunk/src/compiler/linkage.cc
 /trunk/src/compiler/machine-operator-reducer.cc
 /trunk/src/compiler/machine-operator-reducer.h
 /trunk/src/compiler/machine-operator.cc
 /trunk/src/compiler/machine-operator.h
 /trunk/src/compiler/mips/instruction-selector-mips.cc
 /trunk/src/compiler/opcodes.h
 /trunk/src/compiler/operator-properties-inl.h
 /trunk/src/compiler/pipeline.cc
 /trunk/src/compiler/schedule.cc
 /trunk/src/compiler/schedule.h
 /trunk/src/compiler/scheduler.cc
 /trunk/src/compiler/simplified-lowering.cc
 /trunk/src/compiler/typer.cc
 /trunk/src/compiler/verifier.cc
 /trunk/src/compiler/x64/instruction-selector-x64.cc
 /trunk/src/compiler.cc
 /trunk/src/flag-definitions.h
 /trunk/src/heap/heap.cc
 /trunk/src/heap/heap.h
 /trunk/src/heap-snapshot-generator.cc
 /trunk/src/hydrogen-instructions.cc
 /trunk/src/ia32/full-codegen-ia32.cc
 /trunk/src/ic/ic-compiler.cc
 /trunk/src/ic/ic-compiler.h
 /trunk/src/json.js
 /trunk/src/list-inl.h
 /trunk/src/math.js
 /trunk/src/mips/full-codegen-mips.cc
 /trunk/src/mips64/full-codegen-mips64.cc
 /trunk/src/objects-printer.cc
 /trunk/src/objects.cc
 /trunk/src/objects.h
 /trunk/src/preparser.cc
 /trunk/src/runtime/runtime-function.cc
 /trunk/src/scanner.h
 /trunk/src/serialize.cc
 /trunk/src/serialize.h
 /trunk/src/string-iterator.js
 /trunk/src/typedarray.js
 /trunk/src/version.cc
 /trunk/src/x64/full-codegen-x64.cc
 /trunk/src/x87/full-codegen-x87.cc
 /trunk/test/cctest/compiler/test-schedule.cc
 /trunk/test/cctest/compiler/test-scheduler.cc
 /trunk/test/cctest/test-assembler-arm.cc
 /trunk/test/cctest/test-parsing.cc
 /trunk/test/cctest/test-serialize.cc
 /trunk/test/mjsunit/es6/array-iterator.js
 /trunk/test/mjsunit/es6/collection-iterator.js
 /trunk/test/mjsunit/es6/string-iterator.js
 /trunk/test/mjsunit/harmony/proxies.js
 /trunk/test/mjsunit/harmony/typedarrays.js
 /trunk/test/mjsunit/regress/regress-417709a.js
 /trunk/test/unittests/base/bits-unittest.cc
 /trunk/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
 /trunk/test/unittests/compiler/js-operator-unittest.cc
 /trunk/test/unittests/compiler/machine-operator-reducer-unittest.cc
 /trunk/test/unittests/compiler/machine-operator-unittest.cc
 /trunk/tools/gdbinit
 /trunk/tools/whitespace.txt

=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/json.js     Mon Oct 27 07:54:22 2014 UTC
@@ -0,0 +1,15 @@
+// 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.
+
+// Flags: --harmony-tostring
+
+function testJSONToString() {
+  assertEquals('[object JSON]', "" + JSON);
+  assertEquals("JSON", JSON[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(JSON, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("JSON", desc.value);
+}
+testJSONToString();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/es6/math.js     Mon Oct 27 07:54:22 2014 UTC
@@ -0,0 +1,15 @@
+// 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.
+
+// Flags: --harmony-tostring
+
+function testMathToString() {
+  assertEquals('[object Math]', "" + Math);
+  assertEquals("Math", Math[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(Math, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("Math", desc.value);
+}
+testMathToString();
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-3643.js Mon Oct 27 07:54:22 2014 UTC
@@ -0,0 +1,21 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var a = [1, 2, 3];
+Object.defineProperty(a, '1', {
+  get: function() { delete this[1]; return undefined; },
+  configurable: true
+});
+var s = a.slice(1);
+assertTrue('0' in s);
+
+// Sparse case should hit the same code as above due to presence of the getter.
+a = [1, 2, 3];
+a[0xffff] = 4;
+Object.defineProperty(a, '1', {
+  get: function() { delete this[1]; return undefined; },
+  configurable: true
+});
+s = a.slice(1);
+assertTrue('0' in s);
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-shift-enumerable.js Mon Oct 27 07:54:22 2014 UTC
@@ -0,0 +1,16 @@
+// 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 arr = [1, 2];
+Object.defineProperty(arr, 0xfffe, {
+  value: 3,
+  configurable: true,
+  writable: true,
+  enumerable: false
+});
+arr[0xffff] = 4;
+arr.shift();
+var desc = Object.getOwnPropertyDescriptor(arr, 0xfffe);
+assertEquals(4, desc.value);
+assertFalse(desc.enumerable);
=======================================
--- /trunk/ChangeLog    Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/ChangeLog    Mon Oct 27 07:54:22 2014 UTC
@@ -1,3 +1,13 @@
+2014-10-27: Version 3.30.19
+
+        Check string literals with escapes in PreParserTraits::GetSymbol()
+        (issue 3606).
+
+ only define ARRAYSIZE_UNSAFE for NaCl builds (Chromium issue 405225).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-10-24: Version 3.30.18

         Narrow cases where Sparse/Smart versions of Array methods are used
=======================================
--- /trunk/src/arm/full-codegen-arm.cc  Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/arm/full-codegen-arm.cc  Mon Oct 27 07:54:22 2014 UTC
@@ -1131,6 +1131,7 @@
   __ push(r0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(r0);

   // Check for proxies.
@@ -1155,6 +1156,7 @@
   __ bind(&call_runtime);
   __ push(r0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);

   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1698,6 +1700,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);

   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in r0.
=======================================
--- /trunk/src/arm/simulator-arm.cc     Wed Oct 15 00:05:09 2014 UTC
+++ /trunk/src/arm/simulator-arm.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -2741,15 +2741,12 @@
             int rs = instr->RsValue();
             int32_t rs_val = get_register(rs);
             int32_t ret_val = 0;
-            DCHECK(rs_val != 0);
             // udiv
             if (instr->Bit(21) == 0x1) {
- ret_val = static_cast<int32_t>(static_cast<uint32_t>(rm_val) / - static_cast<uint32_t>(rs_val));
-            } else if ((rm_val == kMinInt) && (rs_val == -1)) {
-              ret_val = kMinInt;
+              ret_val = bit_cast<int32_t>(base::bits::UnsignedDiv32(
+                  bit_cast<uint32_t>(rm_val), bit_cast<uint32_t>(rs_val)));
             } else {
-              ret_val = rm_val / rs_val;
+              ret_val = base::bits::SignedDiv32(rm_val, rs_val);
             }
             set_register(rn, ret_val);
             return;
=======================================
--- /trunk/src/arm64/full-codegen-arm64.cc      Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/arm64/full-codegen-arm64.cc      Mon Oct 27 07:54:22 2014 UTC
@@ -1124,6 +1124,7 @@
   __ Push(x0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ Bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ Push(x0);

   // Check for proxies.
@@ -1147,6 +1148,7 @@
   __ Bind(&call_runtime);
   __ Push(x0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);

   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1678,6 +1680,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);

   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in x0.
=======================================
--- /trunk/src/array-iterator.js        Fri Oct 17 20:38:26 2014 UTC
+++ /trunk/src/array-iterator.js        Mon Oct 27 07:54:22 2014 UTC
@@ -112,6 +112,8 @@
   %FunctionSetName(ArrayIteratorIterator, '[Symbol.iterator]');
   %AddNamedProperty(ArrayIterator.prototype, symbolIterator,
                     ArrayIteratorIterator, DONT_ENUM);
+  %AddNamedProperty(ArrayIterator.prototype, symbolToStringTag,
+                    "Array Iterator", READ_ONLY | DONT_ENUM);
 }
 SetUpArrayIterator();

=======================================
--- /trunk/src/array.js Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/array.js Mon Oct 27 07:54:22 2014 UTC
@@ -284,11 +284,8 @@
 function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
   for (var i = 0; i < del_count; i++) {
     var index = start_i + i;
-    // The spec could also be interpreted such that %HasOwnProperty
-    // would be the appropriate test.  We follow KJS in consulting the
-    // prototype.
-    var current = array[index];
-    if (!IS_UNDEFINED(current) || index in array) {
+    if (index in array) {
+      var current = array[index];
       // The spec requires [[DefineOwnProperty]] here, %AddElement is close
       // enough (in that it ignores the prototype).
       %AddElement(deleted_elements, i, current, NONE);
=======================================
--- /trunk/src/ast-value-factory.cc     Fri Oct  3 00:04:58 2014 UTC
+++ /trunk/src/ast-value-factory.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -328,15 +328,25 @@
   values_.Add(value);
   return value;
 }
+
+
+#define GENERATE_VALUE_GETTER(value, initializer) \
+  if (!value) {                                   \
+    value = new (zone_) AstValue(initializer);    \
+    if (isolate_) {                               \
+      value->Internalize(isolate_);               \
+    }                                             \
+    values_.Add(value);                           \
+  }                                               \
+  return value;


 const AstValue* AstValueFactory::NewBoolean(bool b) {
-  AstValue* value = new (zone_) AstValue(b);
-  if (isolate_) {
-    value->Internalize(isolate_);
+  if (b) {
+    GENERATE_VALUE_GETTER(true_value_, true);
+  } else {
+    GENERATE_VALUE_GETTER(false_value_, false);
   }
-  values_.Add(value);
-  return value;
 }


@@ -352,34 +362,21 @@


 const AstValue* AstValueFactory::NewNull() {
-  AstValue* value = new (zone_) AstValue(AstValue::NULL_TYPE);
-  if (isolate_) {
-    value->Internalize(isolate_);
-  }
-  values_.Add(value);
-  return value;
+  GENERATE_VALUE_GETTER(null_value_, AstValue::NULL_TYPE);
 }


 const AstValue* AstValueFactory::NewUndefined() {
-  AstValue* value = new (zone_) AstValue(AstValue::UNDEFINED);
-  if (isolate_) {
-    value->Internalize(isolate_);
-  }
-  values_.Add(value);
-  return value;
+  GENERATE_VALUE_GETTER(undefined_value_, AstValue::UNDEFINED);
 }


 const AstValue* AstValueFactory::NewTheHole() {
-  AstValue* value = new (zone_) AstValue(AstValue::THE_HOLE);
-  if (isolate_) {
-    value->Internalize(isolate_);
-  }
-  values_.Add(value);
-  return value;
+  GENERATE_VALUE_GETTER(the_hole_value_, AstValue::THE_HOLE);
 }

+
+#undef GENERATE_VALUE_GETTER

 const AstRawString* AstValueFactory::GetString(
     uint32_t hash, bool is_one_byte, Vector<const byte> literal_bytes) {
=======================================
--- /trunk/src/ast-value-factory.h      Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/ast-value-factory.h      Mon Oct 27 07:54:22 2014 UTC
@@ -238,7 +238,7 @@
 };


-// For generating string constants.
+// For generating constants.
 #define STRING_CONSTANTS(F)                           \
   F(anonymous_function, "(anonymous function)")       \
   F(arguments, "arguments")                           \
@@ -268,6 +268,12 @@
   F(use_strict, "use strict")                         \
   F(value, "value")

+#define OTHER_CONSTANTS(F) \
+  F(true_value)            \
+  F(false_value)           \
+  F(null_value)            \
+  F(undefined_value)       \
+  F(the_hole_value)

 class AstValueFactory {
  public:
@@ -276,10 +282,12 @@
         zone_(zone),
         isolate_(NULL),
         hash_seed_(hash_seed) {
-#define F(name, str) \
-    name##_string_ = NULL;
+#define F(name, str) name##_string_ = NULL;
     STRING_CONSTANTS(F)
 #undef F
+#define F(name) name##_ = NULL;
+    OTHER_CONSTANTS(F)
+#undef F
   }

   Zone* zone() const { return zone_; }
@@ -299,15 +307,15 @@
     return isolate_ != NULL;
   }

-#define F(name, str) \
-  const AstRawString* name##_string() { \
-    if (name##_string_ == NULL) { \
-      const char* data = str; \
-      name##_string_ = GetOneByteString( \
+#define F(name, str)                                                    \
+  const AstRawString* name##_string() {                                 \
+    if (name##_string_ == NULL) {                                       \
+      const char* data = str;                                           \
+      name##_string_ = GetOneByteString(                                \
           Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), \
-                                static_cast<int>(strlen(data)))); \
-    } \
-    return name##_string_; \
+                                static_cast<int>(strlen(data))));       \
+    }                                                                   \
+    return name##_string_;                                              \
   }
   STRING_CONSTANTS(F)
 #undef F
@@ -338,10 +346,13 @@

   uint32_t hash_seed_;

-#define F(name, str) \
-  const AstRawString* name##_string_;
+#define F(name, str) const AstRawString* name##_string_;
   STRING_CONSTANTS(F)
 #undef F
+
+#define F(name) AstValue* name##_;
+  OTHER_CONSTANTS(F)
+#undef F
 };


@@ -351,5 +362,6 @@
 } }  // namespace v8::internal

 #undef STRING_CONSTANTS
+#undef OTHER_CONSTANTS

 #endif  // V8_AST_VALUE_FACTORY_H_
=======================================
--- /trunk/src/ast.h    Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/ast.h    Mon Oct 27 07:54:22 2014 UTC
@@ -957,9 +957,11 @@
   ForInType for_in_type() const { return for_in_type_; }
   void set_for_in_type(ForInType type) { for_in_type_ = type; }

-  static int num_ids() { return parent_num_ids() + 2; }
+  static int num_ids() { return parent_num_ids() + 4; }
   BailoutId BodyId() const { return BailoutId(local_id(0)); }
   BailoutId PrepareId() const { return BailoutId(local_id(1)); }
+  BailoutId EnumId() const { return BailoutId(local_id(2)); }
+  BailoutId ToObjectId() const { return BailoutId(local_id(3)); }
   virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
   virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }

@@ -1568,10 +1570,14 @@
   };

   struct Accessors: public ZoneObject {
-    Accessors() : getter(NULL), setter(NULL) { }
+    Accessors() : getter(NULL), setter(NULL) {}
     Expression* getter;
     Expression* setter;
   };
+
+  BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
+
+  static int num_ids() { return parent_num_ids() + 1; }

  protected:
ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
@@ -1582,8 +1588,10 @@
         fast_elements_(false),
         may_store_doubles_(false),
         has_function_(has_function) {}
+  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }

  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   Handle<FixedArray> constant_properties_;
   ZoneList<Property*>* properties_;
   int boilerplate_properties_;
=======================================
--- /trunk/src/base/bits.cc     Wed Oct 15 00:05:09 2014 UTC
+++ /trunk/src/base/bits.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -3,6 +3,9 @@
 // found in the LICENSE file.

 #include "src/base/bits.h"
+
+#include <limits>
+
 #include "src/base/logging.h"

 namespace v8 {
@@ -31,6 +34,19 @@
   return bit_cast<int32_t>(bit_cast<uint32_t>(acc) +
                            bit_cast<uint32_t>(SignedMulHigh32(lhs, rhs)));
 }
+
+
+int32_t SignedDiv32(int32_t lhs, int32_t rhs) {
+  if (rhs == 0) return 0;
+  if (rhs == -1) return -lhs;
+  return lhs / rhs;
+}
+
+
+int32_t SignedMod32(int32_t lhs, int32_t rhs) {
+  if (rhs == 0 || rhs == -1) return 0;
+  return lhs % rhs;
+}

 }  // namespace bits
 }  // namespace base
=======================================
--- /trunk/src/base/bits.h      Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/base/bits.h      Mon Oct 27 07:54:22 2014 UTC
@@ -198,6 +198,32 @@
// |lhs| and |rhs|, extracts the most significant 32 bits of the result, and
 // adds the accumulate value |acc|.
 int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, int32_t acc);
+
+
+// SignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
+// truncated to int32. If |rhs| is zero, then zero is returned. If |lhs|
+// is minint and |rhs| is -1, it returns minint.
+int32_t SignedDiv32(int32_t lhs, int32_t rhs);
+
+
+// SignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
+// truncated to int32. If either |rhs| is zero or |lhs| is minint and |rhs|
+// is -1, it returns zero.
+int32_t SignedMod32(int32_t lhs, int32_t rhs);
+
+
+// UnsignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
+// truncated to uint32. If |rhs| is zero, then zero is returned.
+inline uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs) {
+  return rhs ? lhs / rhs : 0u;
+}
+
+
+// UnsignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
+// truncated to uint32. If |rhs| is zero, then zero is returned.
+inline uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs) {
+  return rhs ? lhs % rhs : 0u;
+}

 }  // namespace bits
 }  // namespace base
=======================================
--- /trunk/src/base/flags.h     Thu Oct  2 00:05:29 2014 UTC
+++ /trunk/src/base/flags.h     Mon Oct 27 07:54:22 2014 UTC
@@ -26,8 +26,9 @@
   typedef S mask_type;

   Flags() : mask_(0) {}
-  Flags(flag_type flag) : mask_(flag) {}  // NOLINT(runtime/explicit)
-  explicit Flags(mask_type mask) : mask_(mask) {}
+  Flags(flag_type flag)  // NOLINT(runtime/explicit)
+      : mask_(static_cast<S>(flag)) {}
+  explicit Flags(mask_type mask) : mask_(static_cast<S>(mask)) {}

   Flags& operator&=(const Flags& flags) {
     mask_ &= flags.mask_;
=======================================
--- /trunk/src/base/macros.h    Wed Oct 22 07:27:53 2014 UTC
+++ /trunk/src/base/macros.h    Mon Oct 27 07:54:22 2014 UTC
@@ -25,6 +25,8 @@
   (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)


+#if V8_OS_NACL
+
 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
 // but can be used on anonymous types or types defined inside
 // functions.  It's less safe than arraysize as it accepts some
@@ -65,9 +67,6 @@
   ((sizeof(a) / sizeof(*(a))) / \
    static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))  // NOLINT

-
-#if V8_OS_NACL
-
// TODO(bmeurer): For some reason, the NaCl toolchain cannot handle the correct // definition of arraysize() below, so we have to use the unsafe version for
 // now.
@@ -397,5 +396,23 @@
 inline T RoundUp(T x, intptr_t m) {
   return RoundDown<T>(static_cast<T>(x + m - 1), m);
 }
+
+
+namespace v8 {
+namespace base {
+
+// TODO(yangguo): This is a poor man's replacement for std::is_fundamental,
+// which requires C++11. Switch to std::is_fundamental once possible.
+template <typename T>
+inline bool is_fundamental() {
+  return false;
+}
+
+template <>
+inline bool is_fundamental<uint8_t>() {
+  return true;
+}
+}
+}  // namespace v8::base

 #endif   // V8_BASE_MACROS_H_
=======================================
--- /trunk/src/collection-iterator.js   Tue Jul 15 00:04:47 2014 UTC
+++ /trunk/src/collection-iterator.js   Mon Oct 27 07:54:22 2014 UTC
@@ -77,6 +77,8 @@
   %FunctionSetName(SetIteratorSymbolIterator, '[Symbol.iterator]');
   %AddNamedProperty(SetIterator.prototype, symbolIterator,
       SetIteratorSymbolIterator, DONT_ENUM);
+  %AddNamedProperty(SetIterator.prototype, symbolToStringTag,
+      "Set Iterator", READ_ONLY | DONT_ENUM);
 }

 SetUpSetIterator();
@@ -174,6 +176,8 @@
   %FunctionSetName(MapIteratorSymbolIterator, '[Symbol.iterator]');
   %AddNamedProperty(MapIterator.prototype, symbolIterator,
       MapIteratorSymbolIterator, DONT_ENUM);
+  %AddNamedProperty(MapIterator.prototype, symbolToStringTag,
+      "Map Iterator", READ_ONLY | DONT_ENUM);
 }

 SetUpMapIterator();
=======================================
--- /trunk/src/compiler/arm/instruction-selector-arm.cc Fri Oct 24 14:44:48 2014 UTC +++ /trunk/src/compiler/arm/instruction-selector-arm.cc Mon Oct 27 07:54:22 2014 UTC
@@ -1135,6 +1135,12 @@
   VisitFloat64Compare(this, node, &cont);
 }

+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::Flag::kNoFlags;
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/src/compiler/arm64/instruction-selector-arm64.cc Fri Oct 17 20:38:26 2014 UTC +++ /trunk/src/compiler/arm64/instruction-selector-arm64.cc Mon Oct 27 07:54:22 2014 UTC
@@ -982,16 +982,16 @@
 // Shared routine for multiple word compare operations.
 static void VisitWordCompare(InstructionSelector* selector, Node* node,
InstructionCode opcode, FlagsContinuation* cont,
-                             bool commutative) {
+ bool commutative, ImmediateMode immediate_mode) {
   Arm64OperandGenerator g(selector);
   Node* left = node->InputAt(0);
   Node* right = node->InputAt(1);

   // Match immediates on left or right side of comparison.
-  if (g.CanBeImmediate(right, kArithmeticImm)) {
+  if (g.CanBeImmediate(right, immediate_mode)) {
VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
                  cont);
-  } else if (g.CanBeImmediate(left, kArithmeticImm)) {
+  } else if (g.CanBeImmediate(left, immediate_mode)) {
     if (!commutative) cont->Commute();
VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
                  cont);
@@ -1004,7 +1004,7 @@

 static void VisitWord32Compare(InstructionSelector* selector, Node* node,
                                FlagsContinuation* cont) {
-  VisitWordCompare(selector, node, kArm64Cmp32, cont, false);
+ VisitWordCompare(selector, node, kArm64Cmp32, cont, false, kArithmeticImm);
 }


@@ -1098,16 +1098,20 @@
         return VisitWord32Compare(this, value, &cont);
       case IrOpcode::kWord64Equal:
         cont.OverwriteAndNegateIfEqual(kEqual);
-        return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
       case IrOpcode::kInt64LessThan:
         cont.OverwriteAndNegateIfEqual(kSignedLessThan);
-        return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
       case IrOpcode::kInt64LessThanOrEqual:
         cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
-        return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
       case IrOpcode::kUint64LessThan:
         cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
-        return VisitWordCompare(this, value, kArm64Cmp, &cont, false);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
       case IrOpcode::kFloat64Equal:
         cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
         return VisitFloat64Compare(this, value, &cont);
@@ -1145,11 +1149,14 @@
         }
         break;
       case IrOpcode::kInt32Add:
-        return VisitWordCompare(this, value, kArm64Cmn32, &cont, true);
+        return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
+                                kArithmeticImm);
       case IrOpcode::kInt32Sub:
-        return VisitWordCompare(this, value, kArm64Cmp32, &cont, false);
+        return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
+                                kArithmeticImm);
       case IrOpcode::kWord32And:
-        return VisitWordCompare(this, value, kArm64Tst32, &cont, true);
+        return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
+                                kLogical32Imm);
       default:
         break;
     }
@@ -1169,11 +1176,14 @@
     if (CanCover(user, value)) {
       switch (value->opcode()) {
         case IrOpcode::kInt32Add:
-          return VisitWordCompare(this, value, kArm64Cmn32, &cont, true);
+          return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
+                                  kArithmeticImm);
         case IrOpcode::kInt32Sub:
-          return VisitWordCompare(this, value, kArm64Cmp32, &cont, false);
+          return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
+                                  kArithmeticImm);
         case IrOpcode::kWord32And:
-          return VisitWordCompare(this, value, kArm64Tst32, &cont, true);
+          return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
+                                  kLogical32Imm);
         default:
           break;
       }
@@ -1217,14 +1227,15 @@
     if (CanCover(user, value)) {
       switch (value->opcode()) {
         case IrOpcode::kWord64And:
-          return VisitWordCompare(this, value, kArm64Tst, &cont, true);
+          return VisitWordCompare(this, value, kArm64Tst, &cont, true,
+                                  kLogical64Imm);
         default:
           break;
       }
       return VisitWord64Test(this, value, &cont);
     }
   }
-  VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
 }


@@ -1252,19 +1263,19 @@

 void InstructionSelector::VisitInt64LessThan(Node* node) {
   FlagsContinuation cont(kSignedLessThan, node);
-  VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
 }


 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
   FlagsContinuation cont(kSignedLessThanOrEqual, node);
-  VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
 }


 void InstructionSelector::VisitUint64LessThan(Node* node) {
   FlagsContinuation cont(kUnsignedLessThan, node);
-  VisitWordCompare(this, node, kArm64Cmp, &cont, false);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
 }


@@ -1285,6 +1296,12 @@
   VisitFloat64Compare(this, node, &cont);
 }

+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::Flag::kNoFlags;
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/src/compiler/ast-graph-builder.cc    Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/ast-graph-builder.cc    Mon Oct 27 07:54:22 2014 UTC
@@ -642,11 +642,14 @@
     // Convert object to jsobject.
     // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
     obj = NewNode(javascript()->ToObject(), obj);
+ PrepareFrameState(obj, stmt->ToObjectId(), OutputFrameStateCombine::Push());
     environment()->Push(obj);
// TODO(dcarney): should do a fast enum cache check here to skip runtime.
     environment()->Push(obj);
     Node* cache_type = ProcessArguments(
         javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), 1);
+    PrepareFrameState(cache_type, stmt->EnumId(),
+                      OutputFrameStateCombine::Push());
// TODO(dcarney): these next runtime calls should be removed in favour of
     //                a few simplified instructions.
     environment()->Push(obj);
@@ -882,6 +885,8 @@
   const Operator* op =
       javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4);
Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
+  PrepareFrameState(literal, expr->CreateLiteralId(),
+                    OutputFrameStateCombine::Push());

   // The object is expected on the operand stack during computation of the
   // property values and is the value of the entire expression.
@@ -943,7 +948,10 @@
         if (property->emit_store()) {
           const Operator* op =
               javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
-          NewNode(op, receiver, value);
+          Node* set_prototype = NewNode(op, receiver, value);
+          // SetPrototype should not lazy deopt on an object
+          // literal.
+          PrepareFrameState(set_prototype, BailoutId::None());
         }
         break;
       }
@@ -970,7 +978,8 @@
     const Operator* op =
javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
     Node* call = NewNode(op, literal, name, getter, setter, attr);
-    PrepareFrameState(call, it->first->id());
+    // This should not lazy deopt on a new literal.
+    PrepareFrameState(call, BailoutId::None());
   }

   // Transform literals that contain functions to fast properties.
@@ -1237,7 +1246,7 @@
       receiver_value = NewNode(common()->Projection(1), pair);

       PrepareFrameState(pair, expr->EvalOrLookupId(),
-                        OutputFrameStateCombine::Push());
+                        OutputFrameStateCombine::Push(2));
       break;
     }
     case Call::PROPERTY_CALL: {
=======================================
--- /trunk/src/compiler/common-operator.h       Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/common-operator.h       Mon Oct 27 07:54:22 2014 UTC
@@ -66,6 +66,10 @@
   bool IsOutputIgnored() const {
     return kind_ == kPushOutput && parameter_ == 0;
   }
+
+  size_t ConsumedOutputCount() const {
+    return kind_ == kPushOutput ? GetPushCount() : 1;
+  }

   bool operator==(OutputFrameStateCombine const& other) const {
     return kind_ == other.kind_ && parameter_ == other.parameter_;
=======================================
--- /trunk/src/compiler/ia32/instruction-selector-ia32.cc Fri Oct 24 14:44:48 2014 UTC +++ /trunk/src/compiler/ia32/instruction-selector-ia32.cc Mon Oct 27 07:54:22 2014 UTC
@@ -877,6 +877,12 @@
   VisitFloat64Compare(this, node, &cont);
 }

+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::Flag::kNoFlags;
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/src/compiler/instruction-selector-impl.h Wed Oct 15 00:05:09 2014 UTC +++ /trunk/src/compiler/instruction-selector-impl.h Mon Oct 27 07:54:22 2014 UTC
@@ -127,6 +127,12 @@
     int index = sequence()->AddImmediate(Constant(imm));
     return ImmediateOperand::Create(index, zone());
   }
+
+ InstructionOperand* TempLocation(LinkageLocation location, MachineType type) {
+    UnallocatedOperand* op = ToUnallocatedOperand(location, type);
+    op->set_virtual_register(sequence()->NextVirtualRegister());
+    return op;
+  }

   InstructionOperand* Label(BasicBlock* block) {
     // TODO(bmeurer): We misuse ImmediateOperand here.
=======================================
--- /trunk/src/compiler/instruction-selector.cc Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/instruction-selector.cc Mon Oct 27 07:54:22 2014 UTC
@@ -217,6 +217,23 @@
   DCHECK(!IsDouble(node));
   sequence()->MarkAsReference(sequence()->GetVirtualRegister(node));
 }
+
+
+void InstructionSelector::MarkAsRepresentation(MachineType rep,
+                                               InstructionOperand* op) {
+  UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
+  switch (RepresentationOf(rep)) {
+    case kRepFloat32:
+    case kRepFloat64:
+      sequence()->MarkAsDouble(unalloc->virtual_register());
+      break;
+    case kRepTagged:
+      sequence()->MarkAsReference(unalloc->virtual_register());
+      break;
+    default:
+      break;
+  }
+}


void InstructionSelector::MarkAsRepresentation(MachineType rep, Node* node) {
@@ -274,15 +291,27 @@
     }

// Filter out the outputs that aren't live because no projection uses them.
+    size_t outputs_needed_by_framestate =
+        buffer->frame_state_descriptor == NULL
+            ? 0
+            : buffer->frame_state_descriptor->state_combine()
+                  .ConsumedOutputCount();
     for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
-      if (buffer->output_nodes[i] != NULL) {
-        Node* output = buffer->output_nodes[i];
+      bool output_is_live =
+ buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate;
+      if (output_is_live) {
         MachineType type =
             buffer->descriptor->GetReturnType(static_cast<int>(i));
         LinkageLocation location =
             buffer->descriptor->GetReturnLocation(static_cast<int>(i));
-        MarkAsRepresentation(type, output);
- buffer->outputs.push_back(g.DefineAsLocation(output, location, type));
+
+        Node* output = buffer->output_nodes[i];
+        InstructionOperand* op =
+            output == NULL ? g.TempLocation(location, type)
+                           : g.DefineAsLocation(output, location, type);
+        MarkAsRepresentation(type, op);
+
+        buffer->outputs.push_back(op);
       }
     }
   }
=======================================
--- /trunk/src/compiler/instruction-selector.h  Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/instruction-selector.h  Mon Oct 27 07:54:22 2014 UTC
@@ -84,6 +84,9 @@
   static Features SupportedFeatures() {
     return Features(CpuFeatures::SupportedFeatures());
   }
+
+  // TODO(sigurds) This should take a CpuFeatures argument.
+  static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();

// =========================================================================== // ============ Architecture-independent graph covering methods. =============
@@ -136,6 +139,10 @@
   // by {node}.
   void MarkAsRepresentation(MachineType rep, Node* node);

+ // Inform the register allocation of the representation of the unallocated
+  // operand {op}.
+  void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
+
   // Initialize the call buffer with the InstructionOperands, nodes, etc,
   // corresponding
   // to the inputs and outputs of the call.
=======================================
--- /trunk/src/compiler/js-generic-lowering.cc  Mon Oct 13 00:05:20 2014 UTC
+++ /trunk/src/compiler/js-generic-lowering.cc  Mon Oct 27 07:54:22 2014 UTC
@@ -275,8 +275,7 @@
   const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
   Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
   if (FLAG_vector_ics) {
-    PatchInsertInput(node, 2,
-                     jsgraph()->SmiConstant(p.feedback().slot().ToInt()));
+ PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index())); PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
   }
   ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
@@ -289,8 +288,7 @@
       CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode());
   PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
   if (FLAG_vector_ics) {
-    PatchInsertInput(node, 2,
-                     jsgraph()->SmiConstant(p.feedback().slot().ToInt()));
+ PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index())); PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
   }
   ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
=======================================
--- /trunk/src/compiler/js-operator.h   Tue Oct 21 12:48:28 2014 UTC
+++ /trunk/src/compiler/js-operator.h   Mon Oct 27 07:54:22 2014 UTC
@@ -103,6 +103,8 @@

   Handle<TypeFeedbackVector> vector() const { return vector_; }
   FeedbackVectorICSlot slot() const { return slot_; }
+
+  int index() const { return vector_->GetIndex(slot_); }

  private:
   const Handle<TypeFeedbackVector> vector_;
=======================================
--- /trunk/src/compiler/linkage.cc      Tue Oct 21 12:48:28 2014 UTC
+++ /trunk/src/compiler/linkage.cc      Mon Oct 27 07:54:22 2014 UTC
@@ -125,6 +125,7 @@
     case Runtime::kCompileLazy:
     case Runtime::kCompileOptimized:
     case Runtime::kCompileString:
+    case Runtime::kCreateObjectLiteral:
     case Runtime::kDebugBreak:
     case Runtime::kDataViewSetInt8:
     case Runtime::kDataViewSetUint8:
@@ -143,23 +144,38 @@
     case Runtime::kDataViewGetFloat32:
     case Runtime::kDataViewGetFloat64:
     case Runtime::kDebugEvaluate:
+    case Runtime::kDebugEvaluateGlobal:
     case Runtime::kDebugGetLoadedScripts:
     case Runtime::kDebugGetPropertyDetails:
     case Runtime::kDebugPromiseEvent:
+    case Runtime::kDefineAccessorPropertyUnchecked:
+    case Runtime::kDefineDataPropertyUnchecked:
     case Runtime::kDeleteProperty:
     case Runtime::kDeoptimizeFunction:
     case Runtime::kFunctionBindArguments:
+    case Runtime::kGetDefaultReceiver:
     case Runtime::kGetFrameCount:
     case Runtime::kGetOwnProperty:
+    case Runtime::kGetOwnPropertyNames:
+    case Runtime::kGetPropertyNamesFast:
+    case Runtime::kGetPrototype:
+    case Runtime::kInlineArguments:
     case Runtime::kInlineCallFunction:
     case Runtime::kInlineDateField:
     case Runtime::kInlineRegExpExec:
+    case Runtime::kInternalSetPrototype:
+    case Runtime::kInterrupt:
+    case Runtime::kIsPropertyEnumerable:
+    case Runtime::kIsSloppyModeFunction:
     case Runtime::kLiveEditGatherCompileInfo:
     case Runtime::kLoadLookupSlot:
     case Runtime::kLoadLookupSlotNoReferenceError:
     case Runtime::kMaterializeRegExpLiteral:
+    case Runtime::kNewObject:
     case Runtime::kNewObjectFromBound:
+    case Runtime::kNewObjectWithAllocationSite:
     case Runtime::kObjectFreeze:
+    case Runtime::kOwnKeys:
     case Runtime::kParseJson:
     case Runtime::kPrepareStep:
     case Runtime::kPreventExtensions:
@@ -168,22 +184,28 @@
     case Runtime::kRegExpCompile:
     case Runtime::kRegExpExecMultiple:
     case Runtime::kResolvePossiblyDirectEval:
-    // case Runtime::kSetPrototype:
+    case Runtime::kSetPrototype:
     case Runtime::kSetScriptBreakPoint:
+    case Runtime::kSparseJoinWithSeparator:
     case Runtime::kStackGuard:
+    case Runtime::kStoreKeyedToSuper_Sloppy:
+    case Runtime::kStoreKeyedToSuper_Strict:
+    case Runtime::kStoreToSuper_Sloppy:
+    case Runtime::kStoreToSuper_Strict:
     case Runtime::kStoreLookupSlot:
     case Runtime::kStringBuilderConcat:
+    case Runtime::kStringBuilderJoin:
     case Runtime::kStringReplaceGlobalRegExpWithString:
+    case Runtime::kThrowNonMethodError:
+    case Runtime::kThrowNotDateError:
     case Runtime::kThrowReferenceError:
+    case Runtime::kThrowUnsupportedSuperError:
     case Runtime::kThrow:
     case Runtime::kTypedArraySetFastCases:
     case Runtime::kTypedArrayInitializeFromArrayLike:
-    case Runtime::kDebugEvaluateGlobal:
-    case Runtime::kOwnKeys:
-    case Runtime::kGetOwnPropertyNames:
-    case Runtime::kIsPropertyEnumerable:
-    case Runtime::kGetPrototype:
-    case Runtime::kSparseJoinWithSeparator:
+#ifdef V8_I18N_SUPPORT
+    case Runtime::kGetImplFromInitializedIntlObject:
+#endif
       return true;
     default:
       return false;
=======================================
--- /trunk/src/compiler/machine-operator-reducer.cc Fri Oct 24 14:44:48 2014 UTC +++ /trunk/src/compiler/machine-operator-reducer.cc Mon Oct 27 07:54:22 2014 UTC
@@ -56,6 +56,11 @@
 Node* MachineOperatorReducer::Word32Shr(Node* lhs, uint32_t rhs) {
return graph()->NewNode(machine()->Word32Shr(), lhs, Uint32Constant(rhs));
 }
+
+
+Node* MachineOperatorReducer::Word32Equal(Node* lhs, Node* rhs) {
+  return graph()->NewNode(machine()->Word32Equal(), lhs, rhs);
+}


 Node* MachineOperatorReducer::Int32Add(Node* lhs, Node* rhs) {
@@ -299,40 +304,12 @@
     }
     case IrOpcode::kInt32Div:
       return ReduceInt32Div(node);
-    case IrOpcode::kUint32Div: {
-      Uint32BinopMatcher m(node);
-      if (m.right().Is(1)) return Replace(m.left().node());  // x / 1 => x
-      // TODO(turbofan): if (m.left().Is(0))
-      // TODO(turbofan): if (m.right().Is(0))
-      // TODO(turbofan): if (m.LeftEqualsRight())
-      if (m.IsFoldable() && !m.right().Is(0)) {  // K / K => K
-        return ReplaceInt32(m.left().Value() / m.right().Value());
-      }
-      if (m.right().IsPowerOf2()) {  // x / 2^n => x >> n
-        node->set_op(machine()->Word32Shr());
- node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
-        return Changed(node);
-      }
-      break;
-    }
+    case IrOpcode::kUint32Div:
+      return ReduceUint32Div(node);
     case IrOpcode::kInt32Mod:
       return ReduceInt32Mod(node);
-    case IrOpcode::kUint32Mod: {
-      Uint32BinopMatcher m(node);
-      if (m.right().Is(1)) return ReplaceInt32(0);  // x % 1 => 0
-      // TODO(turbofan): if (m.left().Is(0))
-      // TODO(turbofan): if (m.right().Is(0))
-      // TODO(turbofan): if (m.LeftEqualsRight())
-      if (m.IsFoldable() && !m.right().Is(0)) {  // K % K => K
-        return ReplaceInt32(m.left().Value() % m.right().Value());
-      }
-      if (m.right().IsPowerOf2()) {  // x % 2^n => x & 2^n-1
-        node->set_op(machine()->Word32And());
-        node->ReplaceInput(1, Int32Constant(m.right().Value() - 1));
-        return Changed(node);
-      }
-      break;
-    }
+    case IrOpcode::kUint32Mod:
+      return ReduceUint32Mod(node);
     case IrOpcode::kInt32LessThan: {
       Int32BinopMatcher m(node);
       if (m.IsFoldable()) {  // K < K => K
@@ -554,13 +531,16 @@

 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
   Int32BinopMatcher m(node);
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 / x => 0
   if (m.right().Is(0)) return Replace(m.right().node());  // x / 0 => 0
   if (m.right().Is(1)) return Replace(m.left().node());   // x / 1 => x
-  // TODO(turbofan): if (m.left().Is(0))
-  // TODO(turbofan): if (m.LeftEqualsRight())
-  if (m.IsFoldable() && !m.right().Is(0)) {  // K / K => K
-    if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value());
-    return ReplaceInt32(m.left().Value() / m.right().Value());
+  if (m.IsFoldable()) {                                   // K / K => K
+    return ReplaceInt32(
+        base::bits::SignedDiv32(m.left().Value(), m.right().Value()));
+  }
+  if (m.LeftEqualsRight()) {  // x / x => x != 0
+    Node* const zero = Int32Constant(0);
+    return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
   }
   if (m.right().Is(-1)) {  // x / -1 => 0 - x
     node->set_op(machine()->Int32Sub());
@@ -593,17 +573,40 @@
   }
   return NoChange();
 }
+
+
+Reduction MachineOperatorReducer::ReduceUint32Div(Node* node) {
+  Uint32BinopMatcher m(node);
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 / x => 0
+  if (m.right().Is(0)) return Replace(m.right().node());  // x / 0 => 0
+  if (m.right().Is(1)) return Replace(m.left().node());   // x / 1 => x
+  if (m.IsFoldable()) {                                   // K / K => K
+    return ReplaceUint32(
+        base::bits::UnsignedDiv32(m.left().Value(), m.right().Value()));
+  }
+  if (m.LeftEqualsRight()) {  // x / x => x != 0
+    Node* const zero = Int32Constant(0);
+    return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
+  }
+  if (m.right().IsPowerOf2()) {  // x / 2^n => x >> n
+    node->set_op(machine()->Word32Shr());
+ node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
+    return Changed(node);
+  }
+  return NoChange();
+}


 Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) {
   Int32BinopMatcher m(node);
-  if (m.right().Is(1)) return ReplaceInt32(0);   // x % 1  => 0
-  if (m.right().Is(-1)) return ReplaceInt32(0);  // x % -1 => 0
-  // TODO(turbofan): if (m.left().Is(0))
-  // TODO(turbofan): if (m.right().Is(0))
-  // TODO(turbofan): if (m.LeftEqualsRight())
-  if (m.IsFoldable() && !m.right().Is(0)) {  // K % K => K
-    return ReplaceInt32(m.left().Value() % m.right().Value());
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 % x  => 0
+  if (m.right().Is(0)) return Replace(m.right().node());  // x % 0  => 0
+  if (m.right().Is(1)) return ReplaceInt32(0);            // x % 1  => 0
+  if (m.right().Is(-1)) return ReplaceInt32(0);           // x % -1 => 0
+  if (m.LeftEqualsRight()) return ReplaceInt32(0);        // x % x  => 0
+  if (m.IsFoldable()) {                                   // K % K => K
+    return ReplaceInt32(
+        base::bits::SignedMod32(m.left().Value(), m.right().Value()));
   }
   if (m.right().HasValue()) {
     Node* const dividend = m.left().node();
@@ -637,6 +640,25 @@
   }
   return NoChange();
 }
+
+
+Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) {
+  Uint32BinopMatcher m(node);
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 % x => 0
+  if (m.right().Is(0)) return Replace(m.right().node());  // x % 0 => 0
+  if (m.right().Is(1)) return ReplaceUint32(0);           // x % 1 => 0
+  if (m.LeftEqualsRight()) return ReplaceInt32(0);        // x % x  => 0
+  if (m.IsFoldable()) {                                   // K % K => K
+    return ReplaceUint32(
+        base::bits::UnsignedMod32(m.left().Value(), m.right().Value()));
+  }
+  if (m.right().IsPowerOf2()) {  // x % 2^n => x & 2^n-1
+    node->set_op(machine()->Word32And());
+    node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
+    return Changed(node);
+  }
+  return NoChange();
+}


Reduction MachineOperatorReducer::ReduceProjection(size_t index, Node* node) {
=======================================
--- /trunk/src/compiler/machine-operator-reducer.h Wed Oct 15 13:35:30 2014 UTC +++ /trunk/src/compiler/machine-operator-reducer.h Mon Oct 27 07:54:22 2014 UTC
@@ -37,6 +37,7 @@
   Node* Word32And(Node* lhs, uint32_t rhs);
   Node* Word32Sar(Node* lhs, uint32_t rhs);
   Node* Word32Shr(Node* lhs, uint32_t rhs);
+  Node* Word32Equal(Node* lhs, Node* rhs);
   Node* Int32Add(Node* lhs, Node* rhs);
   Node* Int32Sub(Node* lhs, Node* rhs);
   Node* Int32Mul(Node* lhs, Node* rhs);
@@ -53,12 +54,17 @@
   Reduction ReplaceInt32(int32_t value) {
     return Replace(Int32Constant(value));
   }
+  Reduction ReplaceUint32(uint32_t value) {
+    return Replace(Uint32Constant(value));
+  }
   Reduction ReplaceInt64(int64_t value) {
     return Replace(Int64Constant(value));
   }

   Reduction ReduceInt32Div(Node* node);
+  Reduction ReduceUint32Div(Node* node);
   Reduction ReduceInt32Mod(Node* node);
+  Reduction ReduceUint32Mod(Node* node);
   Reduction ReduceProjection(size_t index, Node* node);

   Graph* graph() const;
=======================================
--- /trunk/src/compiler/machine-operator.cc     Wed Oct 15 13:35:30 2014 UTC
+++ /trunk/src/compiler/machine-operator.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -110,6 +110,10 @@
V(Float64Div, Operator::kNoProperties, 2, 1) \ V(Float64Mod, Operator::kNoProperties, 2, 1) \ V(Float64Sqrt, Operator::kNoProperties, 1, 1) \ + V(Float64Ceil, Operator::kNoProperties, 1, 1) \ + V(Float64Floor, Operator::kNoProperties, 1, 1) \ + V(Float64RoundTruncate, Operator::kNoProperties, 1, 1) \ + V(Float64RoundTiesAway, Operator::kNoProperties, 1, 1) \ V(Float64Equal, Operator::kCommutative, 2, 1) \ V(Float64LessThan, Operator::kNoProperties, 2, 1) \ V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 1) \
@@ -188,8 +192,8 @@
     LAZY_INSTANCE_INITIALIZER;


-MachineOperatorBuilder::MachineOperatorBuilder(MachineType word)
-    : impl_(kImpl.Get()), word_(word) {
+MachineOperatorBuilder::MachineOperatorBuilder(MachineType word, Flags flags)
+    : impl_(kImpl.Get()), word_(word), flags_(flags) {
   DCHECK(word == kRepWord32 || word == kRepWord64);
 }

@@ -236,7 +240,6 @@
   UNREACHABLE();
   return NULL;
 }
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/src/compiler/machine-operator.h      Wed Oct 15 13:35:30 2014 UTC
+++ /trunk/src/compiler/machine-operator.h      Mon Oct 27 07:54:22 2014 UTC
@@ -5,6 +5,7 @@
 #ifndef V8_COMPILER_MACHINE_OPERATOR_H_
 #define V8_COMPILER_MACHINE_OPERATOR_H_

+#include "src/base/flags.h"
 #include "src/compiler/machine-type.h"

 namespace v8 {
@@ -57,7 +58,19 @@
 // for generating code to run on architectures such as ia32, x64, arm, etc.
 class MachineOperatorBuilder FINAL {
  public:
-  explicit MachineOperatorBuilder(MachineType word = kMachPtr);
+  // Flags that specify which operations are available. This is useful
+  // for operations that are unsupported by some back-ends.
+  enum class Flag : unsigned {
+    kNoFlags = 0,
+    kFloat64Floor = 1 << 0,
+    kFloat64Ceil = 1 << 1,
+    kFloat64RoundTruncate = 1 << 2,
+    kFloat64RoundTiesAway = 1 << 3
+  };
+  typedef base::Flags<Flag, unsigned> Flags;
+
+  explicit MachineOperatorBuilder(MachineType word = kMachPtr,
+ Flags supportedOperators = Flag::kNoFlags);

   const Operator* Word32And();
   const Operator* Word32Or();
@@ -134,6 +147,20 @@
   const Operator* Float64Equal();
   const Operator* Float64LessThan();
   const Operator* Float64LessThanOrEqual();
+
+  // Floating point rounding.
+  const Operator* Float64Floor();
+  const Operator* Float64Ceil();
+  const Operator* Float64RoundTruncate();
+  const Operator* Float64RoundTiesAway();
+  bool HasFloat64Floor() { return flags_ & Flag::kFloat64Floor; }
+  bool HasFloat64Ceil() { return flags_ & Flag::kFloat64Ceil; }
+  bool HasFloat64RoundTruncate() {
+    return flags_ & Flag::kFloat64RoundTruncate;
+  }
+  bool HasFloat64RoundTiesAway() {
+    return flags_ & Flag::kFloat64RoundTiesAway;
+  }

   // load [base + index]
   const Operator* Load(LoadRepresentation rep);
@@ -181,8 +208,11 @@
  private:
   const MachineOperatorBuilderImpl& impl_;
   const MachineType word_;
+  const Flags flags_;
 };

+
+DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/src/compiler/mips/instruction-selector-mips.cc Fri Oct 17 20:38:26 2014 UTC +++ /trunk/src/compiler/mips/instruction-selector-mips.cc Mon Oct 27 07:54:22 2014 UTC
@@ -647,6 +647,12 @@
   VisitFloat64Compare(this, node, &cont);
 }

+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::Flag::kNoFlags;
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/src/compiler/opcodes.h       Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/opcodes.h       Mon Oct 27 07:54:22 2014 UTC
@@ -226,6 +226,10 @@
   V(Float64Equal)             \
   V(Float64LessThan)          \
   V(Float64LessThanOrEqual)   \
+  V(Float64Floor)             \
+  V(Float64Ceil)              \
+  V(Float64RoundTruncate)     \
+  V(Float64RoundTiesAway)     \
   V(LoadStackPointer)

 #define VALUE_OP_LIST(V) \
=======================================
--- /trunk/src/compiler/operator-properties-inl.h Thu Oct 23 08:44:45 2014 UTC +++ /trunk/src/compiler/operator-properties-inl.h Mon Oct 27 07:54:22 2014 UTC
@@ -81,6 +81,9 @@
     case IrOpcode::kJSStoreProperty:
     case IrOpcode::kJSSubtract:

+    // Conversions
+    case IrOpcode::kJSToObject:
+
     // Other
     case IrOpcode::kJSDeleteProperty:
       return true;
=======================================
--- /trunk/src/compiler/pipeline.cc     Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/pipeline.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -178,7 +178,8 @@
// construction. This is currently only needed for the node cache, which the
   // typer could sweep over later.
   Typer typer(&graph, info()->context());
-  MachineOperatorBuilder machine;
+  MachineOperatorBuilder machine(
+      kMachPtr, InstructionSelector::SupportedMachineOperatorFlags());
   CommonOperatorBuilder common(zone());
   JSOperatorBuilder javascript(zone());
   JSGraph jsgraph(&graph, &common, &javascript, &machine);
=======================================
--- /trunk/src/compiler/schedule.cc     Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/schedule.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -51,7 +51,6 @@


 void BasicBlock::set_control(Control control) {
-  DCHECK(control_ == BasicBlock::kNone);
   control_ = control;
 }

@@ -213,12 +212,42 @@
   SetControlInput(block, input);
   if (block != end()) AddSuccessor(block, end());
 }
+
+
+void Schedule::InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
+                            BasicBlock* tblock, BasicBlock* fblock) {
+  DCHECK(block->control() != BasicBlock::kNone);
+  DCHECK(end->control() == BasicBlock::kNone);
+  end->set_control(block->control());
+  block->set_control(BasicBlock::kBranch);
+  MoveSuccessors(block, end);
+  AddSuccessor(block, tblock);
+  AddSuccessor(block, fblock);
+  if (block->control_input() != NULL) {
+    SetControlInput(end, block->control_input());
+  }
+  SetControlInput(block, branch);
+}


 void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) {
   block->AddSuccessor(succ);
   succ->AddPredecessor(block);
 }
+
+
+void Schedule::MoveSuccessors(BasicBlock* from, BasicBlock* to) {
+  for (BasicBlock::Predecessors::iterator i = from->successors_begin();
+       i != from->successors_end(); ++i) {
+    BasicBlock* succ = *i;
+    to->AddSuccessor(succ);
+    for (BasicBlock::Predecessors::iterator j = succ->predecessors_begin();
+         j != succ->predecessors_end(); ++j) {
+      if (*j == from) *j = to;
+    }
+  }
+  from->ClearSuccessors();
+}


 void Schedule::SetControlInput(BasicBlock* block, Node* node) {
=======================================
--- /trunk/src/compiler/schedule.h      Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/schedule.h      Mon Oct 27 07:54:22 2014 UTC
@@ -95,6 +95,7 @@
   }
   size_t PredecessorCount() const { return predecessors_.size(); }
   BasicBlock* PredecessorAt(size_t index) { return predecessors_[index]; }
+  void ClearPredecessors() { predecessors_.clear(); }
   void AddPredecessor(BasicBlock* predecessor);

   typedef ZoneVector<BasicBlock*> Successors;
@@ -108,6 +109,7 @@
   }
   size_t SuccessorCount() const { return successors_.size(); }
   BasicBlock* SuccessorAt(size_t index) { return successors_[index]; }
+  void ClearSuccessors() { successors_.clear(); }
   void AddSuccessor(BasicBlock* successor);

   // Nodes in the basic block.
@@ -240,7 +242,14 @@
   // BasicBlock building: add a throw at the end of {block}.
   void AddThrow(BasicBlock* block, Node* input);

-  void AddSuccessor(BasicBlock* block, BasicBlock* succ);
+  // BasicBlock mutation: insert a branch into the end of {block}.
+  void InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
+                    BasicBlock* tblock, BasicBlock* fblock);
+
+  // Exposed publicly for testing only.
+  void AddSuccessorForTesting(BasicBlock* block, BasicBlock* succ) {
+    return AddSuccessor(block, succ);
+  }

   BasicBlockVector* rpo_order() { return &rpo_order_; }
   const BasicBlockVector* rpo_order() const { return &rpo_order_; }
@@ -256,6 +265,9 @@
   friend class ScheduleVisualizer;
   friend class BasicBlockInstrumentor;

+  void AddSuccessor(BasicBlock* block, BasicBlock* succ);
+  void MoveSuccessors(BasicBlock* from, BasicBlock* to);
+
   void SetControlInput(BasicBlock* block, Node* node);
   void SetBlockForNode(BasicBlock* block, Node* node);

=======================================
--- /trunk/src/compiler/scheduler.cc    Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/scheduler.cc    Mon Oct 27 07:54:22 2014 UTC
@@ -239,6 +239,7 @@
     switch (node->opcode()) {
       case IrOpcode::kLoop:
       case IrOpcode::kMerge:
+      case IrOpcode::kTerminate:
         BuildBlockForNode(node);
         break;
       case IrOpcode::kBranch:
@@ -561,15 +562,26 @@
     BasicBlockVector* final_order = schedule_->rpo_order();
     order->Serialize(final_order);

- // Compute the correct loop header for every block and set the correct loop
-    // ends.
+    // Compute the correct loop headers and set the correct loop ends.
     LoopInfo* current_loop = NULL;
     BasicBlock* current_header = NULL;
     int loop_depth = 0;
for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end();
          ++i) {
       BasicBlock* current = *i;
+
+      // Finish the previous loop(s) if we just exited them.
+      while (current_header != NULL &&
+             current->rpo_number() >= current_header->loop_end()) {
+        DCHECK(current_header->IsLoopHeader());
+        DCHECK(current_loop != NULL);
+        current_loop = current_loop->prev;
+ current_header = current_loop == NULL ? NULL : current_loop->header;
+        --loop_depth;
+      }
       current->set_loop_header(current_header);
+
+      // Push a new loop onto the stack if this loop is a loop header.
       if (current->IsLoopHeader()) {
         loop_depth++;
         current_loop = &loops[current->loop_end()];
@@ -580,17 +592,10 @@
         current_header = current_loop->header;
         Trace("B%d is a loop header, increment loop depth to %d\n",
               current->id().ToInt(), loop_depth);
-      } else {
-        while (current_header != NULL &&
-               current->rpo_number() >= current_header->loop_end()) {
-          DCHECK(current_header->IsLoopHeader());
-          DCHECK(current_loop != NULL);
-          current_loop = current_loop->prev;
- current_header = current_loop == NULL ? NULL : current_loop->header;
-          --loop_depth;
-        }
       }
+
       current->set_loop_depth(loop_depth);
+
       if (current->loop_header() == NULL) {
Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
               current->loop_depth());
@@ -755,6 +760,12 @@
os << " range: [" << block->rpo_number() << ", " << block->loop_end()
            << ")";
       }
+      if (block->loop_header() != NULL) {
+        os << " header: B" << block->loop_header()->id();
+      }
+      if (block->loop_depth() > 0) {
+        os << " depth: " << block->loop_depth();
+      }
       os << "\n";
     }
   }
@@ -774,6 +785,7 @@
       DCHECK(header->loop_end() >= 0);
       DCHECK(header->loop_end() <= static_cast<int>(order->size()));
       DCHECK(header->loop_end() > header->rpo_number());
+      DCHECK(header->loop_header() != header);

       // Verify the start ... end list relationship.
       int links = 0;
@@ -1073,31 +1085,29 @@
// Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
     // into enclosing loop pre-headers until they would preceed their
     // ScheduleEarly position.
-    BasicBlock* hoist_block = block;
+    BasicBlock* hoist_block = GetPreHeader(block);
     while (hoist_block != NULL && hoist_block->rpo_number() >= min_rpo) {
-      if (hoist_block->loop_depth() < block->loop_depth()) {
-        block = hoist_block;
-        Trace("  hoisting #%d:%s to block %d\n", node->id(),
-              node->op()->mnemonic(), block->id().ToInt());
-      }
-      // Try to hoist to the pre-header of the loop header.
-      hoist_block = hoist_block->loop_header();
-      if (hoist_block != NULL) {
-        BasicBlock* pre_header = hoist_block->dominator();
-        DCHECK(pre_header == NULL ||
-               *hoist_block->predecessors_begin() == pre_header);
-        Trace(
- " hoist to pre-header B%d of loop header B%d, depth would be %d\n",
-            pre_header->id().ToInt(), hoist_block->id().ToInt(),
-            pre_header->loop_depth());
-        hoist_block = pre_header;
-      }
+      Trace("  hoisting #%d:%s to block %d\n", node->id(),
+            node->op()->mnemonic(), hoist_block->id().ToInt());
+      DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
+      block = hoist_block;
+      hoist_block = GetPreHeader(hoist_block);
     }

     ScheduleNode(block, node);
   }

  private:
+  BasicBlock* GetPreHeader(BasicBlock* block) {
+    if (block->IsLoopHeader()) {
+      return block->dominator();
+    } else if (block->loop_header() != NULL) {
+      return block->loop_header()->dominator();
+    } else {
+      return NULL;
+    }
+  }
+
   BasicBlock* GetCommonDominatorOfUses(Node* node) {
     BasicBlock* block = NULL;
     Node::Uses uses = node->uses();
=======================================
--- /trunk/src/compiler/simplified-lowering.cc  Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/simplified-lowering.cc  Mon Oct 27 07:54:22 2014 UTC
@@ -915,6 +915,10 @@
       case IrOpcode::kFloat64Mod:
         return VisitFloat64Binop(node);
       case IrOpcode::kFloat64Sqrt:
+      case IrOpcode::kFloat64Floor:
+      case IrOpcode::kFloat64Ceil:
+      case IrOpcode::kFloat64RoundTruncate:
+      case IrOpcode::kFloat64RoundTiesAway:
         return VisitUnop(node, kMachFloat64, kMachFloat64);
       case IrOpcode::kFloat64Equal:
       case IrOpcode::kFloat64LessThan:
=======================================
--- /trunk/src/compiler/typer.cc        Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler/typer.cc        Mon Oct 27 07:54:22 2014 UTC
@@ -1768,6 +1768,30 @@
 Bounds Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) {
   return Bounds(Type::Boolean());
 }
+
+
+Bounds Typer::Visitor::TypeFloat64Floor(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Ceil(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64RoundTruncate(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64RoundTiesAway(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}


 Bounds Typer::Visitor::TypeLoadStackPointer(Node* node) {
=======================================
--- /trunk/src/compiler/verifier.cc     Thu Oct 23 08:44:45 2014 UTC
+++ /trunk/src/compiler/verifier.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -702,6 +702,10 @@
     case IrOpcode::kFloat64Div:
     case IrOpcode::kFloat64Mod:
     case IrOpcode::kFloat64Sqrt:
+    case IrOpcode::kFloat64Floor:
+    case IrOpcode::kFloat64Ceil:
+    case IrOpcode::kFloat64RoundTruncate:
+    case IrOpcode::kFloat64RoundTiesAway:
     case IrOpcode::kFloat64Equal:
     case IrOpcode::kFloat64LessThan:
     case IrOpcode::kFloat64LessThanOrEqual:
=======================================
--- /trunk/src/compiler/x64/instruction-selector-x64.cc Fri Oct 24 14:44:48 2014 UTC +++ /trunk/src/compiler/x64/instruction-selector-x64.cc Mon Oct 27 07:54:22 2014 UTC
@@ -1108,6 +1108,12 @@
   VisitFloat64Compare(this, node, &cont);
 }

+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::Flag::kNoFlags;
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/src/compiler.cc      Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/compiler.cc      Mon Oct 27 07:54:22 2014 UTC
@@ -414,9 +414,6 @@
     compiler::Pipeline pipeline(info());
     pipeline.GenerateCode();
     if (!info()->code().is_null()) {
-      if (FLAG_turbo_deoptimization) {
- info()->context()->native_context()->AddOptimizedCode(*info()->code());
-      }
       return SetLastStatus(SUCCEEDED);
     }
   }
@@ -485,6 +482,9 @@
   DCHECK(last_status() == SUCCEEDED);
   // TODO(turbofan): Currently everything is done in the first phase.
   if (!info()->code().is_null()) {
+    if (FLAG_turbo_deoptimization) {
+ info()->context()->native_context()->AddOptimizedCode(*info()->code());
+    }
     RecordOptimizationStats();
     return last_status();
   }
=======================================
--- /trunk/src/flag-definitions.h       Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/flag-definitions.h       Mon Oct 27 07:54:22 2014 UTC
@@ -462,7 +462,7 @@
 DEFINE_BOOL(trace_stub_failures, false,
             "trace deoptimization of generated code stubs")

-DEFINE_BOOL(serialize_toplevel, false, "enable caching of toplevel scripts")
+DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
 DEFINE_BOOL(trace_code_serializer, false, "print code serializer trace")

 // compiler.cc
=======================================
--- /trunk/src/heap/heap.cc     Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/heap/heap.cc     Mon Oct 27 07:54:22 2014 UTC
@@ -4549,6 +4549,19 @@
   UNREACHABLE();
   return false;
 }
+
+
+bool Heap::RootIsImmortalImmovable(int root_index) {
+  switch (root_index) {
+#define CASE(name)               \
+  case Heap::k##name##RootIndex: \
+    return true;
+    IMMORTAL_IMMOVABLE_ROOT_LIST(CASE);
+#undef CASE
+    default:
+      return false;
+  }
+}


 #ifdef VERIFY_HEAP
=======================================
--- /trunk/src/heap/heap.h      Fri Oct 24 14:44:48 2014 UTC
+++ /trunk/src/heap/heap.h      Mon Oct 27 07:54:22 2014 UTC
@@ -198,58 +198,6 @@
   SMI_ROOT_LIST(V)    \
   V(StringTable, string_table, StringTable)

-// Heap roots that are known to be immortal immovable, for which we can safely
-// skip write barriers.
-#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \
-  V(byte_array_map)                     \
-  V(free_space_map)                     \
-  V(one_pointer_filler_map)             \
-  V(two_pointer_filler_map)             \
-  V(undefined_value)                    \
-  V(the_hole_value)                     \
-  V(null_value)                         \
-  V(true_value)                         \
-  V(false_value)                        \
-  V(uninitialized_value)                \
-  V(cell_map)                           \
-  V(global_property_cell_map)           \
-  V(shared_function_info_map)           \
-  V(meta_map)                           \
-  V(heap_number_map)                    \
-  V(mutable_heap_number_map)            \
-  V(native_context_map)                 \
-  V(fixed_array_map)                    \
-  V(code_map)                           \
-  V(scope_info_map)                     \
-  V(fixed_cow_array_map)                \
-  V(fixed_double_array_map)             \
-  V(constant_pool_array_map)            \
-  V(weak_cell_map)                      \
-  V(no_interceptor_result_sentinel)     \
-  V(hash_table_map)                     \
-  V(ordered_hash_table_map)             \
-  V(empty_fixed_array)                  \
-  V(empty_byte_array)                   \
-  V(empty_descriptor_array)             \
-  V(empty_constant_pool_array)          \
-  V(arguments_marker)                   \
-  V(symbol_map)                         \
-  V(sloppy_arguments_elements_map)      \
-  V(function_context_map)               \
-  V(catch_context_map)                  \
-  V(with_context_map)                   \
-  V(block_context_map)                  \
-  V(module_context_map)                 \
-  V(global_context_map)                 \
-  V(undefined_map)                      \
-  V(the_hole_map)                       \
-  V(null_map)                           \
-  V(boolean_map)                        \
-  V(uninitialized_map)                  \
-  V(message_object_map)                 \
-  V(foreign_map)                        \
-  V(neander_map)
-
 #define INTERNALIZED_STRING_LIST(V)                        \
   V(Object_string, "Object")                               \
   V(proto_string, "__proto__")                             \
@@ -351,6 +299,60 @@
   V(class_start_position_symbol)    \
   V(class_end_position_symbol)

+// Heap roots that are known to be immortal immovable, for which we can safely
+// skip write barriers. This list is not complete and has omissions.
+#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \
+  V(ByteArrayMap)                       \
+  V(FreeSpaceMap)                       \
+  V(OnePointerFillerMap)                \
+  V(TwoPointerFillerMap)                \
+  V(UndefinedValue)                     \
+  V(TheHoleValue)                       \
+  V(NullValue)                          \
+  V(TrueValue)                          \
+  V(FalseValue)                         \
+  V(UninitializedValue)                 \
+  V(CellMap)                            \
+  V(GlobalPropertyCellMap)              \
+  V(SharedFunctionInfoMap)              \
+  V(MetaMap)                            \
+  V(HeapNumberMap)                      \
+  V(MutableHeapNumberMap)               \
+  V(NativeContextMap)                   \
+  V(FixedArrayMap)                      \
+  V(CodeMap)                            \
+  V(ScopeInfoMap)                       \
+  V(FixedCOWArrayMap)                   \
+  V(FixedDoubleArrayMap)                \
+  V(ConstantPoolArrayMap)               \
+  V(WeakCellMap)                        \
+  V(NoInterceptorResultSentinel)        \
+  V(HashTableMap)                       \
+  V(OrderedHashTableMap)                \
+  V(EmptyFixedArray)                    \
+  V(EmptyByteArray)                     \
+  V(EmptyDescriptorArray)               \
+  V(EmptyConstantPoolArray)             \
+  V(ArgumentsMarker)                    \
+  V(SymbolMap)                          \
+  V(SloppyArgumentsElementsMap)         \
+  V(FunctionContextMap)                 \
+  V(CatchContextMap)                    \
+  V(WithContextMap)                     \
+  V(BlockContextMap)                    \
+  V(ModuleContextMap)                   \
+  V(GlobalContextMap)                   \
+  V(UndefinedMap)                       \
+  V(TheHoleMap)                         \
+  V(NullMap)                            \
+  V(BooleanMap)                         \
+  V(UninitializedMap)                   \
+  V(ArgumentsMarkerMap)                 \
+  V(JSMessageObjectMap)                 \
+  V(ForeignMap)                         \
+  V(NeanderMap)                         \
+  PRIVATE_SYMBOL_LIST(V)
+
 // Forward declarations.
 class HeapStats;
 class Isolate;
@@ -927,6 +929,8 @@
   Address* store_buffer_top_address() {
     return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
   }
+
+  static bool RootIsImmortalImmovable(int root_index);

 #ifdef VERIFY_HEAP
   // Verify the heap is in its normal state before or after a GC.
@@ -1115,6 +1119,8 @@
     kStrongRootListLength = kStringTableRootIndex,
     kSmiRootsStart = kStringTableRootIndex + 1
   };
+
+  Object* root(RootListIndex index) { return roots_[index]; }

   STATIC_ASSERT(kUndefinedValueRootIndex ==
                 Internals::kUndefinedValueRootIndex);
=======================================
--- /trunk/src/heap-snapshot-generator.cc       Thu Oct  2 00:05:29 2014 UTC
+++ /trunk/src/heap-snapshot-generator.cc       Mon Oct 27 07:54:22 2014 UTC
@@ -1711,11 +1711,11 @@
   AccessorPair* accessors = AccessorPair::cast(callback_obj);
   Object* getter = accessors->getter();
   if (!getter->IsOddball()) {
- SetPropertyReference(js_obj, entry, String::cast(key), getter, "get %s");
+    SetPropertyReference(js_obj, entry, Name::cast(key), getter, "get %s");
   }
   Object* setter = accessors->setter();
   if (!setter->IsOddball()) {
- SetPropertyReference(js_obj, entry, String::cast(key), setter, "set %s");
+    SetPropertyReference(js_obj, entry, Name::cast(key), setter, "set %s");
   }
   return true;
 }
=======================================
--- /trunk/src/hydrogen-instructions.cc Fri Oct  3 00:04:58 2014 UTC
+++ /trunk/src/hydrogen-instructions.cc Mon Oct 27 07:54:22 2014 UTC
@@ -2862,7 +2862,7 @@
   DCHECK(!object_.IsKnownGlobal(heap->nan_value()));
   return
 #define IMMORTAL_IMMOVABLE_ROOT(name) \
-      object_.IsKnownGlobal(heap->name()) ||
+  object_.IsKnownGlobal(heap->root(Heap::k##name##RootIndex)) ||
       IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
 #undef IMMORTAL_IMMOVABLE_ROOT
 #define INTERNALIZED_STRING(name, value) \
@@ -2873,9 +2873,6 @@
       object_.IsKnownGlobal(heap->name##_map()) ||
       STRING_TYPE_LIST(STRING_TYPE)
 #undef STRING_TYPE
-#define SYMBOL(name) object_.IsKnownGlobal(heap->name()) ||
-      PRIVATE_SYMBOL_LIST(SYMBOL)
-#undef SYMBOL
       false;
 }

=======================================
***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