Revision: 23475
Author:   [email protected]
Date:     Thu Aug 28 07:03:22 2014 UTC
Log:      Version 3.29.24 (based on bleeding_edge revision r23472)

Tweaks to generate XP-compatible .exes (Chromium issue 407517).

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

Added:
 /trunk/src/base/flags.h
 /trunk/test/base-unittests/flags-unittest.cc
 /trunk/test/mjsunit/harmony/regress/regress-405844.js
Modified:
 /trunk/AUTHORS
 /trunk/BUILD.gn
 /trunk/ChangeLog
 /trunk/build/standalone.gypi
 /trunk/src/arm/code-stubs-arm.cc
 /trunk/src/arm64/code-stubs-arm64.cc
 /trunk/src/base/platform/platform-posix.cc
 /trunk/src/code-stubs.cc
 /trunk/src/code-stubs.h
 /trunk/src/compiler/arm/code-generator-arm.cc
 /trunk/src/compiler/arm64/code-generator-arm64.cc
 /trunk/src/compiler/change-lowering.cc
 /trunk/src/compiler/change-lowering.h
 /trunk/src/compiler/code-generator.cc
 /trunk/src/compiler/code-generator.h
 /trunk/src/compiler/ia32/code-generator-ia32.cc
 /trunk/src/compiler/instruction-selector.cc
 /trunk/src/compiler/pipeline.cc
 /trunk/src/compiler/raw-machine-assembler.cc
 /trunk/src/compiler/raw-machine-assembler.h
 /trunk/src/compiler/simplified-lowering.cc
 /trunk/src/compiler/simplified-lowering.h
 /trunk/src/compiler/simplified-operator-reducer.cc
 /trunk/src/compiler/x64/code-generator-x64.cc
 /trunk/src/debug-debugger.js
 /trunk/src/factory.cc
 /trunk/src/factory.h
 /trunk/src/heap/mark-compact-inl.h
 /trunk/src/ia32/code-stubs-ia32.cc
 /trunk/src/math.js
 /trunk/src/mips/code-stubs-mips.cc
 /trunk/src/mips64/code-stubs-mips64.cc
 /trunk/src/v8natives.js
 /trunk/src/version.cc
 /trunk/src/x64/code-stubs-x64.cc
 /trunk/src/x87/code-stubs-x87.cc
 /trunk/src/zone-containers.h
 /trunk/test/base-unittests/base-unittests.gyp
 /trunk/test/base-unittests/sys-info-unittest.cc
 /trunk/test/cctest/compiler/test-changes-lowering.cc
 /trunk/test/cctest/compiler/test-codegen-deopt.cc
 /trunk/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc
 /trunk/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc
 /trunk/test/compiler-unittests/change-lowering-unittest.cc
 /trunk/test/compiler-unittests/graph-unittest.cc
 /trunk/test/compiler-unittests/graph-unittest.h
 /trunk/test/compiler-unittests/instruction-selector-unittest.cc
 /trunk/test/compiler-unittests/instruction-selector-unittest.h
 /trunk/test/compiler-unittests/simplified-operator-reducer-unittest.cc
 /trunk/tools/gyp/v8.gyp
 /trunk/tools/push-to-trunk/chromium_roll.py
 /trunk/tools/push-to-trunk/test_scripts.py
 /trunk/tools/whitespace.txt

=======================================
--- /dev/null
+++ /trunk/src/base/flags.h     Thu Aug 28 07:03:22 2014 UTC
@@ -0,0 +1,120 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_BASE_FLAGS_H_
+#define V8_BASE_FLAGS_H_
+
+#include "include/v8config.h"
+
+namespace v8 {
+namespace base {
+
+// The Flags class provides a type-safe way of storing OR-combinations of enum
+// values. The Flags<T> class is a template class, where T is an enum type.
+//
+// The traditional C++ approach for storing OR-combinations of enum values is to +// use an int or unsigned int variable. The inconvenience with this approach is +// that there's no type checking at all; any enum value can be OR'd with any +// other enum value and passed on to a function that takes an int or unsigned
+// int.
+template <typename T>
+class Flags V8_FINAL {
+ public:
+  typedef T flag_type;
+  typedef int mask_type;
+
+  Flags() : mask_(0) {}
+  Flags(flag_type flag) : mask_(flag) {}  // NOLINT(runtime/explicit)
+  explicit Flags(mask_type mask) : mask_(mask) {}
+
+  Flags& operator&=(const Flags& flags) {
+    mask_ &= flags.mask_;
+    return *this;
+  }
+  Flags& operator|=(const Flags& flags) {
+    mask_ |= flags.mask_;
+    return *this;
+  }
+  Flags& operator^=(const Flags& flags) {
+    mask_ ^= flags.mask_;
+    return *this;
+  }
+
+ Flags operator&(const Flags& flags) const { return Flags(*this) &= flags; } + Flags operator|(const Flags& flags) const { return Flags(*this) |= flags; } + Flags operator^(const Flags& flags) const { return Flags(*this) ^= flags; }
+
+  Flags& operator&=(flag_type flag) { return operator&=(Flags(flag)); }
+  Flags& operator|=(flag_type flag) { return operator|=(Flags(flag)); }
+  Flags& operator^=(flag_type flag) { return operator^=(Flags(flag)); }
+
+  Flags operator&(flag_type flag) const { return operator&(Flags(flag)); }
+  Flags operator|(flag_type flag) const { return operator|(Flags(flag)); }
+  Flags operator^(flag_type flag) const { return operator^(Flags(flag)); }
+
+  Flags operator~() const { return Flags(~mask_); }
+
+  operator mask_type() const { return mask_; }
+  bool operator!() const { return !mask_; }
+
+ private:
+  mask_type mask_;
+};
+
+
+#define DEFINE_FLAGS(Type, Enum) typedef ::v8::base::Flags<Enum> Type
+
+#define DEFINE_OPERATORS_FOR_FLAGS(Type) \ + inline ::v8::base::Flags<Type::flag_type> operator&( \ + Type::flag_type lhs, \ + Type::flag_type rhs)V8_UNUSED V8_WARN_UNUSED_RESULT; \ + inline ::v8::base::Flags<Type::flag_type> operator&(Type::flag_type lhs, \ + Type::flag_type rhs) { \ + return ::v8::base::Flags<Type::flag_type>(lhs) & rhs; \ + } \ + inline ::v8::base::Flags<Type::flag_type> operator&( \ + Type::flag_type lhs, const ::v8::base::Flags<Type::flag_type>& rhs) \ + V8_UNUSED V8_WARN_UNUSED_RESULT; \ + inline ::v8::base::Flags<Type::flag_type> operator&( \ + Type::flag_type lhs, const ::v8::base::Flags<Type::flag_type>& rhs) { \ + return rhs & lhs; \ + } \ + inline void operator&(Type::flag_type lhs, Type::mask_type rhs)V8_UNUSED; \ + inline void operator&(Type::flag_type lhs, Type::mask_type rhs) {} \ + inline ::v8::base::Flags<Type::flag_type> operator|(Type::flag_type lhs, \ + Type::flag_type rhs) \ + V8_UNUSED V8_WARN_UNUSED_RESULT; \ + inline ::v8::base::Flags<Type::flag_type> operator|(Type::flag_type lhs, \ + Type::flag_type rhs) { \ + return ::v8::base::Flags<Type::flag_type>(lhs) | rhs; \ + } \ + inline ::v8::base::Flags<Type::flag_type> operator| ( \ + Type::flag_type lhs, const ::v8::base::Flags<Type::flag_type>& rhs) \ + V8_UNUSED V8_WARN_UNUSED_RESULT; \ + inline ::v8::base::Flags<Type::flag_type> operator| ( \ + Type::flag_type lhs, const ::v8::base::Flags<Type::flag_type>& rhs) { \ + return rhs | lhs; \ + } \ + inline void operator|(Type::flag_type lhs, Type::mask_type rhs) V8_UNUSED; \ + inline void operator|(Type::flag_type lhs, Type::mask_type rhs) {} \ + inline ::v8::base::Flags<Type::flag_type> operator^(Type::flag_type lhs, \ + Type::flag_type rhs) \ + V8_UNUSED V8_WARN_UNUSED_RESULT; \ + inline ::v8::base::Flags<Type::flag_type> operator^(Type::flag_type lhs, \ + Type::flag_type rhs) { \ + return ::v8::base::Flags<Type::flag_type>(lhs) ^ rhs; \ + } inline ::v8::base::Flags<Type::flag_type> \ + operator^(Type::flag_type lhs, \ + const ::v8::base::Flags<Type::flag_type>& rhs) \ + V8_UNUSED V8_WARN_UNUSED_RESULT; \ + inline ::v8::base::Flags<Type::flag_type> operator^( \ + Type::flag_type lhs, const ::v8::base::Flags<Type::flag_type>& rhs) { \ + return rhs ^ lhs; \ + } inline void operator^(Type::flag_type lhs, Type::mask_type rhs) V8_UNUSED; \
+  inline void operator^(Type::flag_type lhs, Type::mask_type rhs) {}
+
+}  // namespace base
+}  // namespace v8
+
+#endif  // V8_BASE_FLAGS_H_
=======================================
--- /dev/null
+++ /trunk/test/base-unittests/flags-unittest.cc Thu Aug 28 07:03:22 2014 UTC
@@ -0,0 +1,103 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/flags.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+namespace {
+
+enum Flag1 {
+  kFlag1None = 0,
+  kFlag1First = 1u << 1,
+  kFlag1Second = 1u << 2,
+  kFlag1All = kFlag1None | kFlag1First | kFlag1Second
+};
+DEFINE_FLAGS(Flags1, Flag1);
+
+
+DEFINE_OPERATORS_FOR_FLAGS(Flags1)
+
+
+Flags1 bar(Flags1 flags1) { return flags1; }
+
+}  // namespace
+
+
+TEST(FlagsTest, BasicOperations) {
+  Flags1 a;
+  EXPECT_EQ(kFlag1None, static_cast<int>(a));
+  a |= kFlag1First;
+  EXPECT_EQ(kFlag1First, static_cast<int>(a));
+  a = a | kFlag1Second;
+  EXPECT_EQ(kFlag1All, static_cast<int>(a));
+  a &= kFlag1Second;
+  EXPECT_EQ(kFlag1Second, static_cast<int>(a));
+  a = kFlag1None & a;
+  EXPECT_EQ(kFlag1None, static_cast<int>(a));
+  a ^= (kFlag1All | kFlag1None);
+  EXPECT_EQ(kFlag1All, static_cast<int>(a));
+  Flags1 b = ~a;
+  EXPECT_EQ(kFlag1All, static_cast<int>(a));
+  EXPECT_EQ(~static_cast<int>(a), static_cast<int>(b));
+  Flags1 c = a;
+  EXPECT_EQ(a, c);
+  EXPECT_NE(a, b);
+  EXPECT_EQ(a, bar(a));
+  EXPECT_EQ(a, bar(kFlag1All));
+}
+
+
+namespace {
+namespace foo {
+
+enum Option {
+  kNoOptions = 0,
+  kOption1 = 1,
+  kOption2 = 2,
+  kAllOptions = kNoOptions | kOption1 | kOption2
+};
+DEFINE_FLAGS(Options, Option);
+
+}  // namespace foo
+
+
+DEFINE_OPERATORS_FOR_FLAGS(foo::Options)
+
+}  // namespace
+
+
+TEST(FlagsTest, NamespaceScope) {
+  foo::Options options;
+  options ^= foo::kNoOptions;
+  options |= foo::kOption1 | foo::kOption2;
+  EXPECT_EQ(foo::kAllOptions, static_cast<int>(options));
+}
+
+
+namespace {
+
+struct Foo {
+  enum Enum { kEnum1 = 1, kEnum2 = 2 };
+  DEFINE_FLAGS(Enums, Enum);
+};
+
+
+DEFINE_OPERATORS_FOR_FLAGS(Foo::Enums)
+
+}  // namespace
+
+
+TEST(FlagsTest, ClassScope) {
+  Foo::Enums enums;
+  enums |= Foo::kEnum1;
+  enums |= Foo::kEnum2;
+  EXPECT_TRUE(enums & Foo::kEnum1);
+  EXPECT_TRUE(enums & Foo::kEnum2);
+}
+
+}  // namespace base
+}  // namespace v8
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/harmony/regress/regress-405844.js Thu Aug 28 07:03:22 2014 UTC
@@ -0,0 +1,13 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-proxies
+
+var proxy = Proxy.create({ fix: function() { return {}; } });
+Object.preventExtensions(proxy);
+Object.observe(proxy, function(){});
+
+var functionProxy = Proxy.createFunction({ fix: function() { return {}; } }, function(){});
+Object.preventExtensions(functionProxy);
+Object.observe(functionProxy, function(){});
=======================================
--- /trunk/AUTHORS      Mon May 26 06:35:16 2014 UTC
+++ /trunk/AUTHORS      Thu Aug 28 07:03:22 2014 UTC
@@ -56,6 +56,7 @@
 Peter Varga <[email protected]>
 Rafal Krypa <[email protected]>
 Rajeev R Krithivasan <[email protected]>
+Refael Ackermann <[email protected]>
 Rene Rebe <[email protected]>
 Robert Mustacchi <[email protected]>
 Rodolph Perfetta <[email protected]>
=======================================
--- /trunk/BUILD.gn     Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/BUILD.gn     Thu Aug 28 07:03:22 2014 UTC
@@ -462,6 +462,8 @@
     "src/compilation-cache.h",
     "src/compiler/ast-graph-builder.cc",
     "src/compiler/ast-graph-builder.h",
+    "src/compiler/change-lowering.cc",
+    "src/compiler/change-lowering.h",
     "src/compiler/code-generator-impl.h",
     "src/compiler/code-generator.cc",
     "src/compiler/code-generator.h",
@@ -1163,6 +1165,7 @@
     "src/base/build_config.h",
     "src/base/cpu.cc",
     "src/base/cpu.h",
+    "src/base/flags.h",
     "src/base/lazy-instance.h",
     "src/base/logging.cc",
     "src/base/logging.h",
=======================================
--- /trunk/ChangeLog    Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/ChangeLog    Thu Aug 28 07:03:22 2014 UTC
@@ -1,3 +1,10 @@
+2014-08-28: Version 3.29.24
+
+        Tweaks to generate XP-compatible .exes (Chromium issue 407517).
+
+        Performance and stability improvements on all platforms.
+
+
 2014-08-28: Version 3.29.23

         Performance and stability improvements on all platforms.
=======================================
--- /trunk/build/standalone.gypi        Wed Aug  6 00:06:29 2014 UTC
+++ /trunk/build/standalone.gypi        Thu Aug 28 07:03:22 2014 UTC
@@ -263,6 +263,7 @@
         'defines': [
           '_CRT_SECURE_NO_DEPRECATE',
           '_CRT_NONSTDC_NO_DEPRECATE',
+          '_USING_V110_SDK71_',
         ],
         'conditions': [
           ['component=="static_library"', {
@@ -298,6 +299,7 @@
             'AdditionalOptions': ['/ignore:4221'],
           },
           'VCLinkerTool': {
+            'MinimumRequiredVersion': '5.01',  # XP.
             'AdditionalDependencies': [
               'ws2_32.lib',
             ],
=======================================
--- /trunk/src/arm/code-stubs-arm.cc    Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/arm/code-stubs-arm.cc    Thu Aug 28 07:03:22 2014 UTC
@@ -3723,7 +3723,7 @@

   // Tail call into the stub that handles binary operations with allocation
   // sites.
-  BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
   __ TailCallStub(&stub);
 }

=======================================
--- /trunk/src/arm64/code-stubs-arm64.cc        Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/arm64/code-stubs-arm64.cc        Thu Aug 28 07:03:22 2014 UTC
@@ -4332,7 +4332,7 @@

   // Tail call into the stub that handles binary operations with allocation
   // sites.
-  BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
   __ TailCallStub(&stub);
 }

=======================================
--- /trunk/src/base/platform/platform-posix.cc  Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/src/base/platform/platform-posix.cc  Thu Aug 28 07:03:22 2014 UTC
@@ -6,7 +6,6 @@
// own, but contains the parts which are the same across the POSIX platforms
 // Linux, MacOS, FreeBSD, OpenBSD, NetBSD and QNX.

-#include <dlfcn.h>
 #include <errno.h>
 #include <limits.h>
 #include <pthread.h>
@@ -20,10 +19,12 @@
 #include <sys/mman.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
+#if !defined(__pnacl__)
 #include <sys/syscall.h>
+#endif
 #include <sys/time.h>
 #include <sys/types.h>
-#if defined(__linux__)
+#if defined(__linux__) && !defined(__pnacl__)
 #include <sys/prctl.h>  // NOLINT, for prctl
 #endif
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) | | \
@@ -31,10 +32,6 @@
 #include <sys/sysctl.h>  // NOLINT, for sysctl
 #endif

-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-
 #undef MAP_TYPE

 #if defined(ANDROID) && !defined(V8_ANDROID_LOG_STDOUT)
@@ -55,6 +52,10 @@
 #include "src/base/atomicops.h"
 #endif

+#if V8_OS_MACOSX
+#include <dlfcn.h>
+#endif
+
 namespace v8 {
 namespace base {

@@ -252,9 +253,13 @@
 int OS::GetCurrentThreadId() {
 #if defined(ANDROID)
   return static_cast<int>(syscall(__NR_gettid));
+#elif defined(SYS_gettid)
+  return static_cast<int>(syscall(SYS_gettid));
 #else
-  return static_cast<int>(syscall(SYS_gettid));
-#endif  // defined(ANDROID)
+  // PNaCL doesn't have a way to get an integral thread ID, but it doesn't
+ // really matter, because we only need it in PerfJitLogger::LogRecordedBuffer.
+  return 0;
+#endif
 }


=======================================
--- /trunk/src/code-stubs.cc    Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/code-stubs.cc    Thu Aug 28 07:03:22 2014 UTC
@@ -291,7 +291,7 @@

 void BinaryOpICWithAllocationSiteStub::PrintState(
     OStream& os) const {  // NOLINT
-  os << state_;
+  os << state();
 }


=======================================
--- /trunk/src/code-stubs.h     Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/code-stubs.h     Thu Aug 28 07:03:22 2014 UTC
@@ -448,7 +448,7 @@
   explicit HydrogenCodeStub(Isolate* isolate,
                             InitializationState state = INITIALIZED)
       : CodeStub(isolate) {
-    is_uninitialized_ = (state == UNINITIALIZED);
+    minor_key_ = IsMissBits::encode(state == UNINITIALIZED);
   }

   virtual Code::Kind GetCodeKind() const { return Code::STUB; }
@@ -456,8 +456,6 @@
   CodeStubInterfaceDescriptor* GetInterfaceDescriptor() {
     return isolate()->code_stub_interface_descriptor(MajorKey());
   }
-
-  bool IsUninitialized() { return is_uninitialized_; }

   template<class SubClass>
   static Handle<Code> GetUninitialized(Isolate* isolate) {
@@ -471,24 +469,39 @@
   // Retrieve the code for the stub. Generate the code if needed.
   virtual Handle<Code> GenerateCode() = 0;

-  virtual int NotMissMinorKey() const = 0;
+  bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
+
+  // TODO(yangguo): we use this temporarily to construct the minor key.
+  //   We want to remove NotMissMinorKey methods one by one and eventually
+  //   remove HydrogenStub::MinorKey and turn CodeStub::MinorKey into a
+  //   non-virtual method that directly returns minor_key_.
+  virtual int NotMissMinorKey() const {
+    return SubMinorKeyBits::decode(minor_key_);
+  }

   Handle<Code> GenerateLightweightMissCode();

   template<class StateType>
   void TraceTransition(StateType from, StateType to);

+ protected:
+  void set_sub_minor_key(uint32_t key) {
+    minor_key_ = SubMinorKeyBits::update(minor_key_, key);
+  }
+
+ uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); }
+
+  static const int kSubMinorKeyBits = kStubMinorKeyBits - 1;
+
  private:
-  class MinorKeyBits: public BitField<int, 0, kStubMinorKeyBits - 1> {};
-  class IsMissBits: public BitField<bool, kStubMinorKeyBits - 1, 1> {};
+  class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {};
+  class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {};

   void GenerateLightweightMiss(MacroAssembler* masm);
   virtual uint32_t MinorKey() const {
-    return IsMissBits::encode(is_uninitialized_) |
-        MinorKeyBits::encode(NotMissMinorKey());
+    return IsMissBits::encode(IsUninitialized()) |
+           SubMinorKeyBits::encode(NotMissMinorKey());
   }
-
-  bool is_uninitialized_;
 };


@@ -572,8 +585,7 @@
   }

  private:
-  Major MajorKey() const { return ToNumber; }
-  int NotMissMinorKey() const { return 0; }
+  virtual Major MajorKey() const V8_OVERRIDE { return ToNumber; }
 };


@@ -593,18 +605,17 @@

  private:
   virtual Major MajorKey() const V8_OVERRIDE { return NumberToString; }
-  virtual int NotMissMinorKey() const V8_OVERRIDE { return 0; }
 };


 class FastNewClosureStub : public HydrogenCodeStub {
  public:
-  FastNewClosureStub(Isolate* isolate,
-                     StrictMode strict_mode,
+  FastNewClosureStub(Isolate* isolate, StrictMode strict_mode,
                      bool is_generator)
-      : HydrogenCodeStub(isolate),
-        strict_mode_(strict_mode),
-        is_generator_(is_generator) { }
+      : HydrogenCodeStub(isolate) {
+    set_sub_minor_key(StrictModeBits::encode(strict_mode) |
+                      IsGeneratorBits::encode(is_generator));
+  }

   virtual Handle<Code> GenerateCode() V8_OVERRIDE;

@@ -613,21 +624,19 @@

   static void InstallDescriptors(Isolate* isolate);

-  StrictMode strict_mode() const { return strict_mode_; }
-  bool is_generator() const { return is_generator_; }
+  StrictMode strict_mode() const {
+    return StrictModeBits::decode(sub_minor_key());
+  }
+
+ bool is_generator() const { return IsGeneratorBits::decode(sub_minor_key()); }

  private:
-  class StrictModeBits: public BitField<bool, 0, 1> {};
-  class IsGeneratorBits: public BitField<bool, 1, 1> {};
+  virtual Major MajorKey() const V8_OVERRIDE { return FastNewClosure; }

-  Major MajorKey() const { return FastNewClosure; }
-  int NotMissMinorKey() const {
-    return StrictModeBits::encode(strict_mode_ == STRICT) |
-      IsGeneratorBits::encode(is_generator_);
-  }
+  class StrictModeBits : public BitField<StrictMode, 0, 1> {};
+  class IsGeneratorBits : public BitField<bool, 1, 1> {};

-  StrictMode strict_mode_;
-  bool is_generator_;
+  DISALLOW_COPY_AND_ASSIGN(FastNewClosureStub);
 };


@@ -683,7 +692,7 @@

class AllocationSiteModeBits: public BitField<AllocationSiteMode, 0, 1> {};
   // Ensure data fits within available bits.
-  Major MajorKey() const { return FastCloneShallowArray; }
+ virtual Major MajorKey() const V8_OVERRIDE { return FastCloneShallowArray; }
   int NotMissMinorKey() const {
     return AllocationSiteModeBits::encode(allocation_site_mode_);
   }
@@ -711,7 +720,7 @@
  private:
   int length_;

-  Major MajorKey() const { return FastCloneShallowObject; }
+ virtual Major MajorKey() const V8_OVERRIDE { return FastCloneShallowObject; }
   int NotMissMinorKey() const { return length_; }

   DISALLOW_COPY_AND_ASSIGN(FastCloneShallowObjectStub);
@@ -731,8 +740,7 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return CreateAllocationSite; }
-  int NotMissMinorKey() const { return 0; }
+ virtual Major MajorKey() const V8_OVERRIDE { return CreateAllocationSite; }

   DISALLOW_COPY_AND_ASSIGN(CreateAllocationSiteStub);
 };
@@ -760,7 +768,7 @@
       CodeStubInterfaceDescriptor* descriptor);

  private:
-  Major MajorKey() const { return Instanceof; }
+  virtual Major MajorKey() const V8_OVERRIDE { return Instanceof; }

   Flags flags() const { return FlagBits::decode(minor_key_); }

@@ -799,7 +807,7 @@
   void Generate(MacroAssembler* masm);

  private:
-  virtual CodeStub::Major MajorKey() const { return ArrayConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE { return ArrayConstructor; }

   ArgumentCountKey argument_count() const {
     return ArgumentCountBits::decode(minor_key_);
@@ -823,7 +831,9 @@
   void Generate(MacroAssembler* masm);

  private:
- virtual CodeStub::Major MajorKey() const { return InternalArrayConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return InternalArrayConstructor;
+  }

   void GenerateCase(MacroAssembler* masm, ElementsKind kind);

@@ -843,7 +853,7 @@
   virtual void Generate(MacroAssembler* masm);

  private:
-  virtual CodeStub::Major MajorKey() const { return MathPow; }
+  virtual Major MajorKey() const V8_OVERRIDE { return MathPow; }

   ExponentType exponent_type() const {
     return ExponentTypeBits::decode(minor_key_);
@@ -890,7 +900,7 @@
   void GenerateMiss(MacroAssembler* masm, IC::UtilityId id);

  private:
-  virtual CodeStub::Major MajorKey() const { return CallIC; }
+  virtual Major MajorKey() const V8_OVERRIDE { return CallIC; }

   virtual void PrintState(OStream& os) const V8_OVERRIDE;  // NOLINT

@@ -912,7 +922,7 @@
  private:
   virtual void PrintState(OStream& os) const V8_OVERRIDE;  // NOLINT

-  virtual CodeStub::Major MajorKey() const { return CallIC_Array; }
+  virtual Major MajorKey() const V8_OVERRIDE { return CallIC_Array; }

   DISALLOW_COPY_AND_ASSIGN(CallIC_ArrayStub);
 };
@@ -927,7 +937,7 @@
   virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }

  private:
-  virtual CodeStub::Major MajorKey() const { return FunctionPrototype; }
+  virtual Major MajorKey() const V8_OVERRIDE { return FunctionPrototype; }

   DISALLOW_COPY_AND_ASSIGN(FunctionPrototypeStub);
 };
@@ -970,7 +980,7 @@

  private:
   class EncodedLoadFieldByIndexBits : public BitField<int, 0, 13> {};
-  virtual CodeStub::Major MajorKey() const { return LoadField; }
+  virtual Major MajorKey() const V8_OVERRIDE { return LoadField; }
   FieldIndex index_;
 };

@@ -991,7 +1001,7 @@
   virtual Code::StubType GetStubType() { return Code::FAST; }

  private:
-  virtual CodeStub::Major MajorKey() const { return LoadConstant; }
+  virtual Major MajorKey() const V8_OVERRIDE { return LoadConstant; }
 };


@@ -1005,7 +1015,7 @@
   virtual Code::StubType GetStubType() { return Code::FAST; }

  private:
-  virtual CodeStub::Major MajorKey() const { return StringLength; }
+  virtual Major MajorKey() const V8_OVERRIDE { return StringLength; }
 };


@@ -1034,7 +1044,7 @@
  private:
   class EncodedStoreFieldByIndexBits : public BitField<int, 0, 13> {};
   class RepresentationBits : public BitField<int, 13, 4> {};
-  virtual CodeStub::Major MajorKey() const { return StoreField; }
+  virtual Major MajorKey() const V8_OVERRIDE { return StoreField; }
   FieldIndex index_;
   Representation representation_;
 };
@@ -1089,7 +1099,7 @@
   }

  private:
-  Major MajorKey() const { return StoreGlobal; }
+  virtual Major MajorKey() const V8_OVERRIDE { return StoreGlobal; }

   class IsConstantBits: public BitField<bool, 0, 1> {};
   class RepresentationBits: public BitField<Representation::Kind, 1, 8> {};
@@ -1201,7 +1211,7 @@
  public:
   BinaryOpICWithAllocationSiteStub(Isolate* isolate,
                                    const BinaryOpIC::State& state)
-      : PlatformCodeStub(isolate), state_(state) {
+      : PlatformCodeStub(isolate) {
     minor_key_ = state.GetExtraICState();
   }

@@ -1218,11 +1228,11 @@
   }

   virtual InlineCacheState GetICState() const V8_OVERRIDE {
-    return state_.GetICState();
+    return state().GetICState();
   }

   virtual ExtraICState GetExtraICState() const V8_OVERRIDE {
-    return state_.GetExtraICState();
+    return static_cast<ExtraICState>(minor_key_);
   }

   virtual void Generate(MacroAssembler* masm) V8_OVERRIDE;
@@ -1232,14 +1242,15 @@
   virtual Major MajorKey() const V8_OVERRIDE {
     return BinaryOpICWithAllocationSite;
   }
- virtual uint32_t MinorKey() const V8_OVERRIDE { return GetExtraICState(); }

  private:
+  BinaryOpIC::State state() const {
+ return BinaryOpIC::State(isolate(), static_cast<ExtraICState>(minor_key_));
+  }
+
   static void GenerateAheadOfTime(Isolate* isolate,
                                   const BinaryOpIC::State& state);

-  BinaryOpIC::State state_;
-
   DISALLOW_COPY_AND_ASSIGN(BinaryOpICWithAllocationSiteStub);
 };

@@ -1362,7 +1373,7 @@
   class RightStateField: public BitField<int, 7, 4> { };
   class HandlerStateField: public BitField<int, 11, 4> { };

-  virtual CodeStub::Major MajorKey() const { return CompareIC; }
+  virtual Major MajorKey() const V8_OVERRIDE { return CompareIC; }
   virtual uint32_t MinorKey() const;

   virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; }
@@ -1481,7 +1492,7 @@
   class NilValueField : public BitField<NilValue, 0, 1> {};
   class TypesField    : public BitField<byte,     1, NUMBER_OF_TYPES> {};

-  virtual CodeStub::Major MajorKey() const { return CompareNilIC; }
+  virtual Major MajorKey() const V8_OVERRIDE { return CompareNilIC; }
   virtual int NotMissMinorKey() const { return GetExtraICState(); }

   NilValue nil_value_;
@@ -1515,7 +1526,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);

  private:
-  Major MajorKey() const { return CEntry; }
+  virtual Major MajorKey() const V8_OVERRIDE { return CEntry; }

   bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
 #ifdef _WIN64
@@ -1541,7 +1552,7 @@
   void GenerateBody(MacroAssembler* masm, bool is_construct);

  private:
-  Major MajorKey() const { return JSEntry; }
+  virtual Major MajorKey() const V8_OVERRIDE { return JSEntry; }

   virtual void FinishCode(Handle<Code> code);

@@ -1582,7 +1593,7 @@
   }

  private:
-  Major MajorKey() const { return ArgumentsAccess; }
+  virtual Major MajorKey() const V8_OVERRIDE { return ArgumentsAccess; }

   Type type() const { return TypeBits::decode(minor_key_); }

@@ -1605,7 +1616,7 @@
   explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }

  private:
-  Major MajorKey() const { return RegExpExec; }
+  virtual Major MajorKey() const V8_OVERRIDE { return RegExpExec; }

   void Generate(MacroAssembler* masm);

@@ -1624,7 +1635,6 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

virtual Major MajorKey() const V8_OVERRIDE { return RegExpConstructResult; }
-  virtual int NotMissMinorKey() const V8_OVERRIDE { return 0; }

   static void InstallDescriptors(Isolate* isolate);

@@ -1656,7 +1666,7 @@
       CodeStubInterfaceDescriptor* descriptor);

  private:
-  Major MajorKey() const { return CallFunction; }
+  virtual Major MajorKey() const V8_OVERRIDE { return CallFunction; }

   int argc() const { return ArgcBits::decode(minor_key_); }
   int flags() const { return FlagBits::decode(minor_key_); }
@@ -1695,7 +1705,7 @@
       CodeStubInterfaceDescriptor* descriptor);

  private:
-  Major MajorKey() const { return CallConstruct; }
+  virtual Major MajorKey() const V8_OVERRIDE { return CallConstruct; }

CallConstructorFlags flags() const { return FlagBits::decode(minor_key_); }

@@ -1888,7 +1898,9 @@
 class LoadDictionaryElementStub : public HydrogenCodeStub {
  public:
   explicit LoadDictionaryElementStub(Isolate* isolate)
-      : HydrogenCodeStub(isolate) {}
+      : HydrogenCodeStub(isolate) {
+    set_sub_minor_key(DICTIONARY_ELEMENTS);
+  }

   virtual Handle<Code> GenerateCode() V8_OVERRIDE;

@@ -1896,8 +1908,7 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return LoadElement; }
-  int NotMissMinorKey() const { return DICTIONARY_ELEMENTS; }
+  virtual Major MajorKey() const V8_OVERRIDE { return LoadElement; }

   DISALLOW_COPY_AND_ASSIGN(LoadDictionaryElementStub);
 };
@@ -1913,7 +1924,7 @@
   void Generate(MacroAssembler* masm);

  private:
-  Major MajorKey() const { return LoadElement; }
+  virtual Major MajorKey() const V8_OVERRIDE { return LoadElement; }

   DISALLOW_COPY_AND_ASSIGN(LoadDictionaryElementPlatformStub);
 };
@@ -1934,8 +1945,7 @@
   virtual InlineCacheState GetICState() const { return GENERIC; }

  private:
-  Major MajorKey() const { return KeyedLoadGeneric; }
-  int NotMissMinorKey() const { return 0; }
+  virtual Major MajorKey() const V8_OVERRIDE { return KeyedLoadGeneric; }

   DISALLOW_COPY_AND_ASSIGN(KeyedLoadGenericStub);
 };
@@ -2063,7 +2073,7 @@
   virtual bool SometimesSetsUpAFrame() { return false; }

  private:
-  Major MajorKey() const { return DoubleToI; }
+  virtual Major MajorKey() const V8_OVERRIDE { return DoubleToI; }

   Register source() const {
     return Register::from_code(SourceRegisterBits::decode(minor_key_));
@@ -2124,7 +2134,7 @@
   class IsJSArrayBits: public BitField<bool, 8, 1> {};
   uint32_t bit_field_;

-  Major MajorKey() const { return LoadElement; }
+  virtual Major MajorKey() const V8_OVERRIDE { return LoadElement; }
   int NotMissMinorKey() const { return bit_field_; }

   DISALLOW_COPY_AND_ASSIGN(LoadFastElementStub);
@@ -2164,7 +2174,7 @@
   class IsJSArrayBits: public BitField<bool,                12, 1> {};
   uint32_t bit_field_;

-  Major MajorKey() const { return StoreElement; }
+  virtual Major MajorKey() const V8_OVERRIDE { return StoreElement; }
   int NotMissMinorKey() const { return bit_field_; }

   DISALLOW_COPY_AND_ASSIGN(StoreFastElementStub);
@@ -2205,7 +2215,7 @@
   class IsJSArrayBits: public BitField<bool, 16, 1> {};
   uint32_t bit_field_;

-  Major MajorKey() const { return TransitionElementsKind; }
+ virtual Major MajorKey() const V8_OVERRIDE { return TransitionElementsKind; }
   int NotMissMinorKey() const { return bit_field_; }

   DISALLOW_COPY_AND_ASSIGN(TransitionElementsKindStub);
@@ -2275,7 +2285,9 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return ArrayNoArgumentConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return ArrayNoArgumentConstructor;
+  }

   virtual void PrintName(OStream& os) const V8_OVERRIDE {  // NOLINT
     BasePrintName(os, "ArrayNoArgumentConstructorStub");
@@ -2300,7 +2312,9 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return ArraySingleArgumentConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return ArraySingleArgumentConstructor;
+  }

   virtual void PrintName(OStream& os) const {  // NOLINT
     BasePrintName(os, "ArraySingleArgumentConstructorStub");
@@ -2325,7 +2339,9 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return ArrayNArgumentsConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return ArrayNArgumentsConstructor;
+  }

   virtual void PrintName(OStream& os) const {  // NOLINT
     BasePrintName(os, "ArrayNArgumentsConstructorStub");
@@ -2372,7 +2388,9 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return InternalArrayNoArgumentConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return InternalArrayNoArgumentConstructor;
+  }

   DISALLOW_COPY_AND_ASSIGN(InternalArrayNoArgumentConstructorStub);
 };
@@ -2391,7 +2409,9 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return InternalArraySingleArgumentConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return InternalArraySingleArgumentConstructor;
+  }

   DISALLOW_COPY_AND_ASSIGN(InternalArraySingleArgumentConstructorStub);
 };
@@ -2409,7 +2429,9 @@
       CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;

  private:
-  Major MajorKey() const { return InternalArrayNArgumentsConstructor; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return InternalArrayNArgumentsConstructor;
+  }

   DISALLOW_COPY_AND_ASSIGN(InternalArrayNArgumentsConstructorStub);
 };
@@ -2425,7 +2447,7 @@
   void Generate(MacroAssembler* masm);

  private:
-  Major MajorKey() const { return StoreElement; }
+  virtual Major MajorKey() const V8_OVERRIDE { return StoreElement; }

   ElementsKind elements_kind() const {
     return ElementsKindBits::decode(minor_key_);
@@ -2519,7 +2541,7 @@
   class TypesBits : public BitField<byte, 0, NUMBER_OF_TYPES> {};
class ResultModeBits : public BitField<ResultMode, NUMBER_OF_TYPES, 2> {};

-  Major MajorKey() const { return ToBoolean; }
+  virtual Major MajorKey() const V8_OVERRIDE { return ToBoolean; }
   int NotMissMinorKey() const {
return TypesBits::encode(types_.ToByte()) | ResultModeBits::encode(mode_);
   }
@@ -2584,7 +2606,9 @@
   class IsJSArrayBits: public BitField<bool,                 16, 1> {};
   class StoreModeBits: public BitField<KeyedAccessStoreMode, 17, 4> {};

-  Major MajorKey() const { return ElementsTransitionAndStore; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return ElementsTransitionAndStore;
+  }
   int NotMissMinorKey() const {
     return FromBits::encode(from_kind_) |
         ToBits::encode(to_kind_) |
@@ -2607,7 +2631,9 @@
       : PlatformCodeStub(isolate) { }

  private:
-  Major MajorKey() const { return StoreArrayLiteralElement; }
+  virtual Major MajorKey() const V8_OVERRIDE {
+    return StoreArrayLiteralElement;
+  }

   void Generate(MacroAssembler* masm);

@@ -2625,7 +2651,7 @@
   static void GenerateAheadOfTime(Isolate* isolate);

  private:
-  Major MajorKey() const { return StubFailureTrampoline; }
+ virtual Major MajorKey() const V8_OVERRIDE { return StubFailureTrampoline; }

   StubFunctionMode function_mode() const {
     return FunctionModeField::decode(minor_key_);
@@ -2654,7 +2680,7 @@
                                   intptr_t stack_pointer,
                                   Isolate* isolate);

-  Major MajorKey() const { return ProfileEntryHook; }
+  virtual Major MajorKey() const V8_OVERRIDE { return ProfileEntryHook; }

   void Generate(MacroAssembler* masm);

=======================================
--- /trunk/src/compiler/arm/code-generator-arm.cc Thu Aug 28 00:05:02 2014 UTC +++ /trunk/src/compiler/arm/code-generator-arm.cc Thu Aug 28 07:03:22 2014 UTC
@@ -166,8 +166,8 @@
       break;
     }
     case kArchDeoptimize: {
-      int deoptimization_id = MiscField::decode(instr->opcode());
-      BuildTranslation(instr, 0, deoptimization_id);
+      int deoptimization_id = BuildTranslation(instr, 0);
+
       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
           isolate(), deoptimization_id, Deoptimizer::LAZY);
       __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
=======================================
--- /trunk/src/compiler/arm64/code-generator-arm64.cc Thu Aug 28 00:05:02 2014 UTC +++ /trunk/src/compiler/arm64/code-generator-arm64.cc Thu Aug 28 07:03:22 2014 UTC
@@ -160,8 +160,8 @@
       break;
     }
     case kArchDeoptimize: {
-      int deoptimization_id = MiscField::decode(instr->opcode());
-      BuildTranslation(instr, 0, deoptimization_id);
+      int deoptimization_id = BuildTranslation(instr, 0);
+
       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
           isolate(), deoptimization_id, Deoptimizer::LAZY);
       __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
=======================================
--- /trunk/src/compiler/change-lowering.cc      Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/compiler/change-lowering.cc      Thu Aug 28 07:03:22 2014 UTC
@@ -27,12 +27,9 @@
     case IrOpcode::kChangeTaggedToFloat64:
       return ChangeTaggedToFloat64(node->InputAt(0), control);
     case IrOpcode::kChangeTaggedToInt32:
+      return ChangeTaggedToI32(node->InputAt(0), control, true);
     case IrOpcode::kChangeTaggedToUint32:
-      // ToInt32 and ToUint32 perform exactly the same operation, just the
- // interpretation of the resulting 32 bit value is different, so we can
-      // use the same subgraph for both operations.
-      // See ECMA-262 9.5: ToInt32 and ECMA-262 9.6: ToUint32.
-      return ChangeTaggedToInt32(node->InputAt(0), control);
+      return ChangeTaggedToI32(node->InputAt(0), control, false);
     case IrOpcode::kChangeUint32ToTagged:
       return ChangeUint32ToTagged(node->InputAt(0), control);
     default:
@@ -170,7 +167,8 @@
 }


-Reduction ChangeLowering::ChangeTaggedToInt32(Node* val, Node* control) {
+Reduction ChangeLowering::ChangeTaggedToI32(Node* val, Node* control,
+                                            bool is_signed) {
   STATIC_ASSERT(kSmiTag == 0);
   STATIC_ASSERT(kSmiTagMask == 1);

@@ -179,8 +177,9 @@
   Node* branch = graph()->NewNode(common()->Branch(), tag, control);

   Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* change = graph()->NewNode(machine()->TruncateFloat64ToInt32(),
-                                  LoadHeapNumberValue(val, if_true));
+  Operator* op = is_signed ? machine()->ChangeFloat64ToInt32()
+                           : machine()->ChangeFloat64ToUint32();
+  Node* change = graph()->NewNode(op, LoadHeapNumberValue(val, if_true));

   Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
   Node* number = ChangeSmiToInt32(val);
=======================================
--- /trunk/src/compiler/change-lowering.h       Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/compiler/change-lowering.h       Thu Aug 28 07:03:22 2014 UTC
@@ -40,7 +40,7 @@
   Reduction ChangeFloat64ToTagged(Node* val, Node* control);
   Reduction ChangeInt32ToTagged(Node* val, Node* control);
   Reduction ChangeTaggedToFloat64(Node* val, Node* control);
-  Reduction ChangeTaggedToInt32(Node* val, Node* control);
+  Reduction ChangeTaggedToI32(Node* val, Node* control, bool is_signed);
   Reduction ChangeUint32ToTagged(Node* val, Node* control);

   Graph* graph() const;
=======================================
--- /trunk/src/compiler/code-generator.cc       Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/compiler/code-generator.cc       Thu Aug 28 07:03:22 2014 UTC
@@ -258,10 +258,9 @@
     // If the frame state is present, it starts at argument 1
     // (just after the code address).
     InstructionOperandConverter converter(this, instr);
-    // Argument 1 is deoptimization id.
- int deoptimization_id = converter.ToConstant(instr->InputAt(1)).ToInt32();
-    // The actual frame state values start with argument 2.
-    int first_state_value_offset = 2;
+    // Deoptimization info starts at argument 1
+    int frame_state_offset = 1;
+    int deoptimization_id = BuildTranslation(instr, frame_state_offset);
 #if DEBUG
     // Make sure all the values live in stack slots or they are immediates.
// (The values should not live in register because registers are clobbered
@@ -269,11 +268,10 @@
     FrameStateDescriptor* descriptor =
         code()->GetDeoptimizationEntry(deoptimization_id);
     for (int i = 0; i < descriptor->size(); i++) {
- InstructionOperand* op = instr->InputAt(first_state_value_offset + i);
+      InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i);
       CHECK(op->IsStackSlot() || op->IsImmediate());
     }
 #endif
-    BuildTranslation(instr, first_state_value_offset, deoptimization_id);
     safepoints()->RecordLazyDeoptimizationIndex(deoptimization_id);
   }
 }
@@ -310,9 +308,12 @@
 }


-void CodeGenerator::BuildTranslation(Instruction* instr,
-                                     int first_argument_index,
-                                     int deoptimization_id) {
+int CodeGenerator::BuildTranslation(Instruction* instr,
+                                    int frame_state_offset) {
+  InstructionOperandConverter i(this, instr);
+  int deoptimization_id = i.InputInt32(frame_state_offset);
+  frame_state_offset++;
+
   // We should build translation only once.
   DCHECK_EQ(NULL, deoptimization_states_[deoptimization_id]);

@@ -325,11 +326,13 @@

   for (int i = 0; i < descriptor->size(); i++) {
     AddTranslationForOperand(&translation, instr,
-                             instr->InputAt(i + first_argument_index));
+                             instr->InputAt(i + frame_state_offset));
   }

   deoptimization_states_[deoptimization_id] =
       new (zone()) DeoptimizationState(translation.index());
+
+  return deoptimization_id;
 }


=======================================
--- /trunk/src/compiler/code-generator.h        Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/compiler/code-generator.h        Thu Aug 28 07:03:22 2014 UTC
@@ -87,8 +87,7 @@
                                      Safepoint::Id safepoint_id);
   void PopulateDeoptimizationData(Handle<Code> code);
   int DefineDeoptimizationLiteral(Handle<Object> literal);
-  void BuildTranslation(Instruction* instr, int first_argument_index,
-                        int deoptimization_id);
+  int BuildTranslation(Instruction* instr, int frame_state_offset);
void AddTranslationForOperand(Translation* translation, Instruction* instr,
                                 InstructionOperand* op);
   void AddNopForSmiCodeInlining();
=======================================
--- /trunk/src/compiler/ia32/code-generator-ia32.cc Thu Aug 28 00:05:02 2014 UTC +++ /trunk/src/compiler/ia32/code-generator-ia32.cc Thu Aug 28 07:03:22 2014 UTC
@@ -141,8 +141,7 @@
       break;
     }
     case kArchDeoptimize: {
-      int deoptimization_id = MiscField::decode(instr->opcode());
-      BuildTranslation(instr, 0, deoptimization_id);
+      int deoptimization_id = BuildTranslation(instr, 0);

       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
           isolate(), deoptimization_id, Deoptimizer::LAZY);
=======================================
--- /trunk/src/compiler/instruction-selector.cc Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/compiler/instruction-selector.cc Thu Aug 28 07:03:22 2014 UTC
@@ -1082,17 +1082,19 @@
   DCHECK(deopt->op()->opcode() == IrOpcode::kDeoptimize);
   Node* state = deopt->InputAt(0);
   FrameStateDescriptor* descriptor = GetFrameStateDescriptor(state);
+  int deoptimization_id = sequence()->AddDeoptimizationEntry(descriptor);

   InstructionOperandVector inputs(zone());
-  inputs.reserve(descriptor->size());
+  inputs.reserve(descriptor->size() + 1);
+
+  OperandGenerator g(this);
+  inputs.push_back(g.TempImmediate(deoptimization_id));

   AddFrameStateInputs(state, &inputs, descriptor);

-  DCHECK_EQ(descriptor->size(), inputs.size());
+  DCHECK_EQ(descriptor->size() + 1, inputs.size());

-  int deoptimization_id = sequence()->AddDeoptimizationEntry(descriptor);
-  Emit(kArchDeoptimize | MiscField::encode(deoptimization_id), 0, NULL,
-       inputs.size(), &inputs.front(), 0, NULL);
+  Emit(kArchDeoptimize, 0, NULL, inputs.size(), &inputs.front(), 0, NULL);
 }


=======================================
--- /trunk/src/compiler/pipeline.cc     Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/compiler/pipeline.cc     Thu Aug 28 07:03:22 2014 UTC
@@ -6,6 +6,7 @@

 #include "src/base/platform/elapsed-timer.h"
 #include "src/compiler/ast-graph-builder.h"
+#include "src/compiler/change-lowering.h"
 #include "src/compiler/code-generator.h"
 #include "src/compiler/graph-replay.h"
 #include "src/compiler/graph-visualizer.h"
@@ -233,6 +234,32 @@

       VerifyAndPrintGraph(&graph, "Lowered typed");
     }
+    {
+      // Lower simplified operators and insert changes.
+      PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
+                                "simplified lowering");
+      SourcePositionTable::Scope pos(&source_positions,
+                                     SourcePosition::Unknown());
+      SimplifiedLowering lowering(&jsgraph);
+      lowering.LowerAllNodes();
+
+      VerifyAndPrintGraph(&graph, "Lowered simplified");
+    }
+    {
+      // Lower changes that have been inserted before.
+      PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
+                                "change lowering");
+      SourcePositionTable::Scope pos(&source_positions,
+                                     SourcePosition::Unknown());
+      Linkage linkage(info());
+      MachineOperatorBuilder machine(zone());
+      ChangeLowering lowering(&jsgraph, &linkage, &machine);
+      GraphReducer graph_reducer(&graph);
+      graph_reducer.AddReducer(&lowering);
+      graph_reducer.ReduceGraph();
+
+      VerifyAndPrintGraph(&graph, "Lowered changes");
+    }
   }

   Handle<Code> code = Handle<Code>::null();
=======================================
--- /trunk/src/compiler/raw-machine-assembler.cc Sun Aug 24 11:34:17 2014 UTC +++ /trunk/src/compiler/raw-machine-assembler.cc Thu Aug 28 07:03:22 2014 UTC
@@ -81,6 +81,31 @@
   schedule()->AddDeoptimize(CurrentBlock(), deopt);
   current_block_ = NULL;
 }
+
+
+Node* RawMachineAssembler::CallFunctionStub0(Node* function, Node* receiver, + Node* context, Node* frame_state,
+                                             Label* continuation,
+                                             Label* deoptimization,
+                                             CallFunctionFlags flags) {
+  CallFunctionStub stub(isolate(), 0, flags);
+ CodeStubInterfaceDescriptor* d = isolate()->code_stub_interface_descriptor(
+      reinterpret_cast<CodeStub*>(&stub)->MajorKey());
+  stub.InitializeInterfaceDescriptor(d);
+
+  CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+      d, 1, static_cast<CallDescriptor::DeoptimizationSupport>(
+                CallDescriptor::kLazyDeoptimization |
+                CallDescriptor::kNeedsFrameState),
+      zone());
+  Node* stub_code = HeapConstant(stub.GetCode());
+  Node* call = graph()->NewNode(common()->Call(desc), stub_code, function,
+                                receiver, context, frame_state);
+  schedule()->AddCall(CurrentBlock(), call, Use(continuation),
+                      Use(deoptimization));
+  current_block_ = NULL;
+  return call;
+}


 Node* RawMachineAssembler::CallJS0(Node* function, Node* receiver,
=======================================
--- /trunk/src/compiler/raw-machine-assembler.h Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/compiler/raw-machine-assembler.h Thu Aug 28 07:03:22 2014 UTC
@@ -71,6 +71,10 @@
   Label* Exit();
   void Goto(Label* label);
   void Branch(Node* condition, Label* true_val, Label* false_val);
+  // Call through CallFunctionStub with lazy deopt and frame-state.
+  Node* CallFunctionStub0(Node* function, Node* receiver, Node* context,
+                          Node* frame_state, Label* continuation,
+                          Label* deoptimization, CallFunctionFlags flags);
   // Call to a JS function with zero parameters.
   Node* CallJS0(Node* function, Node* receiver, Label* continuation,
                 Label* deoptimization);
=======================================
--- /trunk/src/compiler/simplified-lowering.cc  Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/compiler/simplified-lowering.cc  Thu Aug 28 07:03:22 2014 UTC
@@ -726,10 +726,6 @@
                                 graph()->zone()->isolate());
   RepresentationSelector selector(jsgraph(), zone(), &changer);
   selector.Run(this);
-
-  GraphReducer graph_reducer(graph());
-  graph_reducer.AddReducer(this);
-  graph_reducer.ReduceGraph();
 }


@@ -750,157 +746,6 @@
 Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) {
   return jsgraph()->Int32Constant(offset - kHeapObjectTag);
 }
-
-
-static void UpdateControlSuccessors(Node* before, Node* node) {
-  DCHECK(IrOpcode::IsControlOpcode(before->opcode()));
-  UseIter iter = before->uses().begin();
-  while (iter != before->uses().end()) {
-    if (IrOpcode::IsControlOpcode((*iter)->opcode()) &&
-        NodeProperties::IsControlEdge(iter.edge())) {
-      iter = iter.UpdateToAndIncrement(node);
-      continue;
-    }
-    ++iter;
-  }
-}
-
-
-void SimplifiedLowering::DoChangeTaggedToUI32(Node* node, Node* effect,
- Node* control, bool is_signed) {
-  // if (IsTagged(val))
- // ConvertFloat64To(Int32|Uint32)(Load[kMachFloat64](input, #value_offset))
-  // else Untag(val)
-  Node* val = node->InputAt(0);
- Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
-
-  // true branch.
-  Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
-  Node* loaded = graph()->NewNode(
-      machine()->Load(kMachFloat64), val,
-      OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
-  Operator* op = is_signed ? machine()->ChangeFloat64ToInt32()
-                           : machine()->ChangeFloat64ToUint32();
-  Node* converted = graph()->NewNode(op, loaded);
-
-  // false branch.
-  Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
-  Node* untagged = Untag(val);
-
-  // merge.
-  Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
- Node* phi = graph()->NewNode(common()->Phi(2), converted, untagged, merge);
-  UpdateControlSuccessors(control, merge);
-  branch->ReplaceInput(1, control);
-  node->ReplaceUses(phi);
-}
-
-
-void SimplifiedLowering::DoChangeTaggedToFloat64(Node* node, Node* effect,
-                                                 Node* control) {
-  // if (IsTagged(input)) Load[kMachFloat64](input, #value_offset)
-  // else ConvertFloat64(Untag(input))
-  Node* val = node->InputAt(0);
- Node* branch = graph()->NewNode(common()->Branch(), IsTagged(val), control);
-
-  // true branch.
-  Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
-  Node* loaded = graph()->NewNode(
-      machine()->Load(kMachFloat64), val,
-      OffsetMinusTagConstant(HeapNumber::kValueOffset), effect);
-
-  // false branch.
-  Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
-  Node* untagged = Untag(val);
-  Node* converted =
-      graph()->NewNode(machine()->ChangeInt32ToFloat64(), untagged);
-
-  // merge.
-  Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
-  Node* phi = graph()->NewNode(common()->Phi(2), loaded, converted, merge);
-  UpdateControlSuccessors(control, merge);
-  branch->ReplaceInput(1, control);
-  node->ReplaceUses(phi);
-}
-
-
-void SimplifiedLowering::DoChangeUI32ToTagged(Node* node, Node* effect,
- Node* control, bool is_signed) {
-  Node* val = node->InputAt(0);
-  Node* is_smi = NULL;
-  if (is_signed) {
-    if (SmiValuesAre32Bits()) {
-      // All int32s fit in this case.
-      DCHECK(kPointerSize == 8);
-      return node->ReplaceUses(SmiTag(val));
-    } else {
-      // TODO(turbofan): use an Int32AddWithOverflow to tag and check here.
-      Node* lt = graph()->NewNode(machine()->Int32LessThanOrEqual(), val,
- jsgraph()->Int32Constant(Smi::kMaxValue));
-      Node* gt =
-          graph()->NewNode(machine()->Int32LessThanOrEqual(),
-                           jsgraph()->Int32Constant(Smi::kMinValue), val);
-      is_smi = graph()->NewNode(machine()->Word32And(), lt, gt);
-    }
-  } else {
-    // Check if Uint32 value is in the smi range.
-    is_smi = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
-                              jsgraph()->Int32Constant(Smi::kMaxValue));
-  }
-
-  // TODO(turbofan): fold smi test branch eagerly.
-  // if (IsSmi(input)) SmiTag(input);
-  // else InlineAllocAndInitHeapNumber(ConvertToFloat64(input)))
-  Node* branch = graph()->NewNode(common()->Branch(), is_smi, control);
-
-  // true branch.
-  Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
-  Node* smi_tagged = SmiTag(val);
-
-  // false branch.
-  Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
- Node* heap_num = jsgraph()->Constant(0.0); // TODO(titzer): alloc and init
-
-  // merge.
-  Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
- Node* phi = graph()->NewNode(common()->Phi(2), smi_tagged, heap_num, merge);
-  UpdateControlSuccessors(control, merge);
-  branch->ReplaceInput(1, control);
-  node->ReplaceUses(phi);
-}
-
-
-void SimplifiedLowering::DoChangeFloat64ToTagged(Node* node, Node* effect,
-                                                 Node* control) {
-  return;  // TODO(titzer): need to call runtime to allocate in one branch
-}
-
-
-void SimplifiedLowering::DoChangeBoolToBit(Node* node, Node* effect,
-                                           Node* control) {
-  Node* cmp = graph()->NewNode(machine()->WordEqual(), node->InputAt(0),
-                               jsgraph()->TrueConstant());
-  node->ReplaceUses(cmp);
-}
-
-
-void SimplifiedLowering::DoChangeBitToBool(Node* node, Node* effect,
-                                           Node* control) {
-  Node* val = node->InputAt(0);
-  Node* branch = graph()->NewNode(common()->Branch(), val, control);
-
-  // true branch.
-  Node* tbranch = graph()->NewNode(common()->IfTrue(), branch);
-  // false branch.
-  Node* fbranch = graph()->NewNode(common()->IfFalse(), branch);
-  // merge.
-  Node* merge = graph()->NewNode(common()->Merge(2), tbranch, fbranch);
-  Node* phi = graph()->NewNode(common()->Phi(2), jsgraph()->TrueConstant(),
-                               jsgraph()->FalseConstant(), merge);
-  UpdateControlSuccessors(control, merge);
-  branch->ReplaceInput(1, control);
-  node->ReplaceUses(phi);
-}


static WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
@@ -963,41 +808,6 @@
   node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
 }

-
-Reduction SimplifiedLowering::Reduce(Node* node) { return NoChange(); }
-
-
-void SimplifiedLowering::LowerChange(Node* node, Node* effect, Node* control) {
-  switch (node->opcode()) {
-    case IrOpcode::kChangeTaggedToInt32:
-      DoChangeTaggedToUI32(node, effect, control, true);
-      break;
-    case IrOpcode::kChangeTaggedToUint32:
-      DoChangeTaggedToUI32(node, effect, control, false);
-      break;
-    case IrOpcode::kChangeTaggedToFloat64:
-      DoChangeTaggedToFloat64(node, effect, control);
-      break;
-    case IrOpcode::kChangeInt32ToTagged:
-      DoChangeUI32ToTagged(node, effect, control, true);
-      break;
-    case IrOpcode::kChangeUint32ToTagged:
-      DoChangeUI32ToTagged(node, effect, control, false);
-      break;
-    case IrOpcode::kChangeFloat64ToTagged:
-      DoChangeFloat64ToTagged(node, effect, control);
-      break;
-    case IrOpcode::kChangeBoolToBit:
-      DoChangeBoolToBit(node, effect, control);
-      break;
-    case IrOpcode::kChangeBitToBool:
-      DoChangeBitToBool(node, effect, control);
-      break;
-    default:
-      UNREACHABLE();
-      break;
-  }
-}

 }  // namespace compiler
 }  // namespace internal
=======================================
--- /trunk/src/compiler/simplified-lowering.h   Wed Aug 20 00:06:26 2014 UTC
+++ /trunk/src/compiler/simplified-lowering.h   Thu Aug 28 07:03:22 2014 UTC
@@ -5,7 +5,6 @@
 #ifndef V8_COMPILER_SIMPLIFIED_LOWERING_H_
 #define V8_COMPILER_SIMPLIFIED_LOWERING_H_

-#include "src/compiler/graph-reducer.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node.h"
@@ -15,7 +14,7 @@
 namespace internal {
 namespace compiler {

-class SimplifiedLowering : public Reducer {
+class SimplifiedLowering {
  public:
   explicit SimplifiedLowering(JSGraph* jsgraph)
       : jsgraph_(jsgraph), machine_(jsgraph->zone()) {}
@@ -23,9 +22,6 @@

   void LowerAllNodes();

-  virtual Reduction Reduce(Node* node);
-  void LowerChange(Node* node, Node* effect, Node* control);
-
// TODO(titzer): These are exposed for direct testing. Use a friend class.
   void DoLoadField(Node* node);
   void DoStoreField(Node* node);
@@ -42,15 +38,6 @@
   Node* OffsetMinusTagConstant(int32_t offset);
   Node* ComputeIndex(const ElementAccess& access, Node* index);

-  void DoChangeTaggedToUI32(Node* node, Node* effect, Node* control,
-                            bool is_signed);
-  void DoChangeUI32ToTagged(Node* node, Node* effect, Node* control,
-                            bool is_signed);
-  void DoChangeTaggedToFloat64(Node* node, Node* effect, Node* control);
-  void DoChangeFloat64ToTagged(Node* node, Node* effect, Node* control);
-  void DoChangeBoolToBit(Node* node, Node* effect, Node* control);
-  void DoChangeBitToBool(Node* node, Node* effect, Node* control);
-
   friend class RepresentationSelector;

   Zone* zone() { return jsgraph_->zone(); }
=======================================
--- /trunk/src/compiler/simplified-operator-reducer.cc Mon Aug 25 07:00:33 2014 UTC +++ /trunk/src/compiler/simplified-operator-reducer.cc Thu Aug 28 07:03:22 2014 UTC
@@ -69,7 +69,7 @@
       Float64Matcher m(node->InputAt(0));
       if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
       if (m.IsChangeFloat64ToTagged()) {
-        return Change(node, machine()->TruncateFloat64ToInt32(),
+        return Change(node, machine()->ChangeFloat64ToInt32(),
                       m.node()->InputAt(0));
       }
       if (m.IsChangeInt32ToTagged()) return Replace(m.node()->InputAt(0));
@@ -79,7 +79,7 @@
       Float64Matcher m(node->InputAt(0));
       if (m.HasValue()) return ReplaceUint32(DoubleToUint32(m.Value()));
       if (m.IsChangeFloat64ToTagged()) {
-        return Change(node, machine()->TruncateFloat64ToInt32(),
+        return Change(node, machine()->ChangeFloat64ToUint32(),
                       m.node()->InputAt(0));
       }
       if (m.IsChangeUint32ToTagged()) return Replace(m.node()->InputAt(0));
=======================================
--- /trunk/src/compiler/x64/code-generator-x64.cc Thu Aug 28 00:05:02 2014 UTC +++ /trunk/src/compiler/x64/code-generator-x64.cc Thu Aug 28 07:03:22 2014 UTC
@@ -235,8 +235,8 @@
       break;
     }
     case kArchDeoptimize: {
-      int deoptimization_id = MiscField::decode(instr->opcode());
-      BuildTranslation(instr, 0, deoptimization_id);
+      int deoptimization_id = BuildTranslation(instr, 0);
+
       Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
           isolate(), deoptimization_id, Deoptimizer::LAZY);
       __ call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
=======================================
--- /trunk/src/debug-debugger.js        Wed Aug  6 00:06:29 2014 UTC
+++ /trunk/src/debug-debugger.js        Thu Aug 28 07:03:22 2014 UTC
@@ -21,7 +21,8 @@
                      AfterCompile: 5,
                      CompileError: 6,
                      PromiseEvent: 7,
-                     AsyncTaskEvent: 8 };
+                     AsyncTaskEvent: 8,
+                     BreakForCommand: 9 };

 // Types of exceptions that can be broken upon.
 Debug.ExceptionBreak = { Caught : 0,
@@ -1172,10 +1173,13 @@
   switch (this.type_) {
     case Debug.DebugEvent.BeforeCompile:
       o.event = "beforeCompile";
+      break;
     case Debug.DebugEvent.AfterCompile:
       o.event = "afterCompile";
+      break;
     case Debug.DebugEvent.CompileError:
       o.event = "compileError";
+      break;
   }
   o.body = {};
   o.body.script = this.script_;
=======================================
--- /trunk/src/factory.cc       Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/factory.cc       Thu Aug 28 07:03:22 2014 UTC
@@ -1777,20 +1777,19 @@
 }


-void Factory::ReinitializeJSReceiver(Handle<JSReceiver> object,
-                                     InstanceType type,
-                                     int size) {
-  DCHECK(type >= FIRST_JS_OBJECT_TYPE);
+void Factory::ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type,
+                                  int size) {
+  DCHECK(type == JS_OBJECT_TYPE || type == JS_FUNCTION_TYPE);

   // Allocate fresh map.
   // TODO(rossberg): Once we optimize proxies, cache these maps.
   Handle<Map> map = NewMap(type, size);

   // Check that the receiver has at least the size of the fresh object.
- int size_difference = object->map()->instance_size() - map->instance_size(); + int size_difference = proxy->map()->instance_size() - map->instance_size();
   DCHECK(size_difference >= 0);

-  map->set_prototype(object->map()->prototype());
+  map->set_prototype(proxy->map()->prototype());

   // Allocate the backing storage for the properties.
   int prop_size = map->InitialPropertiesLength();
@@ -1811,24 +1810,31 @@

   // Put in filler if the new object is smaller than the old.
   if (size_difference > 0) {
-    Address address = object->address();
+    Address address = proxy->address();
heap->CreateFillerObjectAt(address + map->instance_size(), size_difference);
     heap->AdjustLiveBytes(address, -size_difference, Heap::FROM_MUTATOR);
   }

   // Reset the map for the object.
-  object->synchronized_set_map(*map);
-  Handle<JSObject> jsobj = Handle<JSObject>::cast(object);
+  proxy->synchronized_set_map(*map);
+  Handle<JSObject> jsobj = Handle<JSObject>::cast(proxy);

   // Reinitialize the object from the constructor map.
   heap->InitializeJSObjectFromMap(*jsobj, *properties, *map);

+  // The current native context is used to set up certain bits.
+ // TODO(adamk): Using the current context seems wrong, it should be whatever + // context the JSProxy originated in. But that context isn't stored anywhere.
+  Handle<Context> context(isolate()->native_context());
+
   // Functions require some minimal initialization.
   if (type == JS_FUNCTION_TYPE) {
     map->set_function_with_prototype(true);
-    Handle<JSFunction> js_function = Handle<JSFunction>::cast(object);
-    Handle<Context> context(isolate()->native_context());
+    Handle<JSFunction> js_function = Handle<JSFunction>::cast(proxy);
     InitializeFunction(js_function, shared.ToHandleChecked(), context);
+  } else {
+    // Provide JSObjects with a constructor.
+    map->set_constructor(context->object_function());
   }
 }

@@ -1866,13 +1872,13 @@
 }


-void Factory::BecomeJSObject(Handle<JSReceiver> object) {
-  ReinitializeJSReceiver(object, JS_OBJECT_TYPE, JSObject::kHeaderSize);
+void Factory::BecomeJSObject(Handle<JSProxy> proxy) {
+  ReinitializeJSProxy(proxy, JS_OBJECT_TYPE, JSObject::kHeaderSize);
 }


-void Factory::BecomeJSFunction(Handle<JSReceiver> object) {
-  ReinitializeJSReceiver(object, JS_FUNCTION_TYPE, JSFunction::kSize);
+void Factory::BecomeJSFunction(Handle<JSProxy> proxy) {
+  ReinitializeJSProxy(proxy, JS_FUNCTION_TYPE, JSFunction::kSize);
 }


=======================================
--- /trunk/src/factory.h        Wed Aug 20 00:06:26 2014 UTC
+++ /trunk/src/factory.h        Thu Aug 28 07:03:22 2014 UTC
@@ -449,13 +449,6 @@
                                      Handle<Object> construct_trap,
                                      Handle<Object> prototype);

- // Reinitialize a JSReceiver into an (empty) JS object of respective type and - // size, but keeping the original prototype. The receiver must have at least - // the size of the new object. The object is reinitialized and behaves as an
-  // object that has been freshly allocated.
-  void ReinitializeJSReceiver(
-      Handle<JSReceiver> object, InstanceType type, int size);
-
   // Reinitialize an JSGlobalProxy based on a constructor.  The object
   // must have the same size as objects allocated using the
   // constructor.  The object is reinitialized and behaves as an
@@ -464,8 +457,8 @@
                                  Handle<JSFunction> constructor);

// Change the type of the argument into a JS object/function and reinitialize.
-  void BecomeJSObject(Handle<JSReceiver> object);
-  void BecomeJSFunction(Handle<JSReceiver> object);
+  void BecomeJSObject(Handle<JSProxy> object);
+  void BecomeJSFunction(Handle<JSProxy> object);

   Handle<JSFunction> NewFunction(Handle<String> name,
                                  Handle<Code> code,
@@ -707,6 +700,12 @@
   Handle<JSFunction> NewFunction(Handle<Map> map,
                                  Handle<String> name,
                                  MaybeHandle<Code> maybe_code);
+
+ // Reinitialize a JSProxy into an (empty) JS object of respective type and + // size, but keeping the original prototype. The receiver must have at least + // the size of the new object. The object is reinitialized and behaves as an
+  // object that has been freshly allocated.
+ void ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type, int size);
 };

 } }  // namespace v8::internal
=======================================
--- /trunk/src/heap/mark-compact-inl.h  Sun Aug 24 11:34:17 2014 UTC
+++ /trunk/src/heap/mark-compact-inl.h  Thu Aug 28 07:03:22 2014 UTC
@@ -5,8 +5,6 @@
 #ifndef V8_HEAP_MARK_COMPACT_INL_H_
 #define V8_HEAP_MARK_COMPACT_INL_H_

-#include <memory.h>
-
 #include "src/heap/mark-compact.h"
 #include "src/isolate.h"

=======================================
--- /trunk/src/ia32/code-stubs-ia32.cc  Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/ia32/code-stubs-ia32.cc  Thu Aug 28 07:03:22 2014 UTC
@@ -3626,7 +3626,7 @@

   // Tail call into the stub that handles binary operations with allocation
   // sites.
-  BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
   __ TailCallStub(&stub);
 }

=======================================
--- /trunk/src/math.js  Thu Aug 21 07:23:04 2014 UTC
+++ /trunk/src/math.js  Thu Aug 28 07:03:22 2014 UTC
@@ -173,8 +173,8 @@
   x = TO_NUMBER_INLINE(x);
   if (x > 0) return 1;
   if (x < 0) return -1;
-  if (x === 0) return x;
-  return NAN;
+  // -0, 0 or NaN.
+  return x;
 }

 // ES6 draft 09-27-13, section 20.2.2.34.
@@ -182,8 +182,8 @@
   x = TO_NUMBER_INLINE(x);
   if (x > 0) return MathFloor(x);
   if (x < 0) return MathCeil(x);
-  if (x === 0) return x;
-  return NAN;
+  // -0, 0 or NaN.
+  return x;
 }

 // ES6 draft 09-27-13, section 20.2.2.30.
=======================================
--- /trunk/src/mips/code-stubs-mips.cc  Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/src/mips/code-stubs-mips.cc  Thu Aug 28 07:03:22 2014 UTC
@@ -3878,7 +3878,7 @@

   // Tail call into the stub that handles binary operations with allocation
   // sites.
-  BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
   __ TailCallStub(&stub);
 }

=======================================
--- /trunk/src/mips64/code-stubs-mips64.cc      Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/src/mips64/code-stubs-mips64.cc      Thu Aug 28 07:03:22 2014 UTC
@@ -3914,7 +3914,7 @@

   // Tail call into the stub that handles binary operations with allocation
   // sites.
-  BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
   __ TailCallStub(&stub);
 }

=======================================
--- /trunk/src/v8natives.js     Thu Aug 21 00:04:56 2014 UTC
+++ /trunk/src/v8natives.js     Thu Aug 28 07:03:22 2014 UTC
@@ -571,10 +571,6 @@
 // property descriptor. For a description of the array layout please
 // see the runtime.cc file.
 function ConvertDescriptorArrayToDescriptor(desc_array) {
-  if (desc_array === false) {
-    throw 'Internal error: invalid desc_array';
-  }
-
   if (IS_UNDEFINED(desc_array)) {
     return UNDEFINED;
   }
@@ -649,9 +645,6 @@
   // If p is not a property on obj undefined is returned.
   var props = %GetOwnProperty(ToObject(obj), p);

-  // A false value here means that access checks failed.
-  if (props === false) return UNDEFINED;
-
   return ConvertDescriptorArrayToDescriptor(props);
 }

@@ -692,11 +685,8 @@

 // ES5 8.12.9.
 function DefineObjectProperty(obj, p, desc, should_throw) {
-  var current_or_access = %GetOwnProperty(ToObject(obj), ToName(p));
-  // A false value here means that access checks failed.
-  if (current_or_access === false) return UNDEFINED;
-
-  var current = ConvertDescriptorArrayToDescriptor(current_or_access);
+  var current_array = %GetOwnProperty(ToObject(obj), ToName(p));
+  var current = ConvertDescriptorArrayToDescriptor(current_array);
   var extensible = %IsExtensible(ToObject(obj));

   // Error handling according to spec.
=======================================
--- /trunk/src/version.cc       Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/src/version.cc       Thu Aug 28 07:03:22 2014 UTC
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     29
-#define BUILD_NUMBER      23
+#define BUILD_NUMBER      24
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
=======================================
--- /trunk/src/x64/code-stubs-x64.cc    Wed Aug 27 00:06:40 2014 UTC
+++ /trunk/src/x64/code-stubs-x64.cc    Thu Aug 28 07:03:22 2014 UTC
@@ -3593,7 +3593,7 @@

   // Tail call into the stub that handles binary operations with allocation
   // sites.
-  BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
   __ TailCallStub(&stub);
 }

=======================================
--- /trunk/src/x87/code-stubs-x87.cc    Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/src/x87/code-stubs-x87.cc    Thu Aug 28 07:03:22 2014 UTC
@@ -3301,7 +3301,7 @@

   // Tail call into the stub that handles binary operations with allocation
   // sites.
-  BinaryOpWithAllocationSiteStub stub(isolate(), state_);
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
   __ TailCallStub(&stub);
 }

=======================================
--- /trunk/src/zone-containers.h        Thu Aug 28 00:05:02 2014 UTC
+++ /trunk/src/zone-containers.h        Thu Aug 28 07:03:22 2014 UTC
@@ -17,36 +17,37 @@
 // A wrapper subclass for std::vector to make it easy to construct one
 // that uses a zone allocator.
 template <typename T>
-class ZoneVector : public std::vector<T, zone_allocator<T>> {
+class ZoneVector : public std::vector<T, zone_allocator<T> > {
  public:
   // Constructs an empty vector.
   explicit ZoneVector(Zone* zone)
-      : std::vector<T, zone_allocator<T>>(zone_allocator<T>(zone)) {}
+      : std::vector<T, zone_allocator<T> >(zone_allocator<T>(zone)) {}

   // Constructs a new vector and fills it with {size} elements, each
   // having the value {def}.
   ZoneVector(int size, T def, Zone* zone)
- : std::vector<T, zone_allocator<T>>(size, def, zone_allocator<T>(zone)) {} + : std::vector<T, zone_allocator<T> >(size, def, zone_allocator<T>(zone)) {
+  }
 };

 // A wrapper subclass std::deque to make it easy to construct one
 // that uses a zone allocator.
 template <typename T>
-class ZoneDeque : public std::deque<T, zone_allocator<T>> {
+class ZoneDeque : public std::deque<T, zone_allocator<T> > {
  public:
   explicit ZoneDeque(Zone* zone)
-      : std::deque<T, zone_allocator<T>>(zone_allocator<T>(zone)) {}
+      : std::deque<T, zone_allocator<T> >(zone_allocator<T>(zone)) {}
 };

 // A wrapper subclass for std::queue to make it easy to construct one
 // that uses a zone allocator.
 template <typename T>
-class ZoneQueue : public std::queue<T, std::deque<T, zone_allocator<T>>> {
+class ZoneQueue : public std::queue<T, std::deque<T, zone_allocator<T> > > {
  public:
   // Constructs an empty queue.
   explicit ZoneQueue(Zone* zone)
-      : std::queue<T, std::deque<T, zone_allocator<T>>>(
-            std::deque<T, zone_allocator<T>>(zone_allocator<T>(zone))) {}
+      : std::queue<T, std::deque<T, zone_allocator<T> > >(
+            std::deque<T, zone_allocator<T> >(zone_allocator<T>(zone))) {}
 };

 // Typedefs to shorten commonly used vectors.
=======================================
--- /trunk/test/base-unittests/base-unittests.gyp Thu Aug 28 00:05:02 2014 UTC +++ /trunk/test/base-unittests/base-unittests.gyp Thu Aug 28 07:03:22 2014 UTC
@@ -22,6 +22,7 @@
       'sources': [  ### gcmole(all) ###
         'bits-unittest.cc',
         'cpu-unittest.cc',
+        'flags-unittest.cc',
         'platform/condition-variable-unittest.cc',
         'platform/mutex-unittest.cc',
         'platform/platform-unittest.cc',
=======================================
--- /trunk/test/base-unittests/sys-info-unittest.cc Thu Aug 28 00:05:02 2014 UTC +++ /trunk/test/base-unittests/sys-info-unittest.cc Thu Aug 28 07:03:22 2014 UTC
@@ -5,6 +5,12 @@
 #include "src/base/sys-info.h"
 #include "testing/gtest/include/gtest/gtest.h"

+#if V8_OS_NACL
+#define DISABLE_ON_NACL(Name) DISABLED_##Name
+#else
+#define DISABLE_ON_NACL(Name) Name
+#endif
+
 namespace v8 {
 namespace base {

@@ -13,7 +19,7 @@
 }


-TEST(SysInfoTest, AmountOfPhysicalMemory) {
+TEST(SysInfoTest, DISABLE_ON_NACL(AmountOfPhysicalMemory)) {
   EXPECT_LT(0, SysInfo::AmountOfPhysicalMemory());
 }

=======================================
--- /trunk/test/cctest/compiler/test-changes-lowering.cc Wed Aug 20 00:06:26 2014 UTC +++ /trunk/test/cctest/compiler/test-changes-lowering.cc Thu Aug 28 07:03:22 2014 UTC
@@ -4,15 +4,17 @@

 #include <limits>

+#include "src/compiler/change-lowering.h"
 #include "src/compiler/control-builders.h"
 #include "src/compiler/generic-node-inl.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/pipeline.h"
-#include "src/compiler/simplified-lowering.h"
 #include "src/compiler/simplified-node-factory.h"
 #include "src/compiler/typer.h"
 #include "src/compiler/verifier.h"
 #include "src/execution.h"
+#include "src/globals.h"
 #include "src/parser.h"
 #include "src/rewriter.h"
 #include "src/scopes.h"
@@ -31,12 +33,10 @@
       : GraphBuilderTester<ReturnType>(p0),
         typer(this->zone()),
         jsgraph(this->graph(), this->common(), &typer),
-        lowering(&jsgraph),
         function(Handle<JSFunction>::null()) {}

   Typer typer;
   JSGraph jsgraph;
-  SimplifiedLowering lowering;
   Handle<JSFunction> function;

   Node* start() { return this->graph()->start(); }
@@ -109,8 +109,7 @@
                                        this->start(), this->start());
     Node* end = this->graph()->NewNode(this->common()->End(), ret);
     this->graph()->SetEnd(end);
-    this->lowering.LowerChange(change, this->start(), this->start());
-    Verifier::Run(this->graph());
+    LowerChange(change);
   }

void BuildStoreAndLower(Operator* op, Operator* store_op, void* location) {
@@ -125,8 +124,7 @@
this->common()->Return(), this->Int32Constant(0), store, this->start());
     Node* end = this->graph()->NewNode(this->common()->End(), ret);
     this->graph()->SetEnd(end);
-    this->lowering.LowerChange(change, this->start(), this->start());
-    Verifier::Run(this->graph());
+    LowerChange(change);
   }

   void BuildLoadAndLower(Operator* op, Operator* load_op, void* location) {
@@ -140,7 +138,17 @@
                                        this->start(), this->start());
     Node* end = this->graph()->NewNode(this->common()->End(), ret);
     this->graph()->SetEnd(end);
-    this->lowering.LowerChange(change, this->start(), this->start());
+    LowerChange(change);
+  }
+
+  void LowerChange(Node* change) {
+    // Run the graph reducer with changes lowering on a single node.
+    CompilationInfo info(this->isolate(), this->zone());
+    Linkage linkage(&info);
+    ChangeLowering lowering(&jsgraph, &linkage, this->machine());
+    GraphReducer reducer(this->graph());
+    reducer.AddReducer(&lowering);
+    reducer.ReduceNode(change);
     Verifier::Run(this->graph());
   }

@@ -295,21 +303,13 @@
 }


-bool TODO_INT32_TO_TAGGED_WILL_WORK(int32_t v) {
- // TODO(titzer): enable all UI32 -> Tagged checking when inline allocation
-  // works.
-  return Smi::IsValid(v);
-}
+#ifndef V8_TARGET_ARCH_ARM64
+#if V8_TURBOFAN_BACKEND
+// TODO(titzer): disabled on ARM64 because calling into the runtime to
+// allocate uses the wrong stack pointer.
+// TODO(titzer): disabled on ARM

-
-bool TODO_UINT32_TO_TAGGED_WILL_WORK(uint32_t v) {
- // TODO(titzer): enable all UI32 -> Tagged checking when inline allocation
-  // works.
-  return v <= static_cast<uint32_t>(Smi::kMaxValue);
-}
-
-
-TEST(RunChangeInt32ToTagged) {
+TEST(RunChangeInt32ToTaggedSmi) {
   ChangesLoweringTester<Object*> t;
   int32_t input;
   t.BuildLoadAndLower(t.simplified()->ChangeInt32ToTagged(),
@@ -318,19 +318,47 @@
   if (Pipeline::SupportedTarget()) {
     FOR_INT32_INPUTS(i) {
       input = *i;
-      Object* result = t.CallWithPotentialGC<Object>();
-      if (TODO_INT32_TO_TAGGED_WILL_WORK(input)) {
-        t.CheckNumber(static_cast<double>(input), result);
-      }
+      if (!Smi::IsValid(input)) continue;
+      Object* result = t.Call();
+      t.CheckNumber(static_cast<double>(input), result);
     }
   }
+}
+
+
+TEST(RunChangeUint32ToTaggedSmi) {
+  ChangesLoweringTester<Object*> t;
+  uint32_t input;
+  t.BuildLoadAndLower(t.simplified()->ChangeUint32ToTagged(),
+                      t.machine()->Load(kMachUint32), &input);

   if (Pipeline::SupportedTarget()) {
-    FOR_INT32_INPUTS(i) {
+    FOR_UINT32_INPUTS(i) {
       input = *i;
-      SimulateFullSpace(CcTest::heap()->new_space());
-      Object* result = t.CallWithPotentialGC<Object>();
-      if (TODO_INT32_TO_TAGGED_WILL_WORK(input)) {
+      if (input > static_cast<uint32_t>(Smi::kMaxValue)) continue;
+      Object* result = t.Call();
+      double expected = static_cast<double>(input);
+      t.CheckNumber(expected, result);
+    }
+  }
+}
+
+
+TEST(RunChangeInt32ToTagged) {
+  ChangesLoweringTester<Object*> t;
+  int32_t input;
+  t.BuildLoadAndLower(t.simplified()->ChangeInt32ToTagged(),
+                      t.machine()->Load(kMachInt32), &input);
+
+  if (Pipeline::SupportedTarget()) {
+    for (int m = 0; m < 3; m++) {  // Try 3 GC modes.
+      FOR_INT32_INPUTS(i) {
+        if (m == 0) CcTest::heap()->EnableInlineAllocation();
+        if (m == 1) CcTest::heap()->DisableInlineAllocation();
+        if (m == 2) SimulateFullSpace(CcTest::heap()->new_space());
+
+        input = *i;
+        Object* result = t.CallWithPotentialGC<Object>();
         t.CheckNumber(static_cast<double>(input), result);
       }
     }
@@ -345,32 +373,21 @@
                       t.machine()->Load(kMachUint32), &input);

   if (Pipeline::SupportedTarget()) {
-    FOR_UINT32_INPUTS(i) {
-      input = *i;
-      Object* result = t.CallWithPotentialGC<Object>();
-      double expected = static_cast<double>(input);
-      if (TODO_UINT32_TO_TAGGED_WILL_WORK(input)) {
-        t.CheckNumber(expected, result);
-      }
-    }
-  }
+    for (int m = 0; m < 3; m++) {  // Try 3 GC modes.
+      FOR_UINT32_INPUTS(i) {
+        if (m == 0) CcTest::heap()->EnableInlineAllocation();
+        if (m == 1) CcTest::heap()->DisableInlineAllocation();
+        if (m == 2) SimulateFullSpace(CcTest::heap()->new_space());

-  if (Pipeline::SupportedTarget()) {
-    FOR_UINT32_INPUTS(i) {
-      input = *i;
-      SimulateFullSpace(CcTest::heap()->new_space());
-      Object* result = t.CallWithPotentialGC<Object>();
-      double expected = static_cast<double>(static_cast<uint32_t>(input));
-      if (TODO_UINT32_TO_TAGGED_WILL_WORK(input)) {
+        input = *i;
+        Object* result = t.CallWithPotentialGC<Object>();
+        double expected = static_cast<double>(input);
         t.CheckNumber(expected, result);
       }
     }
   }
 }

-
-// TODO(titzer): lowering of Float64->Tagged needs inline allocation.
-#define TODO_FLOAT64_TO_TAGGED false

 TEST(RunChangeFloat64ToTagged) {
   ChangesLoweringTester<Object*> t;
@@ -378,21 +395,20 @@
   t.BuildLoadAndLower(t.simplified()->ChangeFloat64ToTagged(),
                       t.machine()->Load(kMachFloat64), &input);

-  // TODO(titzer): need inline allocation to change float to tagged.
-  if (TODO_FLOAT64_TO_TAGGED && Pipeline::SupportedTarget()) {
-    FOR_FLOAT64_INPUTS(i) {
-      input = *i;
-      Object* result = t.CallWithPotentialGC<Object>();
-      t.CheckNumber(input, result);
-    }
-  }
+  if (Pipeline::SupportedTarget()) {
+    for (int m = 0; m < 3; m++) {  // Try 3 GC modes.
+      FOR_FLOAT64_INPUTS(i) {
+        if (m == 0) CcTest::heap()->EnableInlineAllocation();
+        if (m == 1) CcTest::heap()->DisableInlineAllocation();
+        if (m == 2) SimulateFullSpace(CcTest::heap()->new_space());

-  if (TODO_FLOAT64_TO_TAGGED && Pipeline::SupportedTarget()) {
-    FOR_FLOAT64_INPUTS(i) {
-      input = *i;
-      SimulateFullSpace(CcTest::heap()->new_space());
-      Object* result = t.CallWithPotentialGC<Object>();
-      t.CheckNumber(input, result);
+        input = *i;
+        Object* result = t.CallWithPotentialGC<Object>();
+        t.CheckNumber(input, result);
+      }
     }
   }
 }
+
+#endif  // V8_TURBOFAN_BACKEND
+#endif  // !V8_TARGET_ARCH_ARM64
=======================================
--- /trunk/test/cctest/compiler/test-codegen-deopt.cc Mon Aug 25 19:57:56 2014 UTC +++ /trunk/test/cctest/compiler/test-codegen-deopt.cc Thu Aug 28 07:03:22 2014 UTC
@@ -210,7 +210,6 @@

   // Check that we deoptimize to the right AST id.
   CHECK_EQ(1, data->DeoptCount());
-  CHECK_EQ(1, data->DeoptCount());
   CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt());
 }

=======================================
--- /trunk/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc Wed Aug 27 00:06:40 2014 UTC +++ /trunk/test/compiler-unittests/arm/instruction-selector-arm-unittest.cc Thu Aug 28 07:03:22 2014 UTC
@@ -1895,7 +1895,6 @@
     }
   }
 }
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
=======================================
--- /trunk/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc Wed Aug 27 00:06:40 2014 UTC +++ /trunk/test/compiler-unittests/arm64/instruction-selector-arm64-unittest.cc Thu Aug 28 07:03:22 2014 UTC
@@ -12,23 +12,26 @@

 namespace {

-typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
-
-struct DPI {
-  Constructor constructor;
+template <typename T>
+struct MachInst {
+  T constructor;
   const char* constructor_name;
   ArchOpcode arch_opcode;
   MachineType machine_type;
 };

+typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
+typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;

-std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
-  return os << dpi.constructor_name;
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
+  return os << mi.constructor_name;
 }


-// ARM64 Logical instructions.
-static const DPI kLogicalInstructions[] = {
+// ARM64 logical instructions.
+static const MachInst2 kLogicalInstructions[] = {
{&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32},
     {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64},
     {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32},
@@ -60,8 +63,8 @@
     0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff};


-// ARM64 Arithmetic instructions.
-static const DPI kAddSubInstructions[] = {
+// ARM64 arithmetic instructions.
+static const MachInst2 kAddSubInstructions[] = {
     {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32},
     {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64},
     {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32},
@@ -86,7 +89,7 @@


 // ARM64 shift instructions.
-static const DPI kShiftInstructions[] = {
+static const MachInst2 kShiftInstructions[] = {
{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32},
     {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64},
{&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32},
@@ -98,7 +101,7 @@


 // ARM64 Mul/Div instructions.
-static const DPI kMulDivInstructions[] = {
+static const MachInst2 kMulDivInstructions[] = {
     {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32},
     {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64},
     {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32},
@@ -106,17 +109,92 @@
{&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32, kMachInt32}, {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv, kMachInt64}};

+
+// ARM64 FP arithmetic instructions.
+static const MachInst2 kFPArithInstructions[] = {
+    {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add,
+     kMachFloat64},
+    {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub,
+     kMachFloat64},
+    {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul,
+     kMachFloat64},
+    {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div,
+     kMachFloat64}};
+
+
+struct FPCmp {
+  MachInst2 mi;
+  FlagsCondition cond;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) {
+  return os << cmp.mi;
+}
+
+
+// ARM64 FP comparison instructions.
+static const FPCmp kFPCmpInstructions[] = {
+    {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp,
+      kMachFloat64},
+     kUnorderedEqual},
+    {{&RawMachineAssembler::Float64LessThan, "Float64LessThan",
+      kArm64Float64Cmp, kMachFloat64},
+     kUnorderedLessThan},
+ {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
+      kArm64Float64Cmp, kMachFloat64},
+     kUnorderedLessThanOrEqual}};
+
+
+struct Conversion {
+  // The machine_type field in MachInst1 represents the destination type.
+  MachInst1 mi;
+  MachineType src_machine_type;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const Conversion& conv) {
+  return os << conv.mi;
+}
+
+
+// ARM64 type conversion instructions.
+static const Conversion kConversionInstructions[] = {
+    {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64",
+      kArm64Sxtw, kMachInt64},
+     kMachInt32},
+    {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64",
+      kArm64Mov32, kMachUint64},
+     kMachUint32},
+    {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32",
+      kArm64Mov32, kMachInt32},
+     kMachInt64},
+    {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
+      kArm64Int32ToFloat64, kMachFloat64},
+     kMachInt32},
+    {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
+      kArm64Uint32ToFloat64, kMachFloat64},
+     kMachUint32},
+    {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
+      kArm64Float64ToInt32, kMachInt32},
+     kMachFloat64},
+    {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
+      kArm64Float64ToUint32, kMachUint32},
+     kMachFloat64}};
+
 }  // namespace


// -----------------------------------------------------------------------------
 // Logical instructions.

+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorLogicalTest;

-typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorLogicalTest;

 TEST_P(InstructionSelectorLogicalTest, Parameter) {
-  const DPI dpi = GetParam();
+  const MachInst2 dpi = GetParam();
   const MachineType type = dpi.machine_type;
   StreamBuilder m(this, type, type, type);
   m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
@@ -129,7 +207,7 @@


 TEST_P(InstructionSelectorLogicalTest, Immediate) {
-  const DPI dpi = GetParam();
+  const MachInst2 dpi = GetParam();
   const MachineType type = dpi.machine_type;
   // TODO(all): Add support for testing 64-bit immediates.
   if (type == kMachInt32) {
@@ -169,10 +247,12 @@
// -----------------------------------------------------------------------------
 // Add and Sub instructions.

-typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorAddSubTest;
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorAddSubTest;
+

 TEST_P(InstructionSelectorAddSubTest, Parameter) {
-  const DPI dpi = GetParam();
+  const MachInst2 dpi = GetParam();
   const MachineType type = dpi.machine_type;
   StreamBuilder m(this, type, type, type);
   m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
@@ -185,7 +265,7 @@


 TEST_P(InstructionSelectorAddSubTest, Immediate) {
-  const DPI dpi = GetParam();
+  const MachInst2 dpi = GetParam();
   const MachineType type = dpi.machine_type;
   TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
     StreamBuilder m(this, type, type);
@@ -208,11 +288,13 @@
// -----------------------------------------------------------------------------
 // Shift instructions.

+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorShiftTest;

-typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorShiftTest;

 TEST_P(InstructionSelectorShiftTest, Parameter) {
-  const DPI dpi = GetParam();
+  const MachInst2 dpi = GetParam();
   const MachineType type = dpi.machine_type;
   StreamBuilder m(this, type, type, type);
   m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
@@ -225,7 +307,7 @@


 TEST_P(InstructionSelectorShiftTest, Immediate) {
-  const DPI dpi = GetParam();
+  const MachInst2 dpi = GetParam();
   const MachineType type = dpi.machine_type;
   TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
     StreamBuilder m(this, type, type);
@@ -249,11 +331,12 @@
 // Mul and Div instructions.


-typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorMulDivTest;
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorMulDivTest;


 TEST_P(InstructionSelectorMulDivTest, Parameter) {
-  const DPI dpi = GetParam();
+  const MachInst2 dpi = GetParam();
   const MachineType type = dpi.machine_type;
   StreamBuilder m(this, type, type, type);
   m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
@@ -269,34 +352,71 @@


// -----------------------------------------------------------------------------
-// Conversions.
+// Floating point instructions.
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorFPArithTest;


-TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithParameter) {
-  StreamBuilder m(this, kMachInt64, kMachInt32);
-  m.Return(m.ChangeInt32ToInt64(m.Parameter(0)));
+TEST_P(InstructionSelectorFPArithTest, Parameter) {
+  const MachInst2 fpa = GetParam();
+ StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type);
+  m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1)));
   Stream s = m.Build();
   ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArm64Sxtw, s[0]->arch_opcode());
+  EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
 }


-TEST_F(InstructionSelectorTest, ChangeUint32ToUint64WithParameter) {
-  StreamBuilder m(this, kMachUint64, kMachUint32);
-  m.Return(m.ChangeUint32ToUint64(m.Parameter(0)));
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
+                        ::testing::ValuesIn(kFPArithInstructions));
+
+
+typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
+
+
+TEST_P(InstructionSelectorFPCmpTest, Parameter) {
+  const FPCmp cmp = GetParam();
+ StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type);
+  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
   Stream s = m.Build();
   ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArm64Mov32, s[0]->arch_opcode());
+  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(cmp.cond, s[0]->flags_condition());
 }


-TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) {
-  StreamBuilder m(this, kMachInt32, kMachInt64);
-  m.Return(m.TruncateInt64ToInt32(m.Parameter(0)));
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest,
+                        ::testing::ValuesIn(kFPCmpInstructions));
+
+
+// -----------------------------------------------------------------------------
+// Conversions.
+
+typedef InstructionSelectorTestWithParam<Conversion>
+    InstructionSelectorConversionTest;
+
+
+TEST_P(InstructionSelectorConversionTest, Parameter) {
+  const Conversion conv = GetParam();
+  StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
+  m.Return((m.*conv.mi.constructor)(m.Parameter(0)));
   Stream s = m.Build();
   ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArm64Mov32, s[0]->arch_opcode());
+  EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
 }
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorConversionTest,
+                        ::testing::ValuesIn(kConversionInstructions));


// -----------------------------------------------------------------------------
=======================================
--- /trunk/test/compiler-unittests/change-lowering-unittest.cc Sun Aug 24 11:34:17 2014 UTC +++ /trunk/test/compiler-unittests/change-lowering-unittest.cc Thu Aug 28 07:03:22 2014 UTC
@@ -269,7 +269,7 @@
   Capture<Node*> branch, if_true;
   EXPECT_THAT(
       phi,
-      IsPhi(IsTruncateFloat64ToInt32(IsLoad(
+      IsPhi(IsChangeFloat64ToInt32(IsLoad(
kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
                 IsControlEffect(CaptureEq(&if_true)))),
             IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
@@ -294,7 +294,7 @@
   Capture<Node*> branch, if_true;
   EXPECT_THAT(
       phi,
-      IsPhi(IsTruncateFloat64ToInt32(IsLoad(
+      IsPhi(IsChangeFloat64ToUint32(IsLoad(
kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
                 IsControlEffect(CaptureEq(&if_true)))),
             IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
@@ -403,7 +403,7 @@
   Capture<Node*> branch, if_true;
   EXPECT_THAT(
       phi,
-      IsPhi(IsTruncateFloat64ToInt32(IsLoad(
+      IsPhi(IsChangeFloat64ToInt32(IsLoad(
kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
                 IsControlEffect(CaptureEq(&if_true)))),
             IsTruncateInt64ToInt32(
@@ -429,7 +429,7 @@
   Capture<Node*> branch, if_true;
   EXPECT_THAT(
       phi,
-      IsPhi(IsTruncateFloat64ToInt32(IsLoad(
+      IsPhi(IsChangeFloat64ToUint32(IsLoad(
kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
                 IsControlEffect(CaptureEq(&if_true)))),
             IsTruncateInt64ToInt32(
=======================================
--- /trunk/test/compiler-unittests/graph-unittest.cc Sun Aug 24 11:34:17 2014 UTC +++ /trunk/test/compiler-unittests/graph-unittest.cc Thu Aug 28 07:03:22 2014 UTC
@@ -744,6 +744,7 @@
return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
   }
 IS_UNOP_MATCHER(ChangeFloat64ToInt32)
+IS_UNOP_MATCHER(ChangeFloat64ToUint32)
 IS_UNOP_MATCHER(ChangeInt32ToFloat64)
 IS_UNOP_MATCHER(ChangeInt32ToInt64)
 IS_UNOP_MATCHER(ChangeUint32ToFloat64)
=======================================
--- /trunk/test/compiler-unittests/graph-unittest.h Sun Aug 24 11:34:17 2014 UTC +++ /trunk/test/compiler-unittests/graph-unittest.h Thu Aug 28 07:03:22 2014 UTC
@@ -113,6 +113,7 @@
 Matcher<Node*> IsUint32LessThanOrEqual(const Matcher<Node*>& lhs_matcher,
                                        const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeFloat64ToUint32(const Matcher<Node*>& input_matcher);
 Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
 Matcher<Node*> IsChangeInt32ToInt64(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsChangeUint32ToFloat64(const Matcher<Node*>& input_matcher);
=======================================
--- /trunk/test/compiler-unittests/instruction-selector-unittest.cc Wed Aug 27 00:06:40 2014 UTC +++ /trunk/test/compiler-unittests/instruction-selector-unittest.cc Thu Aug 28 07:03:22 2014 UTC
@@ -57,6 +57,9 @@
           continue;
       }
     }
+ if (mode == kAllExceptNopInstructions && instr->arch_opcode() == kArchNop) {
+      continue;
+    }
     for (size_t i = 0; i < instr->OutputCount(); ++i) {
       InstructionOperand* output = instr->OutputAt(i);
       EXPECT_NE(InstructionOperand::IMMEDIATE, output->kind());
@@ -94,6 +97,9 @@
       s.references_.insert(virtual_register);
     }
   }
+  for (int i = 0; i < sequence.GetDeoptimizationEntryCount(); i++) {
+ s.deoptimization_entries_.push_back(sequence.GetDeoptimizationEntry(i));
+  }
   return s;
 }

@@ -306,6 +312,159 @@
     EXPECT_EQ(i1->OutputCount(), i2->OutputCount());
   }
 }
+
+
+// -----------------------------------------------------------------------------
+// Calls with deoptimization.
+TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
+  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged);
+
+  BailoutId bailout_id(42);
+
+  Node* function_node = m.Parameter(0);
+  Node* receiver = m.Parameter(1);
+  StreamBuilder::Label deopt, cont;
+
+  // TODO(jarin) Add frame state.
+  Node* call = m.CallJS0(function_node, receiver, &cont, &deopt);
+
+  m.Bind(&cont);
+  m.NewNode(m.common()->Continuation(), call);
+  m.Return(call);
+
+  m.Bind(&deopt);
+  m.NewNode(m.common()->LazyDeoptimization(), call);
+
+ Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(1));
+  Node* locals = m.NewNode(m.common()->StateValues(0));
+  Node* stack = m.NewNode(m.common()->StateValues(0));
+
+  Node* state_node =
+ m.NewNode(m.common()->FrameState(bailout_id), parameters, locals, stack);
+  m.Deoptimize(state_node);
+
+  Stream s = m.Build(kAllExceptNopInstructions);
+
+  // Skip until kArchCallJSFunction.
+  size_t index = 0;
+ for (; index < s.size() && s[index]->arch_opcode() != kArchCallJSFunction;
+       index++) {
+  }
+  // Now we should have three instructions: call, return and deoptimize.
+  ASSERT_EQ(index + 3, s.size());
+
+  EXPECT_EQ(kArchCallJSFunction, s[index++]->arch_opcode());
+  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
+  EXPECT_EQ(kArchDeoptimize, s[index++]->arch_opcode());
+  EXPECT_EQ(index, s.size());
+}
+
+
+TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
+  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
+                  kMachAnyTagged);
+
+  BailoutId bailout_id_before(42);
+  BailoutId bailout_id_after(54);
+
+  // Some arguments for the call node.
+  Node* function_node = m.Parameter(0);
+  Node* receiver = m.Parameter(1);
+  Node* context = m.Int32Constant(1);  // Context is ignored.
+
+  // Build frame state for the state before the call.
+ Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43)); + Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44));
+  Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45));
+  Node* frame_state_before = m.NewNode(
+ m.common()->FrameState(bailout_id_before), parameters, locals, stack);
+
+  StreamBuilder::Label deopt, cont;
+  // Build the call.
+  Node* call =
+ m.CallFunctionStub0(function_node, receiver, context, frame_state_before,
+                          &cont, &deopt, CALL_AS_METHOD);
+
+  // Create the continuation branch.
+  m.Bind(&cont);
+  m.NewNode(m.common()->Continuation(), call);
+  m.Return(call);
+
+  // Create the lazy deoptimization block (with a different frame state).
+  m.Bind(&deopt);
+  m.NewNode(m.common()->LazyDeoptimization(), call);
+
+  Node* stack_after =
+      m.NewNode(m.common()->StateValues(2), m.Int32Constant(55), call);
+
+ Node* frame_state_after = m.NewNode(m.common()->FrameState(bailout_id_after),
+                                      parameters, locals, stack_after);
+  m.Deoptimize(frame_state_after);
+
+  Stream s = m.Build(kAllExceptNopInstructions);
+
+  // Skip until kArchCallJSFunction.
+  size_t index = 0;
+ for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject;
+       index++) {
+  }
+  // Now we should have three instructions: call, return and deoptimize.
+  ASSERT_EQ(index + 3, s.size());
+
+  // Check the call instruction
+  const Instruction* call_instr = s[index++];
+  EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode());
+  size_t num_operands =
+      1 +  // Code object.
+      1 +
+ 3 + // Frame state deopt id + one input for each value in frame state.
+      1 +  // Function.
+      1 +  // Context.
+      2;   // Continuation and deoptimization block labels.
+  ASSERT_EQ(num_operands, call_instr->InputCount());
+
+  // Code object.
+  EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate());
+
+  // Deoptimization id.
+  int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1));
+ FrameStateDescriptor* desc_before = s.GetDeoptimizationEntry(deopt_id_before);
+  EXPECT_EQ(bailout_id_before, desc_before->bailout_id());
+  EXPECT_EQ(1, desc_before->parameters_count());
+  EXPECT_EQ(1, desc_before->locals_count());
+  EXPECT_EQ(1, desc_before->stack_count());
+  EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2)));
+  EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(3)));
+  EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(4)));
+
+  // Function.
+  EXPECT_EQ(function_node->id(), s.ToVreg(call_instr->InputAt(5)));
+  // Context.
+  EXPECT_EQ(context->id(), s.ToVreg(call_instr->InputAt(6)));
+  // Continuation.
+  EXPECT_EQ(cont.block()->id(), s.ToInt32(call_instr->InputAt(7)));
+  // Deoptimization.
+  EXPECT_EQ(deopt.block()->id(), s.ToInt32(call_instr->InputAt(8)));
+
+  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
+
+  // Check the deoptimize instruction.
+  const Instruction* deopt_instr = s[index++];
+  EXPECT_EQ(kArchDeoptimize, deopt_instr->arch_opcode());
+  ASSERT_EQ(5U, deopt_instr->InputCount());
+  int32_t deopt_id_after = s.ToInt32(deopt_instr->InputAt(0));
+ FrameStateDescriptor* desc_after = s.GetDeoptimizationEntry(deopt_id_after);
+  EXPECT_EQ(bailout_id_after, desc_after->bailout_id());
+  EXPECT_EQ(1, desc_after->parameters_count());
+  EXPECT_EQ(1, desc_after->locals_count());
+  EXPECT_EQ(2, desc_after->stack_count());
+  // Parameter value from the frame state.
+  EXPECT_EQ(43, s.ToInt32(deopt_instr->InputAt(1)));
+  EXPECT_EQ(44, s.ToInt32(deopt_instr->InputAt(2)));
+  EXPECT_EQ(55, s.ToInt32(deopt_instr->InputAt(3)));
+  EXPECT_EQ(call->id(), s.ToVreg(deopt_instr->InputAt(4)));
+  EXPECT_EQ(index, s.size());
+}

 }  // namespace compiler
 }  // namespace internal
=======================================
***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