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.