summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/cctest/compiler')
-rw-r--r--deps/v8/test/cctest/compiler/c-signature.h147
-rw-r--r--deps/v8/test/cctest/compiler/call-tester.h366
-rw-r--r--deps/v8/test/cctest/compiler/codegen-tester.h79
-rw-r--r--deps/v8/test/cctest/compiler/function-tester.h21
-rw-r--r--deps/v8/test/cctest/compiler/graph-builder-tester.h21
-rw-r--r--deps/v8/test/cctest/compiler/simplified-graph-builder.cc4
-rw-r--r--deps/v8/test/cctest/compiler/simplified-graph-builder.h3
-rw-r--r--deps/v8/test/cctest/compiler/test-changes-lowering.cc10
-rw-r--r--deps/v8/test/cctest/compiler/test-codegen-deopt.cc301
-rw-r--r--deps/v8/test/cctest/compiler/test-control-reducer.cc1641
-rw-r--r--deps/v8/test/cctest/compiler/test-js-constant-cache.cc14
-rw-r--r--deps/v8/test/cctest/compiler/test-js-context-specialization.cc41
-rw-r--r--deps/v8/test/cctest/compiler/test-js-typed-lowering.cc89
-rw-r--r--deps/v8/test/cctest/compiler/test-jump-threading.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-linkage.cc5
-rw-r--r--deps/v8/test/cctest/compiler/test-loop-analysis.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-osr.cc62
-rw-r--r--deps/v8/test/cctest/compiler/test-pipeline.cc23
-rw-r--r--deps/v8/test/cctest/compiler/test-representation-change.cc8
-rw-r--r--deps/v8/test/cctest/compiler/test-run-deopt.cc88
-rw-r--r--deps/v8/test/cctest/compiler/test-run-inlining.cc129
-rw-r--r--deps/v8/test/cctest/compiler/test-run-intrinsics.cc51
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jscalls.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jsexceptions.cc43
-rw-r--r--deps/v8/test/cctest/compiler/test-run-jsops.cc2
-rw-r--r--deps/v8/test/cctest/compiler/test-run-machops.cc223
-rw-r--r--deps/v8/test/cctest/compiler/test-run-stubs.cc137
-rw-r--r--deps/v8/test/cctest/compiler/test-simplified-lowering.cc46
30 files changed, 838 insertions, 2726 deletions
diff --git a/deps/v8/test/cctest/compiler/c-signature.h b/deps/v8/test/cctest/compiler/c-signature.h
index 5d161dbe7a..83b3328a3b 100644
--- a/deps/v8/test/cctest/compiler/c-signature.h
+++ b/deps/v8/test/cctest/compiler/c-signature.h
@@ -11,76 +11,103 @@ namespace v8 {
namespace internal {
namespace compiler {
+#define FOREACH_CTYPE_MACHINE_TYPE_MAPPING(V) \
+ V(void, kMachNone) \
+ V(bool, kMachBool) \
+ V(int8_t, kMachInt8) \
+ V(uint8_t, kMachUint8) \
+ V(int16_t, kMachInt16) \
+ V(uint16_t, kMachUint16) \
+ V(int32_t, kMachInt32) \
+ V(uint32_t, kMachUint32) \
+ V(int64_t, kMachInt64) \
+ V(uint64_t, kMachUint64) \
+ V(float, kMachFloat32) \
+ V(double, kMachFloat64) \
+ V(void*, kMachPtr) \
+ V(int*, kMachPtr)
+
template <typename T>
inline MachineType MachineTypeForC() {
- CHECK(false); // Instantiated with invalid type.
- return kMachNone;
-}
-
-template <>
-inline MachineType MachineTypeForC<void>() {
- return kMachNone;
-}
-
-template <>
-inline MachineType MachineTypeForC<int8_t>() {
- return kMachInt8;
-}
-
-template <>
-inline MachineType MachineTypeForC<uint8_t>() {
- return kMachUint8;
-}
-
-template <>
-inline MachineType MachineTypeForC<int16_t>() {
- return kMachInt16;
-}
-
-template <>
-inline MachineType MachineTypeForC<uint16_t>() {
- return kMachUint16;
-}
-
-template <>
-inline MachineType MachineTypeForC<int32_t>() {
- return kMachInt32;
+ while (false) {
+ // All other types T must be assignable to Object*
+ *(static_cast<Object* volatile*>(0)) = static_cast<T>(0);
+ }
+ return kMachAnyTagged;
}
-template <>
-inline MachineType MachineTypeForC<uint32_t>() {
- return kMachUint32;
-}
+#define DECLARE_TEMPLATE_SPECIALIZATION(ctype, mtype) \
+ template <> \
+ inline MachineType MachineTypeForC<ctype>() { \
+ return mtype; \
+ }
+FOREACH_CTYPE_MACHINE_TYPE_MAPPING(DECLARE_TEMPLATE_SPECIALIZATION)
+#undef DECLARE_TEMPLATE_SPECIALIZATION
-template <>
-inline MachineType MachineTypeForC<int64_t>() {
- return kMachInt64;
-}
+// Helper for building machine signatures from C types.
+class CSignature : public MachineSignature {
+ protected:
+ CSignature(size_t return_count, size_t parameter_count, MachineType* reps)
+ : MachineSignature(return_count, parameter_count, reps) {}
-template <>
-inline MachineType MachineTypeForC<uint64_t>() {
- return kMachUint64;
-}
+ public:
+ template <typename P1 = void, typename P2 = void, typename P3 = void,
+ typename P4 = void, typename P5 = void>
+ void VerifyParams() {
+ // Verifies the C signature against the machine types. Maximum {5} params.
+ CHECK_LT(parameter_count(), 6u);
+ const int kMax = 5;
+ MachineType params[] = {MachineTypeForC<P1>(), MachineTypeForC<P2>(),
+ MachineTypeForC<P3>(), MachineTypeForC<P4>(),
+ MachineTypeForC<P5>()};
+ for (int p = kMax - 1; p >= 0; p--) {
+ if (p < static_cast<int>(parameter_count())) {
+ CHECK_EQ(GetParam(p), params[p]);
+ } else {
+ CHECK_EQ(kMachNone, params[p]);
+ }
+ }
+ }
-template <>
-inline MachineType MachineTypeForC<double>() {
- return kMachFloat64;
-}
+ static CSignature* New(Zone* zone, MachineType ret,
+ MachineType p1 = kMachNone, MachineType p2 = kMachNone,
+ MachineType p3 = kMachNone, MachineType p4 = kMachNone,
+ MachineType p5 = kMachNone) {
+ MachineType* buffer = zone->NewArray<MachineType>(6);
+ int pos = 0;
+ size_t return_count = 0;
+ if (ret != kMachNone) {
+ buffer[pos++] = ret;
+ return_count++;
+ }
+ buffer[pos++] = p1;
+ buffer[pos++] = p2;
+ buffer[pos++] = p3;
+ buffer[pos++] = p4;
+ buffer[pos++] = p5;
+ size_t param_count = 5;
+ if (p5 == kMachNone) param_count--;
+ if (p4 == kMachNone) param_count--;
+ if (p3 == kMachNone) param_count--;
+ if (p2 == kMachNone) param_count--;
+ if (p1 == kMachNone) param_count--;
+ for (size_t i = 0; i < param_count; i++) {
+ // Check that there are no kMachNone's in the middle of parameters.
+ CHECK_NE(kMachNone, buffer[return_count + i]);
+ }
+ return new (zone) CSignature(return_count, param_count, buffer);
+ }
+};
-template <>
-inline MachineType MachineTypeForC<Object*>() {
- return kMachAnyTagged;
-}
template <typename Ret, uint16_t kParamCount>
-class CSignatureOf : public MachineSignature {
+class CSignatureOf : public CSignature {
protected:
MachineType storage_[1 + kParamCount];
CSignatureOf()
- : MachineSignature(MachineTypeForC<Ret>() != kMachNone ? 1 : 0,
- kParamCount,
- reinterpret_cast<MachineType*>(&storage_)) {
+ : CSignature(MachineTypeForC<Ret>() != kMachNone ? 1 : 0, kParamCount,
+ reinterpret_cast<MachineType*>(&storage_)) {
if (return_count_ == 1) storage_[0] = MachineTypeForC<Ret>();
}
void Set(int index, MachineType type) {
@@ -123,9 +150,11 @@ class CSignature3 : public CSignatureOf<Ret, 3> {
}
};
-static const CSignature2<int32_t, int32_t, int32_t> int32_int32_to_int32;
-static const CSignature2<uint32_t, uint32_t, uint32_t> uint32_uint32_to_uint32;
-static const CSignature2<double, double, double> float64_float64_to_float64;
+typedef CSignature2<int32_t, int32_t, int32_t> CSignature_i_ii;
+typedef CSignature2<uint32_t, uint32_t, uint32_t> CSignature_u_uu;
+typedef CSignature2<float, float, float> CSignature_f_ff;
+typedef CSignature2<double, double, double> CSignature_d_dd;
+typedef CSignature2<Object*, Object*, Object*> CSignature_o_oo;
}
}
} // namespace v8::internal::compiler
diff --git a/deps/v8/test/cctest/compiler/call-tester.h b/deps/v8/test/cctest/compiler/call-tester.h
index 6d8c761452..dc265ea5fa 100644
--- a/deps/v8/test/cctest/compiler/call-tester.h
+++ b/deps/v8/test/cctest/compiler/call-tester.h
@@ -9,6 +9,8 @@
#include "src/simulator.h"
+#include "test/cctest/compiler/c-signature.h"
+
#if V8_TARGET_ARCH_IA32
#if __GNUC__
#define V8_CDECL __attribute__((cdecl))
@@ -23,95 +25,64 @@ namespace v8 {
namespace internal {
namespace compiler {
-// TODO(titzer): use c-signature.h instead of ReturnValueTraits
template <typename R>
-struct ReturnValueTraits {
- static R Cast(uintptr_t r) { return reinterpret_cast<R>(r); }
- static MachineType Representation() {
- // TODO(dcarney): detect when R is of a subclass of Object* instead of this
- // type check.
- while (false) {
- *(static_cast<Object* volatile*>(0)) = static_cast<R>(0);
- }
- return kMachAnyTagged;
- }
-};
+inline R CastReturnValue(uintptr_t r) {
+ return reinterpret_cast<R>(r);
+}
template <>
-struct ReturnValueTraits<int32_t*> {
- static int32_t* Cast(uintptr_t r) { return reinterpret_cast<int32_t*>(r); }
- static MachineType Representation() { return kMachPtr; }
-};
+inline void CastReturnValue(uintptr_t r) {}
template <>
-struct ReturnValueTraits<void> {
- static void Cast(uintptr_t r) {}
- static MachineType Representation() { return kMachPtr; }
-};
+inline bool CastReturnValue(uintptr_t r) {
+ return static_cast<bool>(r);
+}
template <>
-struct ReturnValueTraits<bool> {
- static bool Cast(uintptr_t r) { return static_cast<bool>(r); }
- static MachineType Representation() { return kRepBit; }
-};
+inline int32_t CastReturnValue(uintptr_t r) {
+ return static_cast<int32_t>(r);
+}
template <>
-struct ReturnValueTraits<int32_t> {
- static int32_t Cast(uintptr_t r) { return static_cast<int32_t>(r); }
- static MachineType Representation() { return kMachInt32; }
-};
+inline uint32_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint32_t>(r);
+}
template <>
-struct ReturnValueTraits<uint32_t> {
- static uint32_t Cast(uintptr_t r) { return static_cast<uint32_t>(r); }
- static MachineType Representation() { return kMachUint32; }
-};
-
-template <>
-struct ReturnValueTraits<int64_t> {
- static int64_t Cast(uintptr_t r) { return static_cast<int64_t>(r); }
- static MachineType Representation() { return kMachInt64; }
-};
+inline int64_t CastReturnValue(uintptr_t r) {
+ return static_cast<int64_t>(r);
+}
template <>
-struct ReturnValueTraits<uint64_t> {
- static uint64_t Cast(uintptr_t r) { return static_cast<uint64_t>(r); }
- static MachineType Representation() { return kMachUint64; }
-};
+inline uint64_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint64_t>(r);
+}
template <>
-struct ReturnValueTraits<int16_t> {
- static int16_t Cast(uintptr_t r) { return static_cast<int16_t>(r); }
- static MachineType Representation() { return kMachInt16; }
-};
+inline int16_t CastReturnValue(uintptr_t r) {
+ return static_cast<int16_t>(r);
+}
template <>
-struct ReturnValueTraits<uint16_t> {
- static uint16_t Cast(uintptr_t r) { return static_cast<uint16_t>(r); }
- static MachineType Representation() { return kMachUint16; }
-};
+inline uint16_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint16_t>(r);
+}
template <>
-struct ReturnValueTraits<int8_t> {
- static int8_t Cast(uintptr_t r) { return static_cast<int8_t>(r); }
- static MachineType Representation() { return kMachInt8; }
-};
+inline int8_t CastReturnValue(uintptr_t r) {
+ return static_cast<int8_t>(r);
+}
template <>
-struct ReturnValueTraits<uint8_t> {
- static uint8_t Cast(uintptr_t r) { return static_cast<uint8_t>(r); }
- static MachineType Representation() { return kMachUint8; }
-};
+inline uint8_t CastReturnValue(uintptr_t r) {
+ return static_cast<uint8_t>(r);
+}
template <>
-struct ReturnValueTraits<double> {
- static double Cast(uintptr_t r) {
- UNREACHABLE();
- return 0.0;
- }
- static MachineType Representation() { return kMachFloat64; }
-};
-
+inline double CastReturnValue(uintptr_t r) {
+ UNREACHABLE();
+ return 0.0;
+}
template <typename R>
struct ParameterTraits {
@@ -148,42 +119,52 @@ struct ParameterTraits<uint32_t> {
#endif // !V8_TARGET_ARCH_64_BIT
+template <typename R>
class CallHelper {
public:
- explicit CallHelper(Isolate* isolate, MachineSignature* machine_sig)
- : machine_sig_(machine_sig), isolate_(isolate) {
+ explicit CallHelper(Isolate* isolate, CSignature* csig)
+ : csig_(csig), isolate_(isolate) {
USE(isolate_);
}
virtual ~CallHelper() {}
- static MachineSignature* MakeMachineSignature(
- Zone* zone, MachineType return_type, MachineType p0 = kMachNone,
- MachineType p1 = kMachNone, MachineType p2 = kMachNone,
- MachineType p3 = kMachNone, MachineType p4 = kMachNone) {
- // Count the number of parameters.
- size_t param_count = 5;
- MachineType types[] = {p0, p1, p2, p3, p4};
- while (param_count > 0 && types[param_count - 1] == kMachNone)
- param_count--;
- size_t return_count = return_type == kMachNone ? 0 : 1;
-
- // Build the machine signature.
- MachineSignature::Builder builder(zone, return_count, param_count);
- if (return_count > 0) builder.AddReturn(return_type);
- for (size_t i = 0; i < param_count; i++) {
- builder.AddParam(types[i]);
- }
- return builder.Build();
+ R Call() {
+ typedef R V8_CDECL FType();
+ csig_->VerifyParams();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()));
}
- protected:
- MachineSignature* machine_sig_;
- void VerifyParameters(size_t parameter_count, MachineType* parameter_types) {
- CHECK(machine_sig_->parameter_count() == parameter_count);
- for (size_t i = 0; i < parameter_count; i++) {
- CHECK_EQ(machine_sig_->GetParam(i), parameter_types[i]);
- }
+ template <typename P1>
+ R Call(P1 p1) {
+ typedef R V8_CDECL FType(P1);
+ csig_->VerifyParams<P1>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1);
+ }
+
+ template <typename P1, typename P2>
+ R Call(P1 p1, P2 p2) {
+ typedef R V8_CDECL FType(P1, P2);
+ csig_->VerifyParams<P1, P2>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2);
+ }
+
+ template <typename P1, typename P2, typename P3>
+ R Call(P1 p1, P2 p2, P3 p3) {
+ typedef R V8_CDECL FType(P1, P2, P3);
+ csig_->VerifyParams<P1, P2, P3>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
+ }
+
+ template <typename P1, typename P2, typename P3, typename P4>
+ R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
+ typedef R V8_CDECL FType(P1, P2, P3, P4);
+ csig_->VerifyParams<P1, P2, P3, P4>();
+ return DoCall(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
}
+
+ protected:
+ CSignature* csig_;
+
virtual byte* Generate() = 0;
private:
@@ -193,39 +174,38 @@ class CallHelper {
return static_cast<uintptr_t>(simulator->CallInt64(f, args));
}
- template <typename R, typename F>
+ template <typename F>
R DoCall(F* f) {
Simulator::CallArgument args[] = {Simulator::CallArgument::End()};
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1>
+ template <typename F, typename P1>
R DoCall(F* f, P1 p1) {
Simulator::CallArgument args[] = {Simulator::CallArgument(p1),
Simulator::CallArgument::End()};
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1, typename P2>
+ template <typename F, typename P1, typename P2>
R DoCall(F* f, P1 p1, P2 p2) {
Simulator::CallArgument args[] = {Simulator::CallArgument(p1),
Simulator::CallArgument(p2),
Simulator::CallArgument::End()};
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1, typename P2, typename P3>
+ template <typename F, typename P1, typename P2, typename P3>
R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
Simulator::CallArgument args[] = {
Simulator::CallArgument(p1), Simulator::CallArgument(p2),
Simulator::CallArgument(p3), Simulator::CallArgument::End()};
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
- template <typename R, typename F, typename P1, typename P2, typename P3,
- typename P4>
+ template <typename F, typename P1, typename P2, typename P3, typename P4>
R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
Simulator::CallArgument args[] = {
Simulator::CallArgument(p1), Simulator::CallArgument(p2),
Simulator::CallArgument(p3), Simulator::CallArgument(p4),
Simulator::CallArgument::End()};
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f), args));
}
#elif USE_SIMULATOR && (V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64)
uintptr_t CallSimulator(byte* f, int64_t p1 = 0, int64_t p2 = 0,
@@ -235,31 +215,30 @@ class CallHelper {
}
- template <typename R, typename F>
+ template <typename F>
R DoCall(F* f) {
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f)));
}
- template <typename R, typename F, typename P1>
+ template <typename F, typename P1>
R DoCall(F* f, P1 p1) {
- return ReturnValueTraits<R>::Cast(
+ return CastReturnValue<R>(
CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
}
- template <typename R, typename F, typename P1, typename P2>
+ template <typename F, typename P1, typename P2>
R DoCall(F* f, P1 p1, P2 p2) {
- return ReturnValueTraits<R>::Cast(
- CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
- ParameterTraits<P2>::Cast(p2)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f),
+ ParameterTraits<P1>::Cast(p1),
+ ParameterTraits<P2>::Cast(p2)));
}
- template <typename R, typename F, typename P1, typename P2, typename P3>
+ template <typename F, typename P1, typename P2, typename P3>
R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
- return ReturnValueTraits<R>::Cast(CallSimulator(
+ return CastReturnValue<R>(CallSimulator(
FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3)));
}
- template <typename R, typename F, typename P1, typename P2, typename P3,
- typename P4>
+ template <typename F, typename P1, typename P2, typename P3, typename P4>
R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
- return ReturnValueTraits<R>::Cast(CallSimulator(
+ return CastReturnValue<R>(CallSimulator(
FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
ParameterTraits<P4>::Cast(p4)));
@@ -271,179 +250,60 @@ class CallHelper {
Simulator* simulator = Simulator::current(isolate_);
return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4));
}
- template <typename R, typename F>
+ template <typename F>
R DoCall(F* f) {
- return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f)));
}
- template <typename R, typename F, typename P1>
+ template <typename F, typename P1>
R DoCall(F* f, P1 p1) {
- return ReturnValueTraits<R>::Cast(
+ return CastReturnValue<R>(
CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
}
- template <typename R, typename F, typename P1, typename P2>
+ template <typename F, typename P1, typename P2>
R DoCall(F* f, P1 p1, P2 p2) {
- return ReturnValueTraits<R>::Cast(
- CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
- ParameterTraits<P2>::Cast(p2)));
+ return CastReturnValue<R>(CallSimulator(FUNCTION_ADDR(f),
+ ParameterTraits<P1>::Cast(p1),
+ ParameterTraits<P2>::Cast(p2)));
}
- template <typename R, typename F, typename P1, typename P2, typename P3>
+ template <typename F, typename P1, typename P2, typename P3>
R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
- return ReturnValueTraits<R>::Cast(CallSimulator(
+ return CastReturnValue<R>(CallSimulator(
FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3)));
}
- template <typename R, typename F, typename P1, typename P2, typename P3,
- typename P4>
+ template <typename F, typename P1, typename P2, typename P3, typename P4>
R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
- return ReturnValueTraits<R>::Cast(CallSimulator(
+ return CastReturnValue<R>(CallSimulator(
FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
ParameterTraits<P4>::Cast(p4)));
}
#else
- template <typename R, typename F>
+ template <typename F>
R DoCall(F* f) {
return f();
}
- template <typename R, typename F, typename P1>
+ template <typename F, typename P1>
R DoCall(F* f, P1 p1) {
return f(p1);
}
- template <typename R, typename F, typename P1, typename P2>
+ template <typename F, typename P1, typename P2>
R DoCall(F* f, P1 p1, P2 p2) {
return f(p1, p2);
}
- template <typename R, typename F, typename P1, typename P2, typename P3>
+ template <typename F, typename P1, typename P2, typename P3>
R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
return f(p1, p2, p3);
}
- template <typename R, typename F, typename P1, typename P2, typename P3,
- typename P4>
+ template <typename F, typename P1, typename P2, typename P3, typename P4>
R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
return f(p1, p2, p3, p4);
}
#endif
-#ifndef DEBUG
- void VerifyParameters0() {}
-
- template <typename P1>
- void VerifyParameters1() {}
-
- template <typename P1, typename P2>
- void VerifyParameters2() {}
-
- template <typename P1, typename P2, typename P3>
- void VerifyParameters3() {}
-
- template <typename P1, typename P2, typename P3, typename P4>
- void VerifyParameters4() {}
-#else
- void VerifyParameters0() { VerifyParameters(0, NULL); }
-
- template <typename P1>
- void VerifyParameters1() {
- MachineType parameters[] = {ReturnValueTraits<P1>::Representation()};
- VerifyParameters(arraysize(parameters), parameters);
- }
-
- template <typename P1, typename P2>
- void VerifyParameters2() {
- MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
- ReturnValueTraits<P2>::Representation()};
- VerifyParameters(arraysize(parameters), parameters);
- }
-
- template <typename P1, typename P2, typename P3>
- void VerifyParameters3() {
- MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
- ReturnValueTraits<P2>::Representation(),
- ReturnValueTraits<P3>::Representation()};
- VerifyParameters(arraysize(parameters), parameters);
- }
-
- template <typename P1, typename P2, typename P3, typename P4>
- void VerifyParameters4() {
- MachineType parameters[] = {ReturnValueTraits<P1>::Representation(),
- ReturnValueTraits<P2>::Representation(),
- ReturnValueTraits<P3>::Representation(),
- ReturnValueTraits<P4>::Representation()};
- VerifyParameters(arraysize(parameters), parameters);
- }
-#endif
-
- // TODO(dcarney): replace Call() in CallHelper2 with these.
- template <typename R>
- R Call0() {
- typedef R V8_CDECL FType();
- VerifyParameters0();
- return DoCall<R>(FUNCTION_CAST<FType*>(Generate()));
- }
-
- template <typename R, typename P1>
- R Call1(P1 p1) {
- typedef R V8_CDECL FType(P1);
- VerifyParameters1<P1>();
- return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1);
- }
-
- template <typename R, typename P1, typename P2>
- R Call2(P1 p1, P2 p2) {
- typedef R V8_CDECL FType(P1, P2);
- VerifyParameters2<P1, P2>();
- return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2);
- }
-
- template <typename R, typename P1, typename P2, typename P3>
- R Call3(P1 p1, P2 p2, P3 p3) {
- typedef R V8_CDECL FType(P1, P2, P3);
- VerifyParameters3<P1, P2, P3>();
- return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3);
- }
-
- template <typename R, typename P1, typename P2, typename P3, typename P4>
- R Call4(P1 p1, P2 p2, P3 p3, P4 p4) {
- typedef R V8_CDECL FType(P1, P2, P3, P4);
- VerifyParameters4<P1, P2, P3, P4>();
- return DoCall<R>(FUNCTION_CAST<FType*>(Generate()), p1, p2, p3, p4);
- }
-
- template <typename R, typename C>
- friend class CallHelper2;
Isolate* isolate_;
};
-
-// TODO(dcarney): replace CallHelper with CallHelper2 and rename.
-template <typename R, typename C>
-class CallHelper2 {
- public:
- R Call() { return helper()->template Call0<R>(); }
-
- template <typename P1>
- R Call(P1 p1) {
- return helper()->template Call1<R>(p1);
- }
-
- template <typename P1, typename P2>
- R Call(P1 p1, P2 p2) {
- return helper()->template Call2<R>(p1, p2);
- }
-
- template <typename P1, typename P2, typename P3>
- R Call(P1 p1, P2 p2, P3 p3) {
- return helper()->template Call3<R>(p1, p2, p3);
- }
-
- template <typename P1, typename P2, typename P3, typename P4>
- R Call(P1 p1, P2 p2, P3 p3, P4 p4) {
- return helper()->template Call4<R>(p1, p2, p3, p4);
- }
-
- private:
- CallHelper* helper() { return static_cast<C*>(this); }
-};
-
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/compiler/codegen-tester.h b/deps/v8/test/cctest/compiler/codegen-tester.h
index f2fc48a479..bc6d938ce1 100644
--- a/deps/v8/test/cctest/compiler/codegen-tester.h
+++ b/deps/v8/test/cctest/compiler/codegen-tester.h
@@ -17,38 +17,26 @@ namespace v8 {
namespace internal {
namespace compiler {
-template <typename MachineAssembler>
-class MachineAssemblerTester : public HandleAndZoneScope,
- public CallHelper,
- public MachineAssembler {
+template <typename ReturnType>
+class RawMachineAssemblerTester : public HandleAndZoneScope,
+ public CallHelper<ReturnType>,
+ public RawMachineAssembler {
public:
- MachineAssemblerTester(MachineType return_type, MachineType p0,
- MachineType p1, MachineType p2, MachineType p3,
- MachineType p4,
- MachineOperatorBuilder::Flags flags =
- MachineOperatorBuilder::Flag::kNoFlags)
+ RawMachineAssemblerTester(MachineType p0 = kMachNone,
+ MachineType p1 = kMachNone,
+ MachineType p2 = kMachNone,
+ MachineType p3 = kMachNone,
+ MachineType p4 = kMachNone)
: HandleAndZoneScope(),
- CallHelper(
+ CallHelper<ReturnType>(
main_isolate(),
- MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4)),
- MachineAssembler(
+ CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+ p2, p3, p4)),
+ RawMachineAssembler(
main_isolate(), new (main_zone()) Graph(main_zone()),
- MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4),
- kMachPtr, flags) {}
-
- Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
- return this->Load(rep, this->PointerConstant(address),
- this->Int32Constant(offset));
- }
-
- void StoreToPointer(void* address, MachineType rep, Node* node) {
- this->Store(rep, this->PointerConstant(address), node);
- }
-
- Node* StringConstant(const char* string) {
- return this->HeapConstant(
- this->isolate()->factory()->InternalizeUtf8String(string));
- }
+ CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+ p2, p3, p4),
+ kMachPtr, InstructionSelector::SupportedMachineOperatorFlags()) {}
void CheckNumber(double expected, Object* number) {
CHECK(this->isolate()->factory()->NewNumber(expected)->SameValue(number));
@@ -79,41 +67,6 @@ class MachineAssemblerTester : public HandleAndZoneScope,
};
-template <typename ReturnType>
-class RawMachineAssemblerTester
- : public MachineAssemblerTester<RawMachineAssembler>,
- public CallHelper2<ReturnType, RawMachineAssemblerTester<ReturnType> > {
- public:
- RawMachineAssemblerTester(MachineType p0 = kMachNone,
- MachineType p1 = kMachNone,
- MachineType p2 = kMachNone,
- MachineType p3 = kMachNone,
- MachineType p4 = kMachNone)
- : MachineAssemblerTester<RawMachineAssembler>(
- ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3, p4,
- InstructionSelector::SupportedMachineOperatorFlags()) {}
-
- template <typename Ci, typename Fn>
- void Run(const Ci& ci, const Fn& fn) {
- typename Ci::const_iterator i;
- for (i = ci.begin(); i != ci.end(); ++i) {
- CHECK_EQ(fn(*i), this->Call(*i));
- }
- }
-
- template <typename Ci, typename Cj, typename Fn>
- void Run(const Ci& ci, const Cj& cj, const Fn& fn) {
- typename Ci::const_iterator i;
- typename Cj::const_iterator j;
- for (i = ci.begin(); i != ci.end(); ++i) {
- for (j = cj.begin(); j != cj.end(); ++j) {
- CHECK_EQ(fn(*i, *j), this->Call(*i, *j));
- }
- }
- }
-};
-
-
static const bool USE_RESULT_BUFFER = true;
static const bool USE_RETURN_REGISTER = false;
static const int32_t CHECK_VALUE = 0x99BEEDCE;
diff --git a/deps/v8/test/cctest/compiler/function-tester.h b/deps/v8/test/cctest/compiler/function-tester.h
index 20efd1e304..54c62ab634 100644
--- a/deps/v8/test/cctest/compiler/function-tester.h
+++ b/deps/v8/test/cctest/compiler/function-tester.h
@@ -34,15 +34,16 @@ class FunctionTester : public InitializedHandleScope {
flags_(flags) {
Compile(function);
const uint32_t supported_flags = CompilationInfo::kContextSpecializing |
- CompilationInfo::kBuiltinInliningEnabled |
CompilationInfo::kInliningEnabled |
CompilationInfo::kTypingEnabled;
CHECK_EQ(0u, flags_ & ~supported_flags);
}
+ // TODO(turbofan): generalize FunctionTester to work with N arguments. Now, it
+ // can handle up to four.
explicit FunctionTester(Graph* graph)
: isolate(main_isolate()),
- function(NewFunction("(function(a,b){})")),
+ function(NewFunction("(function(a,b,c,d){})")),
flags_(0) {
CompileGraph(graph);
}
@@ -55,8 +56,14 @@ class FunctionTester : public InitializedHandleScope {
return Execution::Call(isolate, function, undefined(), 2, args, false);
}
+ MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b, Handle<Object> c,
+ Handle<Object> d) {
+ Handle<Object> args[] = {a, b, c, d};
+ return Execution::Call(isolate, function, undefined(), 4, args, false);
+ }
+
void CheckThrows(Handle<Object> a, Handle<Object> b) {
- TryCatch try_catch;
+ TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
MaybeHandle<Object> no_result = Call(a, b);
CHECK(isolate->has_pending_exception());
CHECK(try_catch.HasCaught());
@@ -66,7 +73,7 @@ class FunctionTester : public InitializedHandleScope {
v8::Handle<v8::Message> CheckThrowsReturnMessage(Handle<Object> a,
Handle<Object> b) {
- TryCatch try_catch;
+ TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
MaybeHandle<Object> no_result = Call(a, b);
CHECK(isolate->has_pending_exception());
CHECK(try_catch.HasCaught());
@@ -153,6 +160,7 @@ class FunctionTester : public InitializedHandleScope {
Zone zone;
ParseInfo parse_info(&zone, function);
CompilationInfo info(&parse_info);
+ info.MarkAsDeoptimizationEnabled();
CHECK(Parser::ParseStatic(info.parse_info()));
info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
@@ -170,11 +178,8 @@ class FunctionTester : public InitializedHandleScope {
Pipeline pipeline(&info);
Handle<Code> code = pipeline.GenerateCode();
- if (FLAG_turbo_deoptimization) {
- info.context()->native_context()->AddOptimizedCode(*code);
- }
-
CHECK(!code.is_null());
+ info.context()->native_context()->AddOptimizedCode(*code);
function->ReplaceCode(*code);
#elif USE_CRANKSHAFT
Handle<Code> unoptimized = Handle<Code>(function->code());
diff --git a/deps/v8/test/cctest/compiler/graph-builder-tester.h b/deps/v8/test/cctest/compiler/graph-builder-tester.h
index 9a5174c1d7..7270293e0f 100644
--- a/deps/v8/test/cctest/compiler/graph-builder-tester.h
+++ b/deps/v8/test/cctest/compiler/graph-builder-tester.h
@@ -39,12 +39,10 @@ class GraphAndBuilders {
template <typename ReturnType>
-class GraphBuilderTester
- : public HandleAndZoneScope,
- private GraphAndBuilders,
- public CallHelper,
- public SimplifiedGraphBuilder,
- public CallHelper2<ReturnType, GraphBuilderTester<ReturnType> > {
+class GraphBuilderTester : public HandleAndZoneScope,
+ private GraphAndBuilders,
+ public CallHelper<ReturnType>,
+ public SimplifiedGraphBuilder {
public:
explicit GraphBuilderTester(MachineType p0 = kMachNone,
MachineType p1 = kMachNone,
@@ -52,11 +50,10 @@ class GraphBuilderTester
MachineType p3 = kMachNone,
MachineType p4 = kMachNone)
: GraphAndBuilders(main_zone()),
- CallHelper(
+ CallHelper<ReturnType>(
main_isolate(),
- MakeMachineSignature(
- main_zone(), ReturnValueTraits<ReturnType>::Representation(),
- p0, p1, p2, p3, p4)),
+ CSignature::New(main_zone(), MachineTypeForC<ReturnType>(), p0, p1,
+ p2, p3, p4)),
SimplifiedGraphBuilder(main_isolate(), main_graph_, &main_common_,
&main_machine_, &main_simplified_),
parameters_(main_zone()->template NewArray<Node*>(parameter_count())) {
@@ -79,7 +76,7 @@ class GraphBuilderTester
if (code_.is_null()) {
Zone* zone = graph()->zone();
CallDescriptor* desc =
- Linkage::GetSimplifiedCDescriptor(zone, machine_sig_);
+ Linkage::GetSimplifiedCDescriptor(zone, this->csig_);
code_ = Pipeline::GenerateCodeForTesting(main_isolate(), desc, graph());
}
return code_.ToHandleChecked()->entry();
@@ -92,7 +89,7 @@ class GraphBuilderTester
}
}
- size_t parameter_count() const { return machine_sig_->parameter_count(); }
+ size_t parameter_count() const { return this->csig_->parameter_count(); }
private:
Node** parameters_;
diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.cc b/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
index 6afdc0a211..4d57719eff 100644
--- a/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
+++ b/deps/v8/test/cctest/compiler/simplified-graph-builder.cc
@@ -23,7 +23,7 @@ SimplifiedGraphBuilder::SimplifiedGraphBuilder(
void SimplifiedGraphBuilder::Begin(int num_parameters) {
DCHECK(graph()->start() == NULL);
- Node* start = graph()->NewNode(common()->Start(num_parameters));
+ Node* start = graph()->NewNode(common()->Start(num_parameters + 3));
graph()->SetStart(start);
effect_ = start;
}
@@ -37,7 +37,7 @@ void SimplifiedGraphBuilder::Return(Node* value) {
void SimplifiedGraphBuilder::End() {
- Node* end = graph()->NewNode(common()->End(), return_);
+ Node* end = graph()->NewNode(common()->End(1), return_);
graph()->SetEnd(end);
}
diff --git a/deps/v8/test/cctest/compiler/simplified-graph-builder.h b/deps/v8/test/cctest/compiler/simplified-graph-builder.h
index c9ba002c25..50c51d5ed8 100644
--- a/deps/v8/test/cctest/compiler/simplified-graph-builder.h
+++ b/deps/v8/test/cctest/compiler/simplified-graph-builder.h
@@ -92,9 +92,6 @@ class SimplifiedGraphBuilder : public GraphBuilder {
Node* StringLessThanOrEqual(Node* a, Node* b) {
return NewNode(simplified()->StringLessThanOrEqual(), a, b);
}
- Node* StringAdd(Node* a, Node* b) {
- return NewNode(simplified()->StringAdd(), a, b);
- }
Node* ChangeTaggedToInt32(Node* a) {
return NewNode(simplified()->ChangeTaggedToInt32(), a);
diff --git a/deps/v8/test/cctest/compiler/test-changes-lowering.cc b/deps/v8/test/cctest/compiler/test-changes-lowering.cc
index d11210bb8b..04b5b9176b 100644
--- a/deps/v8/test/cctest/compiler/test-changes-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-changes-lowering.cc
@@ -88,7 +88,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
Node* change = this->graph()->NewNode(op, p0);
Node* ret = this->graph()->NewNode(this->common()->Return(), change,
this->start(), this->start());
- Node* end = this->graph()->NewNode(this->common()->End(), ret);
+ Node* end = this->graph()->NewNode(this->common()->End(1), ret);
this->graph()->SetEnd(end);
LowerChange(change);
}
@@ -104,7 +104,7 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
change, this->start(), this->start());
Node* ret = this->graph()->NewNode(
this->common()->Return(), this->Int32Constant(0), store, this->start());
- Node* end = this->graph()->NewNode(this->common()->End(), ret);
+ Node* end = this->graph()->NewNode(this->common()->End(1), ret);
this->graph()->SetEnd(end);
LowerChange(change);
}
@@ -119,18 +119,18 @@ class ChangesLoweringTester : public GraphBuilderTester<ReturnType> {
Node* change = this->graph()->NewNode(op, load);
Node* ret = this->graph()->NewNode(this->common()->Return(), change,
this->start(), this->start());
- Node* end = this->graph()->NewNode(this->common()->End(), ret);
+ Node* end = this->graph()->NewNode(this->common()->End(1), ret);
this->graph()->SetEnd(end);
LowerChange(change);
}
void LowerChange(Node* change) {
// Run the graph reducer with changes lowering on a single node.
- Typer typer(this->isolate(), this->graph(), Handle<Context>());
+ Typer typer(this->isolate(), this->graph());
typer.Run();
ChangeLowering change_lowering(&jsgraph);
SelectLowering select_lowering(this->graph(), this->common());
- GraphReducer reducer(this->graph(), this->zone());
+ GraphReducer reducer(this->zone(), this->graph());
reducer.AddReducer(&change_lowering);
reducer.AddReducer(&select_lowering);
reducer.ReduceNode(change);
diff --git a/deps/v8/test/cctest/compiler/test-codegen-deopt.cc b/deps/v8/test/cctest/compiler/test-codegen-deopt.cc
deleted file mode 100644
index 0b59308216..0000000000
--- a/deps/v8/test/cctest/compiler/test-codegen-deopt.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/compiler/code-generator.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/instruction-selector.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/raw-machine-assembler.h"
-#include "src/compiler/register-allocator.h"
-#include "src/compiler/schedule.h"
-
-#include "src/ast-numbering.h"
-#include "src/full-codegen.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-
-#include "test/cctest/compiler/c-signature.h"
-#include "test/cctest/compiler/function-tester.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-
-#if V8_TURBOFAN_TARGET
-
-typedef RawMachineAssembler::Label MLabel;
-typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
-
-static Handle<JSFunction> NewFunction(const char* source) {
- return v8::Utils::OpenHandle(
- *v8::Handle<v8::Function>::Cast(CompileRun(source)));
-}
-
-
-class DeoptCodegenTester {
- public:
- explicit DeoptCodegenTester(HandleAndZoneScope* scope, const char* src)
- : scope_(scope),
- function(NewFunction(src)),
- parse_info(scope->main_zone(), function),
- info(&parse_info),
- bailout_id(-1),
- tagged_type(1, kMachAnyTagged, zone()),
- empty_types(zone()) {
- CHECK(Parser::ParseStatic(&parse_info));
- info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
- CHECK(Compiler::Analyze(&parse_info));
- CHECK(Compiler::EnsureDeoptimizationSupport(&info));
-
- DCHECK(info.shared_info()->has_deoptimization_support());
-
- graph = new (scope_->main_zone()) Graph(scope_->main_zone());
- }
-
- virtual ~DeoptCodegenTester() {}
-
- void GenerateCodeFromSchedule(Schedule* schedule) {
- OFStream os(stdout);
- if (FLAG_trace_turbo) {
- os << *schedule;
- }
- result_code = Pipeline::GenerateCodeForTesting(&info, graph, schedule);
-#ifdef OBJECT_PRINT
- if (FLAG_print_opt_code || FLAG_trace_turbo) {
- result_code->Print();
- }
-#endif
- }
-
- Zone* zone() { return scope_->main_zone(); }
- Isolate* isolate() { return scope_->main_isolate(); }
-
- HandleAndZoneScope* scope_;
- Handle<JSFunction> function;
- ParseInfo parse_info;
- CompilationInfo info;
- BailoutId bailout_id;
- Handle<Code> result_code;
- TestInstrSeq* code;
- Graph* graph;
- ZoneVector<MachineType> tagged_type;
- ZoneVector<MachineType> empty_types;
-};
-
-
-class TrivialDeoptCodegenTester : public DeoptCodegenTester {
- public:
- explicit TrivialDeoptCodegenTester(HandleAndZoneScope* scope)
- : DeoptCodegenTester(scope,
- "function foo() { deopt(); return 42; }; foo") {}
-
- void GenerateCode() {
- GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
- }
-
- Schedule* BuildGraphAndSchedule(Graph* graph) {
- CommonOperatorBuilder common(zone());
-
- // Manually construct a schedule for the function below:
- // function foo() {
- // deopt();
- // }
-
- CSignature1<Object*, Object*> sig;
- RawMachineAssembler m(isolate(), graph, &sig);
-
- Handle<JSFunction> deopt_function =
- NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
- Unique<JSFunction> deopt_fun_constant =
- Unique<JSFunction>::CreateUninitialized(deopt_function);
- Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
-
- Handle<Context> caller_context(function->context(), CcTest::i_isolate());
- Unique<Context> caller_context_constant =
- Unique<Context>::CreateUninitialized(caller_context);
- Node* caller_context_node =
- m.NewNode(common.HeapConstant(caller_context_constant));
-
- bailout_id = GetCallBailoutId();
- Node* parameters =
- m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
- Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
- Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
-
- Node* state_node = m.NewNode(
- common.FrameState(JS_FRAME, bailout_id,
- OutputFrameStateCombine::Ignore()),
- parameters, locals, stack, caller_context_node, m.UndefinedConstant());
-
- Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
- Unique<Context> context_constant =
- Unique<Context>::CreateUninitialized(context);
- Node* context_node = m.NewNode(common.HeapConstant(context_constant));
-
- m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);
-
- m.Return(m.UndefinedConstant());
-
- // Schedule the graph:
- Schedule* schedule = m.Export();
-
- return schedule;
- }
-
- BailoutId GetCallBailoutId() {
- ZoneList<Statement*>* body = info.function()->body();
- for (int i = 0; i < body->length(); i++) {
- if (body->at(i)->IsExpressionStatement() &&
- body->at(i)->AsExpressionStatement()->expression()->IsCall()) {
- return body->at(i)->AsExpressionStatement()->expression()->id();
- }
- }
- CHECK(false);
- return BailoutId(-1);
- }
-};
-
-
-TEST(TurboTrivialDeoptCodegen) {
- HandleAndZoneScope scope;
- InitializedHandleScope handles;
-
- FLAG_allow_natives_syntax = true;
- FLAG_turbo_deoptimization = true;
-
- TrivialDeoptCodegenTester t(&scope);
- t.GenerateCode();
-
- DeoptimizationInputData* data =
- DeoptimizationInputData::cast(t.result_code->deoptimization_data());
-
- // TODO(jarin) Find a way to test the safepoint.
-
- // Check that we deoptimize to the right AST id.
- CHECK_EQ(1, data->DeoptCount());
- CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt());
-}
-
-
-TEST(TurboTrivialDeoptCodegenAndRun) {
- HandleAndZoneScope scope;
- InitializedHandleScope handles;
-
- FLAG_allow_natives_syntax = true;
- FLAG_turbo_deoptimization = true;
-
- TrivialDeoptCodegenTester t(&scope);
- t.GenerateCode();
-
- t.function->ReplaceCode(*t.result_code);
- t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
-
- Isolate* isolate = scope.main_isolate();
- Handle<Object> result;
- bool has_pending_exception =
- !Execution::Call(isolate, t.function,
- isolate->factory()->undefined_value(), 0, NULL,
- false).ToHandle(&result);
- CHECK(!has_pending_exception);
- CHECK(result->SameValue(Smi::FromInt(42)));
-}
-
-
-class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
- public:
- explicit TrivialRuntimeDeoptCodegenTester(HandleAndZoneScope* scope)
- : DeoptCodegenTester(
- scope,
- "function foo() { %DeoptimizeFunction(foo); return 42; }; foo") {}
-
- void GenerateCode() {
- GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
- }
-
- Schedule* BuildGraphAndSchedule(Graph* graph) {
- CommonOperatorBuilder common(zone());
-
- // Manually construct a schedule for the function below:
- // function foo() {
- // %DeoptimizeFunction(foo);
- // }
-
- CSignature1<Object*, Object*> sig;
- RawMachineAssembler m(isolate(), graph, &sig);
-
- Unique<HeapObject> this_fun_constant =
- Unique<HeapObject>::CreateUninitialized(function);
- Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
-
- Handle<Context> context(function->context(), CcTest::i_isolate());
- Unique<HeapObject> context_constant =
- Unique<HeapObject>::CreateUninitialized(context);
- Node* context_node = m.NewNode(common.HeapConstant(context_constant));
-
- bailout_id = GetCallBailoutId();
- Node* parameters =
- m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
- Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
- Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
-
- Node* state_node = m.NewNode(
- common.FrameState(JS_FRAME, bailout_id,
- OutputFrameStateCombine::Ignore()),
- parameters, locals, stack, context_node, m.UndefinedConstant());
-
- m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
- state_node);
-
- m.Return(m.UndefinedConstant());
-
- // Schedule the graph:
- Schedule* schedule = m.Export();
-
- return schedule;
- }
-
- BailoutId GetCallBailoutId() {
- ZoneList<Statement*>* body = info.function()->body();
- for (int i = 0; i < body->length(); i++) {
- if (body->at(i)->IsExpressionStatement() &&
- body->at(i)->AsExpressionStatement()->expression()->IsCallRuntime()) {
- return body->at(i)->AsExpressionStatement()->expression()->id();
- }
- }
- CHECK(false);
- return BailoutId(-1);
- }
-};
-
-
-TEST(TurboTrivialRuntimeDeoptCodegenAndRun) {
- HandleAndZoneScope scope;
- InitializedHandleScope handles;
-
- FLAG_allow_natives_syntax = true;
- FLAG_turbo_deoptimization = true;
-
- TrivialRuntimeDeoptCodegenTester t(&scope);
- t.GenerateCode();
-
- t.function->ReplaceCode(*t.result_code);
- t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
-
- Isolate* isolate = scope.main_isolate();
- Handle<Object> result;
- bool has_pending_exception =
- !Execution::Call(isolate, t.function,
- isolate->factory()->undefined_value(), 0, NULL,
- false).ToHandle(&result);
- CHECK(!has_pending_exception);
- CHECK(result->SameValue(Smi::FromInt(42)));
-}
-
-#endif
diff --git a/deps/v8/test/cctest/compiler/test-control-reducer.cc b/deps/v8/test/cctest/compiler/test-control-reducer.cc
deleted file mode 100644
index e969e27106..0000000000
--- a/deps/v8/test/cctest/compiler/test-control-reducer.cc
+++ /dev/null
@@ -1,1641 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/base/bits.h"
-#include "src/compiler/all-nodes.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/control-reducer.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-static const size_t kNumLeafs = 4;
-
-enum Decision { kFalse, kUnknown, kTrue };
-
-// TODO(titzer): convert this whole file into unit tests.
-
-static int CheckInputs(Node* node, Node* i0 = NULL, Node* i1 = NULL,
- Node* i2 = NULL) {
- int count = 3;
- if (i2 == NULL) count = 2;
- if (i1 == NULL) count = 1;
- if (i0 == NULL) count = 0;
- CHECK_EQ(count, node->InputCount());
- if (i0 != NULL) CHECK_EQ(i0, node->InputAt(0));
- if (i1 != NULL) CHECK_EQ(i1, node->InputAt(1));
- if (i2 != NULL) CHECK_EQ(i2, node->InputAt(2));
- return count;
-}
-
-
-static int CheckMerge(Node* node, Node* i0 = NULL, Node* i1 = NULL,
- Node* i2 = NULL) {
- CHECK_EQ(IrOpcode::kMerge, node->opcode());
- int count = CheckInputs(node, i0, i1, i2);
- CHECK_EQ(count, node->op()->ControlInputCount());
- return count;
-}
-
-
-static int CheckLoop(Node* node, Node* i0 = NULL, Node* i1 = NULL,
- Node* i2 = NULL) {
- CHECK_EQ(IrOpcode::kLoop, node->opcode());
- int count = CheckInputs(node, i0, i1, i2);
- CHECK_EQ(count, node->op()->ControlInputCount());
- return count;
-}
-
-
-bool IsUsedBy(Node* a, Node* b) {
- auto const uses = a->uses();
- return std::find(uses.begin(), uses.end(), b) != uses.end();
-}
-
-
-// A helper for all tests dealing with ControlTester.
-class ControlReducerTester : HandleAndZoneScope {
- public:
- ControlReducerTester()
- : isolate(main_isolate()),
- common(main_zone()),
- graph(main_zone()),
- jsgraph(main_isolate(), &graph, &common, NULL, NULL),
- start(graph.NewNode(common.Start(1))),
- end(graph.NewNode(common.End(), start)),
- p0(graph.NewNode(common.Parameter(0), start)),
- zero(jsgraph.Int32Constant(0)),
- one(jsgraph.OneConstant()),
- half(jsgraph.Constant(0.5)),
- self(graph.NewNode(common.Int32Constant(0xaabbccdd))),
- dead(graph.NewNode(common.Dead())) {
- graph.SetEnd(end);
- graph.SetStart(start);
- leaf[0] = zero;
- leaf[1] = one;
- leaf[2] = half;
- leaf[3] = p0;
- }
-
- Isolate* isolate;
- CommonOperatorBuilder common;
- Graph graph;
- JSGraph jsgraph;
- Node* start;
- Node* end;
- Node* p0;
- Node* zero;
- Node* one;
- Node* half;
- Node* self;
- Node* dead;
- Node* leaf[kNumLeafs];
-
- Node* Phi(Node* a) {
- return SetSelfReferences(graph.NewNode(op(1, false), a, start));
- }
-
- Node* Phi(Node* a, Node* b) {
- return SetSelfReferences(graph.NewNode(op(2, false), a, b, start));
- }
-
- Node* Phi(Node* a, Node* b, Node* c) {
- return SetSelfReferences(graph.NewNode(op(3, false), a, b, c, start));
- }
-
- Node* Phi(Node* a, Node* b, Node* c, Node* d) {
- return SetSelfReferences(graph.NewNode(op(4, false), a, b, c, d, start));
- }
-
- Node* EffectPhi(Node* a) {
- return SetSelfReferences(graph.NewNode(op(1, true), a, start));
- }
-
- Node* EffectPhi(Node* a, Node* b) {
- return SetSelfReferences(graph.NewNode(op(2, true), a, b, start));
- }
-
- Node* EffectPhi(Node* a, Node* b, Node* c) {
- return SetSelfReferences(graph.NewNode(op(3, true), a, b, c, start));
- }
-
- Node* EffectPhi(Node* a, Node* b, Node* c, Node* d) {
- return SetSelfReferences(graph.NewNode(op(4, true), a, b, c, d, start));
- }
-
- Node* SetSelfReferences(Node* node) {
- for (Edge edge : node->input_edges()) {
- if (edge.to() == self) node->ReplaceInput(edge.index(), node);
- }
- return node;
- }
-
- const Operator* op(int count, bool effect) {
- return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count);
- }
-
- void Trim() { ControlReducer::TrimGraph(main_zone(), &jsgraph); }
-
- void ReduceGraph() { ControlReducer::ReduceGraph(main_zone(), &jsgraph); }
-
- // Checks one-step reduction of a phi.
- void ReducePhi(Node* expect, Node* phi) {
- Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi);
- CHECK_EQ(expect, result);
- ReducePhiIterative(expect, phi); // iterative should give the same result.
- }
-
- // Checks one-step reduction of a phi.
- void ReducePhiNonIterative(Node* expect, Node* phi) {
- Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, phi);
- CHECK_EQ(expect, result);
- }
-
- void ReducePhiIterative(Node* expect, Node* phi) {
- p0->ReplaceInput(0, start); // hack: parameters may be trimmed.
- Node* ret = graph.NewNode(common.Return(), phi, start, start);
- Node* end = graph.NewNode(common.End(), ret);
- graph.SetEnd(end);
- ControlReducer::ReduceGraph(main_zone(), &jsgraph);
- CheckInputs(end, ret);
- CheckInputs(ret, expect, start, start);
- }
-
- void ReduceMerge(Node* expect, Node* merge) {
- Node* result = ControlReducer::ReduceMerge(&jsgraph, merge);
- CHECK_EQ(expect, result);
- }
-
- void ReduceMergeIterative(Node* expect, Node* merge) {
- p0->ReplaceInput(0, start); // hack: parameters may be trimmed.
- Node* end = graph.NewNode(common.End(), merge);
- graph.SetEnd(end);
- ReduceGraph();
- CheckInputs(end, expect);
- }
-
- void ReduceBranch(Decision expected, Node* branch) {
- Node* control = branch->InputAt(1);
- for (Node* use : branch->uses()) {
- if (use->opcode() == IrOpcode::kIfTrue) {
- Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use);
- if (expected == kTrue) CHECK_EQ(control, result);
- if (expected == kFalse) CHECK_EQ(IrOpcode::kDead, result->opcode());
- if (expected == kUnknown) CHECK_EQ(use, result);
- } else if (use->opcode() == IrOpcode::kIfFalse) {
- Node* result = ControlReducer::ReduceIfNodeForTesting(&jsgraph, use);
- if (expected == kFalse) CHECK_EQ(control, result);
- if (expected == kTrue) CHECK_EQ(IrOpcode::kDead, result->opcode());
- if (expected == kUnknown) CHECK_EQ(use, result);
- } else {
- UNREACHABLE();
- }
- }
- }
-
- Node* Return(Node* val, Node* effect, Node* control) {
- Node* ret = graph.NewNode(common.Return(), val, effect, control);
- end->ReplaceInput(0, ret);
- return ret;
- }
-};
-
-
-struct Branch {
- Node* branch;
- Node* if_true;
- Node* if_false;
-
- Branch(ControlReducerTester& R, Node* cond, Node* control = NULL) {
- if (control == NULL) control = R.start;
- branch = R.graph.NewNode(R.common.Branch(), cond, control);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- }
-};
-
-
-// TODO(titzer): use the diamonds from src/compiler/diamond.h here.
-struct Diamond {
- Node* branch;
- Node* if_true;
- Node* if_false;
- Node* merge;
- Node* phi;
-
- Diamond(ControlReducerTester& R, Node* cond) {
- branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
- phi = NULL;
- }
-
- Diamond(ControlReducerTester& R, Node* cond, Node* tv, Node* fv) {
- branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
- phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 2), tv, fv, merge);
- }
-
- void chain(Diamond& that) { branch->ReplaceInput(1, that.merge); }
-
- // Nest {this} into either the if_true or if_false branch of {that}.
- void nest(Diamond& that, bool if_true) {
- if (if_true) {
- branch->ReplaceInput(1, that.if_true);
- that.merge->ReplaceInput(0, merge);
- } else {
- branch->ReplaceInput(1, that.if_false);
- that.merge->ReplaceInput(1, merge);
- }
- }
-};
-
-
-struct While {
- Node* branch;
- Node* if_true;
- Node* exit;
- Node* loop;
-
- While(ControlReducerTester& R, Node* cond) {
- loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
- branch = R.graph.NewNode(R.common.Branch(), cond, loop);
- if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- exit = R.graph.NewNode(R.common.IfFalse(), branch);
- loop->ReplaceInput(1, if_true);
- }
-
- void chain(Node* control) { loop->ReplaceInput(0, control); }
-};
-
-
-// Helper for checking that nodes are *not* reachable from end.
-struct DeadChecker {
- Zone zone;
- AllNodes nodes;
- explicit DeadChecker(Graph* graph) : zone(), nodes(&zone, graph) {}
-
- void Check(Node* node) { CHECK(!nodes.IsLive(node)); }
-
- void Check(Diamond& d) {
- Check(d.branch);
- Check(d.if_true);
- Check(d.if_false);
- Check(d.merge);
- if (d.phi != NULL) Check(d.phi);
- }
-
- void CheckLive(Diamond& d, bool live_phi = true) {
- CheckInputs(d.merge, d.if_true, d.if_false);
- CheckInputs(d.if_true, d.branch);
- CheckInputs(d.if_false, d.branch);
- if (d.phi != NULL) {
- if (live_phi) {
- CHECK_EQ(3, d.phi->InputCount());
- CHECK_EQ(d.merge, d.phi->InputAt(2));
- } else {
- Check(d.phi);
- }
- }
- }
-};
-
-
-TEST(Trim1_live) {
- ControlReducerTester T;
- CHECK(IsUsedBy(T.start, T.p0));
- T.graph.SetEnd(T.p0);
- T.Trim();
- CHECK(IsUsedBy(T.start, T.p0));
- CheckInputs(T.p0, T.start);
-}
-
-
-TEST(Trim1_dead) {
- ControlReducerTester T;
- CHECK(IsUsedBy(T.start, T.p0));
- T.Trim();
- CHECK(!IsUsedBy(T.start, T.p0));
- CHECK(!T.p0->InputAt(0));
-}
-
-
-TEST(Trim2_live) {
- ControlReducerTester T;
- Node* phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
- CHECK(IsUsedBy(T.start, phi));
- T.graph.SetEnd(phi);
- T.Trim();
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
- CHECK(IsUsedBy(T.start, phi));
- CheckInputs(phi, T.one, T.half, T.start);
-}
-
-
-TEST(Trim2_dead) {
- ControlReducerTester T;
- Node* phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
- CHECK(IsUsedBy(T.start, phi));
- T.Trim();
- CHECK(!IsUsedBy(T.one, phi));
- CHECK(!IsUsedBy(T.half, phi));
- CHECK(!IsUsedBy(T.start, phi));
- CHECK(!phi->InputAt(0));
- CHECK(!phi->InputAt(1));
- CHECK(!phi->InputAt(2));
-}
-
-
-TEST(Trim_chain1) {
- ControlReducerTester T;
- const int kDepth = 15;
- Node* live[kDepth];
- Node* dead[kDepth];
- Node* end = T.start;
- for (int i = 0; i < kDepth; i++) {
- live[i] = end = T.graph.NewNode(T.common.Merge(1), end);
- dead[i] = T.graph.NewNode(T.common.Merge(1), end);
- }
- // end -> live[last] -> live[last-1] -> ... -> start
- // dead[last] ^ dead[last-1] ^ ... ^
- T.graph.SetEnd(end);
- T.Trim();
- for (int i = 0; i < kDepth; i++) {
- CHECK(!IsUsedBy(live[i], dead[i]));
- CHECK(!dead[i]->InputAt(0));
- CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
- }
-}
-
-
-TEST(Trim_chain2) {
- ControlReducerTester T;
- const int kDepth = 15;
- Node* live[kDepth];
- Node* dead[kDepth];
- Node* l = T.start;
- Node* d = T.start;
- for (int i = 0; i < kDepth; i++) {
- live[i] = l = T.graph.NewNode(T.common.Merge(1), l);
- dead[i] = d = T.graph.NewNode(T.common.Merge(1), d);
- }
- // end -> live[last] -> live[last-1] -> ... -> start
- // dead[last] -> dead[last-1] -> ... -> start
- T.graph.SetEnd(l);
- T.Trim();
- CHECK(!IsUsedBy(T.start, dead[0]));
- for (int i = 0; i < kDepth; i++) {
- CHECK_EQ(i == 0 ? NULL : dead[i - 1], dead[i]->InputAt(0));
- CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
- }
-}
-
-
-TEST(Trim_cycle1) {
- ControlReducerTester T;
- Node* loop = T.graph.NewNode(T.common.Loop(1), T.start, T.start);
- loop->ReplaceInput(1, loop);
- Node* end = T.graph.NewNode(T.common.End(), loop);
- T.graph.SetEnd(end);
-
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
-
- T.Trim();
-
- // nothing should have happened to the loop itself.
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
- CheckInputs(loop, T.start, loop);
- CheckInputs(end, loop);
-}
-
-
-TEST(Trim_cycle2) {
- ControlReducerTester T;
- Node* loop = T.graph.NewNode(T.common.Loop(2), T.start, T.start);
- loop->ReplaceInput(1, loop);
- Node* end = T.graph.NewNode(T.common.End(), loop);
- Node* phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, loop);
- T.graph.SetEnd(end);
-
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
- CHECK(IsUsedBy(loop, phi));
- CHECK(IsUsedBy(T.one, phi));
- CHECK(IsUsedBy(T.half, phi));
-
- T.Trim();
-
- // nothing should have happened to the loop itself.
- CHECK(IsUsedBy(T.start, loop));
- CHECK(IsUsedBy(loop, end));
- CHECK(IsUsedBy(loop, loop));
- CheckInputs(loop, T.start, loop);
- CheckInputs(end, loop);
-
- // phi should have been trimmed away.
- CHECK(!IsUsedBy(loop, phi));
- CHECK(!IsUsedBy(T.one, phi));
- CHECK(!IsUsedBy(T.half, phi));
- CHECK(!phi->InputAt(0));
- CHECK(!phi->InputAt(1));
- CHECK(!phi->InputAt(2));
-}
-
-
-void CheckTrimConstant(ControlReducerTester* T, Node* k) {
- Node* phi = T->graph.NewNode(T->common.Phi(kMachInt32, 1), k, T->start);
- CHECK(IsUsedBy(k, phi));
- T->Trim();
- CHECK(!IsUsedBy(k, phi));
- CHECK(!phi->InputAt(0));
- CHECK(!phi->InputAt(1));
-}
-
-
-TEST(Trim_constants) {
- ControlReducerTester T;
- int32_t int32_constants[] = {
- 0, -1, -2, 2, 2, 3, 3, 4, 4, 5, 5, 4, 5, 6, 6, 7, 8, 7, 8, 9,
- 0, -11, -12, 12, 12, 13, 13, 14, 14, 15, 15, 14, 15, 6, 6, 7, 8, 7, 8, 9};
-
- for (size_t i = 0; i < arraysize(int32_constants); i++) {
- CheckTrimConstant(&T, T.jsgraph.Int32Constant(int32_constants[i]));
- CheckTrimConstant(&T, T.jsgraph.Float64Constant(int32_constants[i]));
- CheckTrimConstant(&T, T.jsgraph.Constant(int32_constants[i]));
- }
-
- Node* other_constants[] = {
- T.jsgraph.UndefinedConstant(), T.jsgraph.TheHoleConstant(),
- T.jsgraph.TrueConstant(), T.jsgraph.FalseConstant(),
- T.jsgraph.NullConstant(), T.jsgraph.ZeroConstant(),
- T.jsgraph.OneConstant(), T.jsgraph.NaNConstant(),
- T.jsgraph.Constant(21), T.jsgraph.Constant(22.2)};
-
- for (size_t i = 0; i < arraysize(other_constants); i++) {
- CheckTrimConstant(&T, other_constants[i]);
- }
-}
-
-
-TEST(Trim_EmptyFrameState1) {
- ControlReducerTester T;
-
- Node* node = T.jsgraph.EmptyFrameState();
- T.Trim();
-
- for (Node* input : node->inputs()) {
- CHECK_NOT_NULL(input);
- }
-}
-
-
-TEST(Trim_EmptyFrameState2) {
- ControlReducerTester T;
- CheckTrimConstant(&T, T.jsgraph.EmptyFrameState());
-}
-
-
-TEST(CReducePhi1) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3]));
-}
-
-
-TEST(CReducePhi1_dead) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1], R.dead));
- R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2], R.dead));
- R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3], R.dead));
-
- R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.Phi(R.dead, R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.Phi(R.dead, R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.Phi(R.dead, R.leaf[3]));
-}
-
-
-TEST(CReducePhi1_dead2) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead, R.dead));
- R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.dead, R.leaf[0]));
-}
-
-
-TEST(CReducePhi2a) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a));
- }
-}
-
-
-TEST(CReducePhi2b) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a));
- R.ReducePhi(a, R.Phi(a, R.self));
- }
-}
-
-
-TEST(CReducePhi2c) {
- ControlReducerTester R;
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a);
- R.ReducePhi(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b);
- R.ReducePhi(phi2, phi2);
- }
-}
-
-
-TEST(CReducePhi2_dead) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a, R.dead));
- R.ReducePhi(a, R.Phi(a, R.dead, a));
- R.ReducePhi(a, R.Phi(R.dead, a, a));
- }
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a));
- R.ReducePhi(a, R.Phi(a, R.self));
- R.ReducePhi(a, R.Phi(R.self, a, R.dead));
- R.ReducePhi(a, R.Phi(a, R.self, R.dead));
- }
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a, R.dead);
- R.ReducePhiNonIterative(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b, R.dead);
- R.ReducePhiNonIterative(phi2, phi2);
- }
-}
-
-
-TEST(CReducePhi3) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a, a));
- }
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a, a));
- R.ReducePhi(a, R.Phi(a, R.self, a));
- R.ReducePhi(a, R.Phi(a, a, R.self));
- }
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a, a);
- R.ReducePhi(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b, a);
- R.ReducePhi(phi2, phi2);
-
- Node* phi3 = R.Phi(a, a, b);
- R.ReducePhi(phi3, phi3);
- }
-}
-
-
-TEST(CReducePhi4) {
- ControlReducerTester R;
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(a, a, a, a));
- }
-
- for (size_t i = 0; i < kNumLeafs; i++) {
- Node* a = R.leaf[i];
- R.ReducePhi(a, R.Phi(R.self, a, a, a));
- R.ReducePhi(a, R.Phi(a, R.self, a, a));
- R.ReducePhi(a, R.Phi(a, a, R.self, a));
- R.ReducePhi(a, R.Phi(a, a, a, R.self));
-
- R.ReducePhi(a, R.Phi(R.self, R.self, a, a));
- R.ReducePhi(a, R.Phi(a, R.self, R.self, a));
- R.ReducePhi(a, R.Phi(a, a, R.self, R.self));
- R.ReducePhi(a, R.Phi(R.self, a, a, R.self));
- }
-
- for (size_t i = 1; i < kNumLeafs; i++) {
- Node* a = R.leaf[i], *b = R.leaf[0];
- Node* phi1 = R.Phi(b, a, a, a);
- R.ReducePhi(phi1, phi1);
-
- Node* phi2 = R.Phi(a, b, a, a);
- R.ReducePhi(phi2, phi2);
-
- Node* phi3 = R.Phi(a, a, b, a);
- R.ReducePhi(phi3, phi3);
-
- Node* phi4 = R.Phi(a, a, a, b);
- R.ReducePhi(phi4, phi4);
- }
-}
-
-
-TEST(CReducePhi_iterative1) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0])));
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative2) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.Phi(R.leaf[0])));
-}
-
-
-TEST(CReducePhi_iterative3) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0],
- R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.leaf[0])));
- R.ReducePhiIterative(R.leaf[0],
- R.Phi(R.Phi(R.leaf[0], R.leaf[0]), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative4) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.leaf[0]),
- R.Phi(R.leaf[0], R.leaf[0])));
-
- Node* p1 = R.Phi(R.leaf[0], R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
-
- Node* p2 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2, p2));
-
- Node* p3 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p3, p3, R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative_self1) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.self)));
- R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.leaf[0]));
-}
-
-
-TEST(CReducePhi_iterative_self2) {
- ControlReducerTester R;
-
- R.ReducePhiIterative(
- R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.Phi(R.leaf[0], R.self)));
- R.ReducePhiIterative(
- R.leaf[0], R.Phi(R.Phi(R.self, R.leaf[0]), R.Phi(R.self, R.leaf[0])));
-
- Node* p1 = R.Phi(R.leaf[0], R.self);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
-
- Node* p2 = R.Phi(R.self, R.leaf[0]);
- R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2));
-}
-
-
-TEST(EReducePhi1) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3]));
-}
-
-
-TEST(EReducePhi1_dead) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1], R.dead));
- R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2], R.dead));
- R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3], R.dead));
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0]));
- R.ReducePhi(R.leaf[1], R.EffectPhi(R.dead, R.leaf[1]));
- R.ReducePhi(R.leaf[2], R.EffectPhi(R.dead, R.leaf[2]));
- R.ReducePhi(R.leaf[3], R.EffectPhi(R.dead, R.leaf[3]));
-}
-
-
-TEST(EReducePhi1_dead2) {
- ControlReducerTester R;
-
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead, R.dead));
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0], R.dead));
- R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.dead, R.leaf[0]));
-}
-
-
-TEST(CMergeReduce_simple1) {
- ControlReducerTester R;
-
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
- R.ReduceMerge(R.start, merge);
-}
-
-
-TEST(CMergeReduce_simple2) {
- ControlReducerTester R;
-
- Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
- Node* merge2 = R.graph.NewNode(R.common.Merge(1), merge1);
- R.ReduceMerge(merge1, merge2);
- R.ReduceMergeIterative(R.start, merge2);
-}
-
-
-TEST(CMergeReduce_none1) {
- ControlReducerTester R;
-
- Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.start);
- R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_none2) {
- ControlReducerTester R;
-
- Node* t1 = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* t2 = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* merge = R.graph.NewNode(R.common.Merge(2), t1, t2);
- R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_self3) {
- ControlReducerTester R;
-
- Node* merge =
- R.SetSelfReferences(R.graph.NewNode(R.common.Merge(2), R.start, R.self));
- R.ReduceMerge(merge, merge);
-}
-
-
-TEST(CMergeReduce_dead1) {
- ControlReducerTester R;
-
- Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.dead);
- R.ReduceMerge(R.start, merge);
-}
-
-
-TEST(CMergeReduce_dead2) {
- ControlReducerTester R;
-
- Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
- Node* merge2 = R.graph.NewNode(R.common.Merge(2), merge1, R.dead);
- R.ReduceMerge(merge1, merge2);
- R.ReduceMergeIterative(R.start, merge2);
-}
-
-
-TEST(CMergeReduce_dead_rm1a) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- R.ReduceMerge(merge, merge);
- CheckMerge(merge, R.start, R.start);
- }
-}
-
-
-TEST(CMergeReduce_dead_rm1b) {
- ControlReducerTester R;
-
- Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
- Node* f = R.graph.NewNode(R.common.IfTrue(), R.start);
- for (int i = 0; i < 2; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
- for (int j = i + 1; j < 3; j++) {
- merge->ReplaceInput(i, t);
- merge->ReplaceInput(j, f);
- R.ReduceMerge(merge, merge);
- CheckMerge(merge, t, f);
- }
- }
-}
-
-
-TEST(CMergeReduce_dead_rm2) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
- merge->ReplaceInput(i, R.start);
- R.ReduceMerge(R.start, merge);
- }
-}
-
-
-TEST(CLoopReduce_dead_rm1) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* loop = R.graph.NewNode(R.common.Loop(3), R.dead, R.start, R.start);
- R.ReduceMerge(loop, loop);
- CheckLoop(loop, R.start, R.start);
- }
-}
-
-
-TEST(CMergeReduce_edit_phi1) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
- R.leaf[1], R.leaf[2], merge);
- R.ReduceMerge(merge, merge);
- CHECK_EQ(IrOpcode::kPhi, phi->opcode());
- CHECK_EQ(2, phi->op()->ValueInputCount());
- CHECK_EQ(3, phi->InputCount());
- CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
- CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
- CHECK_EQ(merge, phi->InputAt(2));
- }
-}
-
-
-TEST(CMergeReduce_edit_effect_phi1) {
- ControlReducerTester R;
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- Node* phi = R.graph.NewNode(R.common.EffectPhi(3), R.leaf[0], R.leaf[1],
- R.leaf[2], merge);
- R.ReduceMerge(merge, merge);
- CHECK_EQ(IrOpcode::kEffectPhi, phi->opcode());
- CHECK_EQ(0, phi->op()->ValueInputCount());
- CHECK_EQ(2, phi->op()->EffectInputCount());
- CHECK_EQ(3, phi->InputCount());
- CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
- CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
- CHECK_EQ(merge, phi->InputAt(2));
- }
-}
-
-
-static const int kSelectorSize = 4;
-
-// Helper to select K of N nodes according to a mask, useful for the test below.
-struct Selector {
- int mask;
- int count;
- explicit Selector(int m) {
- mask = m;
- count = v8::base::bits::CountPopulation32(m);
- }
- bool is_selected(int i) { return (mask & (1 << i)) != 0; }
- void CheckNode(Node* node, IrOpcode::Value opcode, Node** inputs,
- Node* control) {
- CHECK_EQ(opcode, node->opcode());
- CHECK_EQ(count + (control != NULL ? 1 : 0), node->InputCount());
- int index = 0;
- for (int i = 0; i < kSelectorSize; i++) {
- if (mask & (1 << i)) {
- CHECK_EQ(inputs[i], node->InputAt(index++));
- }
- }
- CHECK_EQ(count, index);
- if (control != NULL) CHECK_EQ(control, node->InputAt(index++));
- }
- int single_index() {
- CHECK_EQ(1, count);
- return WhichPowerOf2(mask);
- }
-};
-
-
-TEST(CMergeReduce_exhaustive_4) {
- ControlReducerTester R;
- Node* controls[] = {
- R.graph.NewNode(R.common.Start(1)), R.graph.NewNode(R.common.Start(2)),
- R.graph.NewNode(R.common.Start(3)), R.graph.NewNode(R.common.Start(4))};
- Node* values[] = {R.jsgraph.Int32Constant(11), R.jsgraph.Int32Constant(22),
- R.jsgraph.Int32Constant(33), R.jsgraph.Int32Constant(44)};
- Node* effects[] = {
- R.jsgraph.Float64Constant(123.4), R.jsgraph.Float64Constant(223.4),
- R.jsgraph.Float64Constant(323.4), R.jsgraph.Float64Constant(423.4)};
-
- for (int mask = 0; mask < (1 << (kSelectorSize - 1)); mask++) {
- // Reduce a single merge with a given mask.
- Node* merge = R.graph.NewNode(R.common.Merge(4), controls[0], controls[1],
- controls[2], controls[3]);
- Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 4), values[0],
- values[1], values[2], values[3], merge);
- Node* ephi = R.graph.NewNode(R.common.EffectPhi(4), effects[0], effects[1],
- effects[2], effects[3], merge);
-
- Node* phi_use =
- R.graph.NewNode(R.common.Phi(kMachAnyTagged, 1), phi, R.start);
- Node* ephi_use = R.graph.NewNode(R.common.EffectPhi(1), ephi, R.start);
-
- Selector selector(mask);
-
- for (int i = 0; i < kSelectorSize; i++) { // set up dead merge inputs.
- if (!selector.is_selected(i)) merge->ReplaceInput(i, R.dead);
- }
-
- Node* result = ControlReducer::ReduceMerge(&R.jsgraph, merge);
-
- int count = selector.count;
- if (count == 0) {
- // result should be dead.
- CHECK_EQ(IrOpcode::kDead, result->opcode());
- } else if (count == 1) {
- // merge should be replaced with one of the controls.
- CHECK_EQ(controls[selector.single_index()], result);
- // Phis should have been directly replaced.
- CHECK_EQ(values[selector.single_index()], phi_use->InputAt(0));
- CHECK_EQ(effects[selector.single_index()], ephi_use->InputAt(0));
- } else {
- // Otherwise, nodes should be edited in place.
- CHECK_EQ(merge, result);
- selector.CheckNode(merge, IrOpcode::kMerge, controls, NULL);
- selector.CheckNode(phi, IrOpcode::kPhi, values, merge);
- selector.CheckNode(ephi, IrOpcode::kEffectPhi, effects, merge);
- CHECK_EQ(phi, phi_use->InputAt(0));
- CHECK_EQ(ephi, ephi_use->InputAt(0));
- CHECK_EQ(count, phi->op()->ValueInputCount());
- CHECK_EQ(count + 1, phi->InputCount());
- CHECK_EQ(count, ephi->op()->EffectInputCount());
- CHECK_EQ(count + 1, ephi->InputCount());
- }
- }
-}
-
-
-TEST(CMergeReduce_edit_many_phis1) {
- ControlReducerTester R;
-
- const int kPhiCount = 10;
- Node* phis[kPhiCount];
-
- for (int i = 0; i < 3; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
- merge->ReplaceInput(i, R.dead);
- for (int j = 0; j < kPhiCount; j++) {
- phis[j] = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
- R.leaf[1], R.leaf[2], merge);
- }
- R.ReduceMerge(merge, merge);
- for (int j = 0; j < kPhiCount; j++) {
- Node* phi = phis[j];
- CHECK_EQ(IrOpcode::kPhi, phi->opcode());
- CHECK_EQ(2, phi->op()->ValueInputCount());
- CHECK_EQ(3, phi->InputCount());
- CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
- CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
- CHECK_EQ(merge, phi->InputAt(2));
- }
- }
-}
-
-
-TEST(CMergeReduce_simple_chain1) {
- ControlReducerTester R;
- for (int i = 0; i < 5; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
- for (int j = 0; j < i; j++) {
- merge = R.graph.NewNode(R.common.Merge(1), merge);
- }
- R.ReduceMergeIterative(R.start, merge);
- }
-}
-
-
-TEST(CMergeReduce_dead_chain1) {
- ControlReducerTester R;
- for (int i = 0; i < 5; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.dead);
- for (int j = 0; j < i; j++) {
- merge = R.graph.NewNode(R.common.Merge(1), merge);
- }
- Node* end = R.graph.NewNode(R.common.End(), merge);
- R.graph.SetEnd(end);
- R.ReduceGraph();
- CHECK(merge->IsDead());
- CHECK(!end->InputAt(0)); // end dies.
- }
-}
-
-
-TEST(CMergeReduce_dead_chain2) {
- ControlReducerTester R;
- for (int i = 0; i < 5; i++) {
- Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
- for (int j = 0; j < i; j++) {
- merge = R.graph.NewNode(R.common.Merge(2), merge, R.dead);
- }
- R.ReduceMergeIterative(R.start, merge);
- }
-}
-
-
-TEST(CBranchReduce_none1) {
- ControlReducerTester R;
- Diamond d(R, R.p0);
- R.ReduceBranch(kUnknown, d.branch);
-}
-
-
-TEST(CBranchReduce_none2) {
- ControlReducerTester R;
- Diamond d1(R, R.p0);
- Diamond d2(R, R.p0);
- d2.chain(d1);
- R.ReduceBranch(kUnknown, d2.branch);
-}
-
-
-TEST(CBranchReduce_true) {
- ControlReducerTester R;
- Node* true_values[] = {
- R.one, R.jsgraph.Int32Constant(2),
- R.jsgraph.Int32Constant(0x7fffffff), R.jsgraph.Constant(1.0),
- R.jsgraph.Constant(22.1), R.jsgraph.TrueConstant()};
-
- for (size_t i = 0; i < arraysize(true_values); i++) {
- Diamond d(R, true_values[i]);
- R.ReduceBranch(kTrue, d.branch);
- }
-}
-
-
-TEST(CBranchReduce_false) {
- ControlReducerTester R;
- Node* false_values[] = {R.zero, R.jsgraph.Constant(0.0),
- R.jsgraph.Constant(-0.0), R.jsgraph.FalseConstant()};
-
- for (size_t i = 0; i < arraysize(false_values); i++) {
- Diamond d(R, false_values[i]);
- R.ReduceBranch(kFalse, d.branch);
- }
-}
-
-
-TEST(CDiamondReduce_true) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CDiamondReduce_false) {
- ControlReducerTester R;
- Diamond d2(R, R.zero);
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_true_false) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- Diamond d2(R, R.zero);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_x_false) {
- ControlReducerTester R;
- Diamond d1(R, R.p0);
- Diamond d2(R, R.zero);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_false_x) {
- ControlReducerTester R;
- Diamond d1(R, R.zero);
- Diamond d2(R, R.p0);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_phi1) {
- ControlReducerTester R;
- Diamond d1(R, R.zero, R.one, R.zero); // foldable branch, phi.
- Diamond d2(R, d1.phi);
- d2.chain(d1);
-
- R.ReduceMergeIterative(R.start, d2.merge);
-}
-
-
-TEST(CChainedDiamondsReduce_phi2) {
- ControlReducerTester R;
- Diamond d1(R, R.p0, R.one, R.one); // redundant phi.
- Diamond d2(R, d1.phi);
- d2.chain(d1);
-
- R.ReduceMergeIterative(d1.merge, d2.merge);
-}
-
-
-TEST(CNestedDiamondsReduce_true_true_false) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- Diamond d2(R, R.zero);
- d2.nest(d1, true);
-
- R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CNestedDiamondsReduce_false_true_false) {
- ControlReducerTester R;
- Diamond d1(R, R.one);
- Diamond d2(R, R.zero);
- d2.nest(d1, false);
-
- R.ReduceMergeIterative(R.start, d1.merge);
-}
-
-
-TEST(CNestedDiamonds_xyz) {
- ControlReducerTester R;
-
- for (int a = 0; a < 2; a++) {
- for (int b = 0; b < 2; b++) {
- for (int c = 0; c < 2; c++) {
- Diamond d1(R, R.jsgraph.Int32Constant(a));
- Diamond d2(R, R.jsgraph.Int32Constant(b));
- d2.nest(d1, c);
-
- R.ReduceMergeIterative(R.start, d1.merge);
- }
- }
- }
-}
-
-
-TEST(CUnusedDiamond1) {
- ControlReducerTester R;
- // if (p0) { } else { }
- Node* branch = R.graph.NewNode(R.common.Branch(), R.p0, R.start);
- Node* if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- Node* if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- Node* merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
- R.ReduceMergeIterative(R.start, merge);
-}
-
-
-TEST(CUnusedDiamond2) {
- ControlReducerTester R;
- // if (p0) { } else { }
- Node* branch = R.graph.NewNode(R.common.Branch(), R.p0, R.start);
- Node* if_true = R.graph.NewNode(R.common.IfTrue(), branch);
- Node* if_false = R.graph.NewNode(R.common.IfFalse(), branch);
- Node* merge = R.graph.NewNode(R.common.Merge(2), if_false, if_true);
- R.ReduceMergeIterative(R.start, merge);
-}
-
-
-TEST(CDeadLoop1) {
- ControlReducerTester R;
-
- Node* loop = R.graph.NewNode(R.common.Loop(1), R.start);
- Branch b(R, R.p0, loop);
- loop->ReplaceInput(0, b.if_true); // loop is not connected to start.
- Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, b.if_false);
- R.ReduceMergeIterative(R.start, merge);
-
- DeadChecker dead(&R.graph);
- dead.Check(b.if_true);
- dead.Check(b.if_false);
- dead.Check(b.branch);
- dead.Check(loop);
-}
-
-
-TEST(CDeadLoop2) {
- ControlReducerTester R;
-
- While w(R, R.p0);
- Diamond d(R, R.zero);
- // if (0) { while (p0) ; } else { }
- w.branch->ReplaceInput(1, d.if_true);
- d.merge->ReplaceInput(0, w.exit);
-
- R.ReduceMergeIterative(R.start, d.merge);
-
- DeadChecker dead(&R.graph);
- dead.Check(d);
- dead.Check(w.loop);
-}
-
-
-TEST(Return1) {
- ControlReducerTester R;
- Node* ret = R.Return(R.one, R.start, R.start);
- R.ReduceGraph();
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.one, R.start, R.start);
-}
-
-
-TEST(Return2) {
- ControlReducerTester R;
- Diamond d(R, R.one);
- Node* ret = R.Return(R.half, R.start, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d.branch);
- dead.Check(d.if_true);
- dead.Check(d.if_false);
- dead.Check(d.merge);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_true1) {
- ControlReducerTester R;
- Diamond d(R, R.one, R.half, R.zero);
- Node* ret = R.Return(d.phi, R.start, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d.branch);
- dead.Check(d.if_true);
- dead.Check(d.if_false);
- dead.Check(d.merge);
- dead.Check(d.phi);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_false1) {
- ControlReducerTester R;
- Diamond d(R, R.zero, R.one, R.half);
- Node* ret = R.Return(d.phi, R.start, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d.branch);
- dead.Check(d.if_true);
- dead.Check(d.if_false);
- dead.Check(d.merge);
- dead.Check(d.phi);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.half, R.start, R.start);
-}
-
-
-TEST(Return_effect1) {
- ControlReducerTester R;
- Diamond d(R, R.one);
- Node* e1 = R.jsgraph.Float64Constant(-100.1);
- Node* e2 = R.jsgraph.Float64Constant(+100.1);
- Node* effect = R.graph.NewNode(R.common.EffectPhi(2), e1, e2, d.merge);
- Node* ret = R.Return(R.p0, effect, d.merge);
- R.ReduceGraph();
-
- DeadChecker dead(&R.graph);
- dead.Check(d);
- dead.Check(effect);
-
- CheckInputs(R.graph.end(), ret);
- CheckInputs(ret, R.p0, e1, R.start);
-}
-
-
-TEST(Return_nested_diamonds1) {
- ControlReducerTester R;
- Diamond d2(R, R.p0, R.one, R.zero);
- Diamond d3(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.p0, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // nothing should happen.
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge);
- CheckInputs(d1.merge, d2.merge, d3.merge);
-
- DeadChecker dead(&R.graph);
- dead.CheckLive(d2);
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds1_dead1) {
- ControlReducerTester R;
- Diamond d2(R, R.p0); // dead diamond
- Diamond d3(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.p0, R.one, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph();
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, R.one, d3.phi, d1.merge);
- CheckInputs(d1.merge, d1.if_true, d3.merge);
-
- DeadChecker dead(&R.graph);
- dead.Check(d2); // d2 was a dead diamond.
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds1_dead2) {
- ControlReducerTester R;
- Diamond d2(R, R.p0); // dead diamond
- Diamond d3(R, R.p0); // dead diamond
- Diamond d1(R, R.p0, R.one, R.zero);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph();
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, R.one, R.zero, d1.merge);
- CheckInputs(d1.merge, d1.if_true, d1.if_false);
-
- DeadChecker dead(&R.graph);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true1) {
- ControlReducerTester R;
- Diamond d2(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.one, d2.phi, R.zero);
- Diamond d3(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, d2.phi, R.start, d2.merge);
- CheckInputs(d2.branch, R.p0, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.CheckLive(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_false1) {
- ControlReducerTester R;
- Diamond d3(R, R.p0, R.one, R.zero);
- Diamond d1(R, R.zero, R.one, d3.phi);
- Diamond d2(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded false.
-
- CheckInputs(ret, d3.phi, R.start, d3.merge);
- CheckInputs(d3.branch, R.p0, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_true1) {
- ControlReducerTester R;
- Diamond d1(R, R.one, R.one, R.zero);
- Diamond d2(R, R.one);
- Diamond d3(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 and d2 both get folded true.
-
- CheckInputs(ret, R.one, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_false1) {
- ControlReducerTester R;
- Diamond d1(R, R.one, R.one, R.zero);
- Diamond d2(R, R.zero);
- Diamond d3(R, R.p0);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true and d2 gets folded false.
-
- CheckInputs(ret, R.one, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.p0, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.p0, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // nothing should happen.
-
- CheckInputs(ret, d1.phi, R.start, d1.merge);
- CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge);
- CheckInputs(d1.merge, d2.merge, d3.merge);
-
- DeadChecker dead(&R.graph);
- dead.CheckLive(d2);
- dead.CheckLive(d3);
-}
-
-
-TEST(Return_nested_diamonds_true2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.p0, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.one, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, d2.phi, R.start, d2.merge);
- CheckInputs(d2.branch, R.p0, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.CheckLive(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_true2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.one, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.one, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, x2, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
-
-
-TEST(Return_nested_diamonds_true_false2) {
- ControlReducerTester R;
- Node* x2 = R.jsgraph.Float64Constant(11.1);
- Node* y2 = R.jsgraph.Float64Constant(22.2);
- Node* x3 = R.jsgraph.Float64Constant(33.3);
- Node* y3 = R.jsgraph.Float64Constant(44.4);
-
- Diamond d2(R, R.zero, x2, y2);
- Diamond d3(R, R.p0, x3, y3);
- Diamond d1(R, R.one, d2.phi, d3.phi);
-
- d2.nest(d1, true);
- d3.nest(d1, false);
-
- Node* ret = R.Return(d1.phi, R.start, d1.merge);
-
- R.ReduceGraph(); // d1 gets folded true.
-
- CheckInputs(ret, y2, R.start, R.start);
-
- DeadChecker dead(&R.graph);
- dead.Check(d1);
- dead.Check(d2);
- dead.Check(d3);
-}
diff --git a/deps/v8/test/cctest/compiler/test-js-constant-cache.cc b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
index 630f911c5e..8774a9a9e3 100644
--- a/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
+++ b/deps/v8/test/cctest/compiler/test-js-constant-cache.cc
@@ -21,7 +21,7 @@ class JSCacheTesterHelper {
: main_graph_(zone),
main_common_(zone),
main_javascript_(zone),
- main_typer_(isolate, &main_graph_, MaybeHandle<Context>()),
+ main_typer_(isolate, &main_graph_),
main_machine_(zone) {}
Graph main_graph_;
CommonOperatorBuilder main_common_;
@@ -41,7 +41,7 @@ class JSConstantCacheTester : public HandleAndZoneScope,
JSGraph(main_isolate(), &main_graph_, &main_common_, &main_javascript_,
&main_machine_) {
main_graph_.SetStart(main_graph_.NewNode(common()->Start(0)));
- main_graph_.SetEnd(main_graph_.NewNode(common()->End()));
+ main_graph_.SetEnd(main_graph_.NewNode(common()->End(1)));
main_typer_.Run();
}
@@ -335,7 +335,7 @@ TEST(JSGraph_GetCachedNodes_int32) {
25, 15, 30, 31, 45, 46, 47, 48};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Int32Constant(constants[i]);
@@ -357,7 +357,7 @@ TEST(JSGraph_GetCachedNodes_float64) {
11, 11, -33.3, -33.3, -22, -11};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Float64Constant(constants[i]);
@@ -379,7 +379,7 @@ TEST(JSGraph_GetCachedNodes_int64) {
19, 20, 20, 21, 21, 22, 23, 24, 25};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Int64Constant(constants[i]);
@@ -401,7 +401,7 @@ TEST(JSGraph_GetCachedNodes_number) {
11, 11, -33.3, -33.3, -22, -11};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.Constant(constants[i]);
@@ -428,7 +428,7 @@ TEST(JSGraph_GetCachedNodes_external) {
ExternalReference::address_of_one_half()};
for (size_t i = 0; i < arraysize(constants); i++) {
- int count_before = T.graph()->NodeCount();
+ size_t count_before = T.graph()->NodeCount();
NodeVector nodes_before(T.main_zone());
T.GetCachedNodes(&nodes_before);
Node* n = T.ExternalConstant(constants[i]);
diff --git a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
index 2450e7cf57..328b0aefdd 100644
--- a/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
+++ b/deps/v8/test/cctest/compiler/test-js-context-specialization.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "src/compiler/js-context-specialization.h"
+#include "src/compiler/js-graph.h"
#include "src/compiler/js-operator.h"
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
@@ -22,8 +23,11 @@ class ContextSpecializationTester : public HandleAndZoneScope {
javascript_(main_zone()),
machine_(main_zone()),
simplified_(main_zone()),
- jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_) {}
+ jsgraph_(main_isolate(), graph(), common(), &javascript_, &machine_),
+ reducer_(main_zone(), graph()),
+ spec_(&reducer_, jsgraph(), MaybeHandle<Context>()) {}
+ JSContextSpecialization* spec() { return &spec_; }
Factory* factory() { return main_isolate()->factory(); }
CommonOperatorBuilder* common() { return &common_; }
JSOperatorBuilder* javascript() { return &javascript_; }
@@ -38,6 +42,8 @@ class ContextSpecializationTester : public HandleAndZoneScope {
MachineOperatorBuilder machine_;
SimplifiedOperatorBuilder simplified_;
JSGraph jsgraph_;
+ GraphReducer reducer_;
+ JSContextSpecialization spec_;
};
@@ -60,13 +66,12 @@ TEST(ReduceJSLoadContext) {
Node* const_context = t.jsgraph()->Constant(native);
Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
- JSContextSpecializer spec(t.jsgraph());
{
// Mutable slot, constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
const_context, const_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -74,7 +79,7 @@ TEST(ReduceJSLoadContext) {
// Mutable slot, non-constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, 0, false),
param_context, param_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -83,11 +88,11 @@ TEST(ReduceJSLoadContext) {
Node* load = t.graph()->NewNode(
t.javascript()->LoadContext(2, Context::GLOBAL_EVAL_FUN_INDEX, false),
deep_const_context, deep_const_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
- HeapObjectMatcher<Context> match(new_context_input);
+ HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value().handle());
ContextAccess access = OpParameter<ContextAccess>(r.replacement());
CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
@@ -99,11 +104,11 @@ TEST(ReduceJSLoadContext) {
// Immutable slot, constant context, depth = 0 => specialize.
Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true),
const_context, const_context, start);
- Reduction r = spec.ReduceJSLoadContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
CHECK(r.replacement() != load);
- HeapObjectMatcher<Object> match(r.replacement());
+ HeapObjectMatcher match(r.replacement());
CHECK(match.HasValue());
CHECK_EQ(*expected, *match.Value().handle());
}
@@ -132,13 +137,12 @@ TEST(ReduceJSStoreContext) {
Node* const_context = t.jsgraph()->Constant(native);
Node* deep_const_context = t.jsgraph()->Constant(subcontext2);
Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
- JSContextSpecializer spec(t.jsgraph());
{
// Mutable slot, constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
const_context, const_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -146,7 +150,7 @@ TEST(ReduceJSStoreContext) {
// Mutable slot, non-constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, 0),
param_context, param_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -154,7 +158,7 @@ TEST(ReduceJSStoreContext) {
// Immutable slot, constant context, depth = 0 => do nothing.
Node* load = t.graph()->NewNode(t.javascript()->StoreContext(0, slot),
const_context, const_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(!r.Changed());
}
@@ -163,11 +167,11 @@ TEST(ReduceJSStoreContext) {
Node* load = t.graph()->NewNode(
t.javascript()->StoreContext(2, Context::GLOBAL_EVAL_FUN_INDEX),
deep_const_context, deep_const_context, start);
- Reduction r = spec.ReduceJSStoreContext(load);
+ Reduction r = t.spec()->Reduce(load);
CHECK(r.Changed());
Node* new_context_input = NodeProperties::GetValueInput(r.replacement(), 0);
CHECK_EQ(IrOpcode::kHeapConstant, new_context_input->opcode());
- HeapObjectMatcher<Context> match(new_context_input);
+ HeapObjectMatcher match(new_context_input);
CHECK_EQ(*native, *match.Value().handle());
ContextAccess access = OpParameter<ContextAccess>(r.replacement());
CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
@@ -197,7 +201,6 @@ TEST(SpecializeToContext) {
Node* const_context = t.jsgraph()->Constant(native);
Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start);
- JSContextSpecializer spec(t.jsgraph());
{
// Check that specialization replaces values and forwards effects
@@ -222,7 +225,7 @@ TEST(SpecializeToContext) {
Node* ret =
t.graph()->NewNode(t.common()->Return(), add, effect_use, start);
- Node* end = t.graph()->NewNode(t.common()->End(), ret);
+ Node* end = t.graph()->NewNode(t.common()->End(1), ret);
USE(end);
t.graph()->SetEnd(end);
@@ -231,7 +234,9 @@ TEST(SpecializeToContext) {
CheckEffectInput(load, effect_use);
// Perform the reduction on the entire graph.
- GraphReducer graph_reducer(t.graph(), t.main_zone());
+ GraphReducer graph_reducer(t.main_zone(), t.graph());
+ JSContextSpecialization spec(&graph_reducer, t.jsgraph(),
+ MaybeHandle<Context>());
graph_reducer.AddReducer(&spec);
graph_reducer.ReduceGraph();
@@ -242,7 +247,7 @@ TEST(SpecializeToContext) {
CHECK_EQ(other_load, other_use->InputAt(0));
Node* replacement = value_use->InputAt(0);
- HeapObjectMatcher<Object> match(replacement);
+ HeapObjectMatcher match(replacement);
CHECK(match.HasValue());
CHECK_EQ(*expected, *match.Value().handle());
}
diff --git a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
index 92fdb6e874..e512de89b2 100644
--- a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
@@ -38,10 +38,10 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
simplified(main_zone()),
common(main_zone()),
graph(main_zone()),
- typer(main_isolate(), &graph, MaybeHandle<Context>()),
+ typer(main_isolate(), &graph),
context_node(NULL) {
graph.SetStart(graph.NewNode(common.Start(num_parameters)));
- graph.SetEnd(graph.NewNode(common.End()));
+ graph.SetEnd(graph.NewNode(common.End(1)));
typer.Run();
}
@@ -79,17 +79,19 @@ class JSTypedLoweringTester : public HandleAndZoneScope {
Node* locals = graph.NewNode(common.StateValues(0));
Node* stack = graph.NewNode(common.StateValues(0));
- Node* state_node =
- graph.NewNode(common.FrameState(JS_FRAME, BailoutId::None(),
- OutputFrameStateCombine::Ignore()),
- parameters, locals, stack, context, UndefinedConstant());
+ Node* state_node = graph.NewNode(
+ common.FrameState(BailoutId::None(), OutputFrameStateCombine::Ignore(),
+ nullptr),
+ parameters, locals, stack, context, UndefinedConstant());
return state_node;
}
Node* reduce(Node* node) {
JSGraph jsgraph(main_isolate(), &graph, &common, &javascript, &machine);
- JSTypedLowering reducer(&jsgraph, main_zone());
+ // TODO(titzer): mock the GraphReducer here for better unit testing.
+ GraphReducer graph_reducer(main_zone(), &graph);
+ JSTypedLowering reducer(&graph_reducer, &jsgraph, main_zone());
Reduction reduction = reducer.Reduce(node);
if (reduction.Changed()) return reduction.replacement();
return node;
@@ -318,11 +320,11 @@ class JSBitwiseShiftTypedLoweringTester : public JSTypedLoweringTester {
: JSTypedLoweringTester(), language_mode_(language_mode) {
int i = 0;
set(i++, javascript.ShiftLeft(language_mode_), true);
- set(i++, machine.Word32Shl(), false);
+ set(i++, simplified.NumberShiftLeft(), false);
set(i++, javascript.ShiftRight(language_mode_), true);
- set(i++, machine.Word32Sar(), false);
+ set(i++, simplified.NumberShiftRight(), false);
set(i++, javascript.ShiftRightLogical(language_mode_), false);
- set(i++, machine.Word32Shr(), false);
+ set(i++, simplified.NumberShiftRightLogical(), false);
}
static const int kNumberOps = 6;
const Operator* ops[kNumberOps];
@@ -362,14 +364,7 @@ TEST(Int32BitwiseShifts) {
Node* r1 = r->InputAt(1);
CheckToI32(p0, r0, R.signedness[k]);
-
- if (r1->opcode() == IrOpcode::kWord32And) {
- R.CheckPureBinop(IrOpcode::kWord32And, r1);
- CheckToI32(p1, r1->InputAt(0), R.signedness[k + 1]);
- R.CheckInt32Constant(0x1F, r1->InputAt(1));
- } else {
- CheckToI32(p1, r1, R.signedness[k]);
- }
+ CheckToI32(p1, r1, false);
}
}
}
@@ -460,8 +455,9 @@ TEST(JSToNumber_replacement) {
for (size_t i = 0; i < arraysize(types); i++) {
Node* n = R.Parameter(types[i]);
- Node* c = R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
- R.start(), R.start());
+ Node* c =
+ R.graph.NewNode(R.javascript.ToNumber(), n, R.context(),
+ R.EmptyFrameState(R.context()), R.start(), R.start());
Node* effect_use = R.UseForEffect(c);
Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
@@ -688,18 +684,20 @@ TEST_WITH_STRONG(MixedComparison1) {
for (size_t j = 0; j < arraysize(types); j++) {
Node* p1 = R.Parameter(types[j], 1);
{
- Node* cmp = R.Binop(R.javascript.LessThan(language_mode), p0, p1);
+ const Operator* less_than = R.javascript.LessThan(language_mode);
+ Node* cmp = R.Binop(less_than, p0, p1);
Node* r = R.reduce(cmp);
-
- if (!types[i]->Maybe(Type::String()) ||
- !types[j]->Maybe(Type::String())) {
- if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
- R.CheckPureBinop(R.simplified.StringLessThan(), r);
- } else {
- R.CheckPureBinop(R.simplified.NumberLessThan(), r);
- }
+ if (types[i]->Is(Type::String()) && types[j]->Is(Type::String())) {
+ R.CheckPureBinop(R.simplified.StringLessThan(), r);
+ } else if ((types[i]->Is(Type::Number()) &&
+ types[j]->Is(Type::Number())) ||
+ (!is_strong(language_mode) &&
+ (!types[i]->Maybe(Type::String()) ||
+ !types[j]->Maybe(Type::String())))) {
+ R.CheckPureBinop(R.simplified.NumberLessThan(), r);
} else {
- CHECK_EQ(cmp, r); // No reduction of mixed types.
+ // No reduction of mixed types.
+ CHECK_EQ(r->op(), less_than);
}
}
}
@@ -708,8 +706,6 @@ TEST_WITH_STRONG(MixedComparison1) {
TEST_WITH_STRONG(RemoveToNumberEffects) {
- FLAG_turbo_deoptimization = true;
-
JSTypedLoweringTester R;
Node* effect_use = NULL;
@@ -721,27 +717,16 @@ TEST_WITH_STRONG(RemoveToNumberEffects) {
switch (i) {
case 0:
- if (FLAG_turbo_deoptimization) {
- DCHECK(OperatorProperties::GetFrameStateInputCount(
- R.javascript.ToNumber()) == 1);
- effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(),
- frame_state, ton, R.start());
- } else {
+ DCHECK(OperatorProperties::GetFrameStateInputCount(
+ R.javascript.ToNumber()) == 1);
effect_use = R.graph.NewNode(R.javascript.ToNumber(), p0, R.context(),
- ton, R.start());
- }
+ frame_state, ton, R.start());
break;
case 1:
- if (FLAG_turbo_deoptimization) {
- DCHECK(OperatorProperties::GetFrameStateInputCount(
- R.javascript.ToNumber()) == 1);
- effect_use =
- R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(),
- frame_state, ton, R.start());
- } else {
- effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton,
- R.context(), ton, R.start());
- }
+ DCHECK(OperatorProperties::GetFrameStateInputCount(
+ R.javascript.ToNumber()) == 1);
+ effect_use = R.graph.NewNode(R.javascript.ToNumber(), ton, R.context(),
+ frame_state, ton, R.start());
break;
case 2:
effect_use = R.graph.NewNode(R.common.EffectPhi(1), ton, R.start());
@@ -950,8 +935,6 @@ TEST(OrderNumberBinopEffects1) {
R.simplified.NumberMultiply(),
R.javascript.Divide(LanguageMode::SLOPPY),
R.simplified.NumberDivide(),
- R.javascript.Modulus(LanguageMode::SLOPPY),
- R.simplified.NumberModulus(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -982,8 +965,6 @@ TEST(OrderNumberBinopEffects2) {
R.simplified.NumberMultiply(),
R.javascript.Divide(LanguageMode::SLOPPY),
R.simplified.NumberDivide(),
- R.javascript.Modulus(LanguageMode::SLOPPY),
- R.simplified.NumberModulus(),
};
for (size_t j = 0; j < arraysize(ops); j += 2) {
diff --git a/deps/v8/test/cctest/compiler/test-jump-threading.cc b/deps/v8/test/cctest/compiler/test-jump-threading.cc
index e0a4a2fc62..9fa3c9f28a 100644
--- a/deps/v8/test/cctest/compiler/test-jump-threading.cc
+++ b/deps/v8/test/cctest/compiler/test-jump-threading.cc
@@ -85,7 +85,7 @@ class TestCode : public HandleAndZoneScope {
if (current_ == NULL) {
current_ = new (main_zone())
InstructionBlock(main_zone(), rpo_number_, RpoNumber::Invalid(),
- RpoNumber::Invalid(), deferred);
+ RpoNumber::Invalid(), deferred, false);
blocks_.push_back(current_);
sequence_.StartBlock(rpo_number_);
}
diff --git a/deps/v8/test/cctest/compiler/test-linkage.cc b/deps/v8/test/cctest/compiler/test-linkage.cc
index 212ff3a8f2..252c43133e 100644
--- a/deps/v8/test/cctest/compiler/test-linkage.cc
+++ b/deps/v8/test/cctest/compiler/test-linkage.cc
@@ -34,8 +34,8 @@ static Handle<JSFunction> Compile(const char* source) {
->NewStringFromUtf8(CStrVector(source))
.ToHandleChecked();
Handle<SharedFunctionInfo> shared_function = Compiler::CompileScript(
- source_code, Handle<String>(), 0, 0, false, false, Handle<Object>(),
- Handle<Context>(isolate->native_context()), NULL, NULL,
+ source_code, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
+ Handle<Object>(), Handle<Context>(isolate->native_context()), NULL, NULL,
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
shared_function, isolate->native_context());
@@ -114,5 +114,4 @@ TEST(TestLinkageStubCall) {
// TODO(titzer): test linkage creation for outgoing stub calls.
}
-
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-loop-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-analysis.cc
index 06682ef5a9..6560ae337b 100644
--- a/deps/v8/test/cctest/compiler/test-loop-analysis.cc
+++ b/deps/v8/test/cctest/compiler/test-loop-analysis.cc
@@ -41,7 +41,7 @@ class LoopFinderTester : HandleAndZoneScope {
graph(main_zone()),
jsgraph(main_isolate(), &graph, &common, NULL, NULL),
start(graph.NewNode(common.Start(1))),
- end(graph.NewNode(common.End(), start)),
+ end(graph.NewNode(common.End(1), start)),
p0(graph.NewNode(common.Parameter(0), start)),
zero(jsgraph.Int32Constant(0)),
one(jsgraph.OneConstant()),
diff --git a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
index 5f9820c72a..ad05273995 100644
--- a/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
+++ b/deps/v8/test/cctest/compiler/test-loop-assignment-analysis.cc
@@ -51,7 +51,7 @@ struct TestHelper : public HandleAndZoneScope {
i::Variable* var = scope->Lookup(name);
CHECK(var);
- if (var->location() == Variable::UNALLOCATED) {
+ if (var->location() == VariableLocation::UNALLOCATED) {
CHECK_EQ(0, expected);
} else {
CHECK(var->IsStackAllocated());
diff --git a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
index beedc459e7..299f0c02ab 100644
--- a/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
+++ b/deps/v8/test/cctest/compiler/test-machine-operator-reducer.cc
@@ -60,7 +60,7 @@ class ReducerTester : public HandleAndZoneScope {
common(main_zone()),
graph(main_zone()),
javascript(main_zone()),
- typer(isolate, &graph, MaybeHandle<Context>()),
+ typer(isolate, &graph),
jsgraph(isolate, &graph, &common, &javascript, &machine),
maxuint32(Constant<int32_t>(kMaxUInt32)) {
Node* s = graph.NewNode(common.Start(num_parameters));
diff --git a/deps/v8/test/cctest/compiler/test-osr.cc b/deps/v8/test/cctest/compiler/test-osr.cc
index d2171188f8..80dbccc633 100644
--- a/deps/v8/test/cctest/compiler/test-osr.cc
+++ b/deps/v8/test/cctest/compiler/test-osr.cc
@@ -51,7 +51,7 @@ class OsrDeconstructorTester : public HandleAndZoneScope {
jsgraph(main_isolate(), &graph, &common, NULL, NULL),
start(graph.NewNode(common.Start(1))),
p0(graph.NewNode(common.Parameter(0), start)),
- end(graph.NewNode(common.End(), start)),
+ end(graph.NewNode(common.End(1), start)),
osr_normal_entry(graph.NewNode(common.OsrNormalEntry(), start, start)),
osr_loop_entry(graph.NewNode(common.OsrLoopEntry(), start, start)),
self(graph.NewNode(common.Int32Constant(0xaabbccdd))) {
@@ -165,30 +165,6 @@ TEST(Deconstruct_osr1) {
}
-TEST(Deconstruct_osr1_type) {
- OsrDeconstructorTester T(1);
-
- Node* loop = T.NewOsrLoop(1);
- Node* osr_phi =
- T.NewOsrPhi(loop, T.jsgraph.OneConstant(), 0, T.jsgraph.ZeroConstant());
- Type* type = Type::Signed32();
- NodeProperties::SetBounds(osr_phi, Bounds(type, type));
-
- Node* ret = T.graph.NewNode(T.common.Return(), osr_phi, T.start, loop);
- T.graph.SetEnd(ret);
-
- OsrHelper helper(0, 0);
- helper.Deconstruct(&T.jsgraph, &T.common, T.main_zone());
-
- CHECK_EQ(type, NodeProperties::GetBounds(T.osr_values[0]).lower);
- CHECK_EQ(type, NodeProperties::GetBounds(T.osr_values[0]).upper);
-
- CheckInputs(loop, T.start, loop);
- CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), loop);
- CheckInputs(ret, osr_phi, T.start, loop);
-}
-
-
TEST(Deconstruct_osr_remove_prologue) {
OsrDeconstructorTester T(1);
Diamond d(&T.graph, &T.common, T.p0);
@@ -370,14 +346,14 @@ TEST(Deconstruct_osr_nested1) {
Node* outer_phi = outer.Phi(T.p0, T.p0, nullptr);
outer.branch->ReplaceInput(0, outer_phi);
- Node* osr_phi = inner.Phi(T.jsgraph.OneConstant(), T.osr_values[0],
- T.jsgraph.ZeroConstant());
+ Node* osr_phi = inner.Phi(T.jsgraph.TrueConstant(), T.osr_values[0],
+ T.jsgraph.FalseConstant());
inner.branch->ReplaceInput(0, osr_phi);
outer_phi->ReplaceInput(1, osr_phi);
Node* ret =
T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
- Node* end = T.graph.NewNode(T.common.End(), ret);
+ Node* end = T.graph.NewNode(T.common.End(1), ret);
T.graph.SetEnd(end);
T.DeconstructOsr();
@@ -385,7 +361,7 @@ TEST(Deconstruct_osr_nested1) {
// Check structure of deconstructed graph.
// Check inner OSR loop is directly connected to start.
CheckInputs(inner.loop, T.start, inner.if_true);
- CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop);
+ CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.FalseConstant(), inner.loop);
// Check control transfer to copy of outer loop.
Node* new_outer_loop = FindSuccessor(inner.exit, IrOpcode::kLoop);
@@ -412,8 +388,8 @@ TEST(Deconstruct_osr_nested1) {
Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop);
Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi);
- CheckInputs(new_inner_phi, T.jsgraph.OneConstant(), T.jsgraph.ZeroConstant(),
- new_inner_loop);
+ CheckInputs(new_inner_phi, T.jsgraph.TrueConstant(),
+ T.jsgraph.FalseConstant(), new_inner_loop);
CheckInputs(new_outer_phi, osr_phi, new_inner_phi, new_outer_loop);
}
@@ -429,11 +405,11 @@ TEST(Deconstruct_osr_nested2) {
Node* outer_phi = outer.Phi(T.p0, T.p0, T.p0);
outer.branch->ReplaceInput(0, outer_phi);
- Node* osr_phi = inner.Phi(T.jsgraph.OneConstant(), T.osr_values[0],
- T.jsgraph.ZeroConstant());
+ Node* osr_phi = inner.Phi(T.jsgraph.TrueConstant(), T.osr_values[0],
+ T.jsgraph.FalseConstant());
inner.branch->ReplaceInput(0, osr_phi);
outer_phi->ReplaceInput(1, osr_phi);
- outer_phi->ReplaceInput(2, T.jsgraph.ZeroConstant());
+ outer_phi->ReplaceInput(2, T.jsgraph.FalseConstant());
Node* x_branch = T.graph.NewNode(T.common.Branch(), osr_phi, inner.exit);
Node* x_true = T.graph.NewNode(T.common.IfTrue(), x_branch);
@@ -444,7 +420,7 @@ TEST(Deconstruct_osr_nested2) {
Node* ret =
T.graph.NewNode(T.common.Return(), outer_phi, T.start, outer.exit);
- Node* end = T.graph.NewNode(T.common.End(), ret);
+ Node* end = T.graph.NewNode(T.common.End(1), ret);
T.graph.SetEnd(end);
T.DeconstructOsr();
@@ -452,7 +428,7 @@ TEST(Deconstruct_osr_nested2) {
// Check structure of deconstructed graph.
// Check inner OSR loop is directly connected to start.
CheckInputs(inner.loop, T.start, inner.if_true);
- CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.ZeroConstant(), inner.loop);
+ CheckInputs(osr_phi, T.osr_values[0], T.jsgraph.FalseConstant(), inner.loop);
// Check control transfer to copy of outer loop.
Node* new_merge = FindSuccessor(x_true, IrOpcode::kMerge);
@@ -465,7 +441,7 @@ TEST(Deconstruct_osr_nested2) {
CHECK_NE(new_outer_phi, outer_phi);
Node* new_entry_phi = FindSuccessor(new_merge, IrOpcode::kPhi);
- CheckInputs(new_entry_phi, osr_phi, T.jsgraph.ZeroConstant(), new_merge);
+ CheckInputs(new_entry_phi, osr_phi, T.jsgraph.FalseConstant(), new_merge);
CHECK_EQ(new_merge, new_outer_loop->InputAt(0));
@@ -486,10 +462,10 @@ TEST(Deconstruct_osr_nested2) {
Node* new_inner_loop = FindSuccessor(new_outer_if_true, IrOpcode::kLoop);
Node* new_inner_phi = FindSuccessor(new_inner_loop, IrOpcode::kPhi);
- CheckInputs(new_inner_phi, T.jsgraph.OneConstant(), T.jsgraph.ZeroConstant(),
- new_inner_loop);
+ CheckInputs(new_inner_phi, T.jsgraph.TrueConstant(),
+ T.jsgraph.FalseConstant(), new_inner_loop);
CheckInputs(new_outer_phi, new_entry_phi, new_inner_phi,
- T.jsgraph.ZeroConstant(), new_outer_loop);
+ T.jsgraph.FalseConstant(), new_outer_loop);
}
@@ -523,8 +499,8 @@ TEST(Deconstruct_osr_nested3) {
// middle loop.
Node* loop1 = T.graph.NewNode(T.common.Loop(2), loop0.if_true, T.self);
loop1->ReplaceInput(0, loop0.if_true);
- Node* loop1_phi =
- T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), loop0_cntr, loop0_cntr);
+ Node* loop1_phi = T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), loop0_cntr,
+ loop0_cntr, loop1);
// innermost (OSR) loop.
While loop2(T, T.p0, true, 1);
@@ -549,7 +525,7 @@ TEST(Deconstruct_osr_nested3) {
Node* ret =
T.graph.NewNode(T.common.Return(), loop0_cntr, T.start, loop0.exit);
- Node* end = T.graph.NewNode(T.common.End(), ret);
+ Node* end = T.graph.NewNode(T.common.End(1), ret);
T.graph.SetEnd(end);
T.DeconstructOsr();
diff --git a/deps/v8/test/cctest/compiler/test-pipeline.cc b/deps/v8/test/cctest/compiler/test-pipeline.cc
index b67af6ecf7..84550d502a 100644
--- a/deps/v8/test/cctest/compiler/test-pipeline.cc
+++ b/deps/v8/test/cctest/compiler/test-pipeline.cc
@@ -5,23 +5,18 @@
#include "src/v8.h"
#include "test/cctest/cctest.h"
-#include "src/ast-numbering.h"
#include "src/compiler.h"
#include "src/compiler/pipeline.h"
#include "src/handles.h"
#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
using namespace v8::internal;
using namespace v8::internal::compiler;
-TEST(PipelineAdd) {
- HandleAndZoneScope handles;
- const char* source = "(function(a,b) { return a + b; })";
+static void RunPipeline(Zone* zone, const char* source) {
Handle<JSFunction> function = v8::Utils::OpenHandle(
*v8::Handle<v8::Function>::Cast(CompileRun(source)));
- ParseInfo parse_info(handles.main_zone(), function);
+ ParseInfo parse_info(zone, function);
CHECK(Compiler::ParseAndAnalyze(&parse_info));
CompilationInfo info(&parse_info);
@@ -34,3 +29,17 @@ TEST(PipelineAdd) {
USE(pipeline);
#endif
}
+
+
+TEST(PipelineTyped) {
+ HandleAndZoneScope handles;
+ FLAG_turbo_types = true;
+ RunPipeline(handles.main_zone(), "(function(a,b) { return a + b; })");
+}
+
+
+TEST(PipelineGeneric) {
+ HandleAndZoneScope handles;
+ FLAG_turbo_types = false;
+ RunPipeline(handles.main_zone(), "(function(a,b) { return a + b; })");
+}
diff --git a/deps/v8/test/cctest/compiler/test-representation-change.cc b/deps/v8/test/cctest/compiler/test-representation-change.cc
index 55f054a74b..216f9fd847 100644
--- a/deps/v8/test/cctest/compiler/test-representation-change.cc
+++ b/deps/v8/test/cctest/compiler/test-representation-change.cc
@@ -69,7 +69,7 @@ class RepresentationChangerTester : public HandleAndZoneScope,
}
void CheckHeapConstant(Node* n, HeapObject* expected) {
- HeapObjectMatcher<HeapObject> m(n);
+ HeapObjectMatcher m(n);
CHECK(m.HasValue());
CHECK_EQ(expected, *m.Value().handle());
}
@@ -100,9 +100,9 @@ class RepresentationChangerTester : public HandleAndZoneScope,
CHECK_EQ(n, c);
}
};
-}
-}
-} // namespace v8::internal::compiler
+} // namespace compiler
+} // namespace internal
+} // namespace v8
static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64,
diff --git a/deps/v8/test/cctest/compiler/test-run-deopt.cc b/deps/v8/test/cctest/compiler/test-run-deopt.cc
index 14c024cdbc..d895924324 100644
--- a/deps/v8/test/cctest/compiler/test-run-deopt.cc
+++ b/deps/v8/test/cctest/compiler/test-run-deopt.cc
@@ -7,13 +7,12 @@
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/function-tester.h"
-using namespace v8;
using namespace v8::internal;
using namespace v8::internal::compiler;
#if V8_TURBOFAN_TARGET
-static void IsOptimized(const FunctionCallbackInfo<v8::Value>& args) {
+static void IsOptimized(const v8::FunctionCallbackInfo<v8::Value>& args) {
JavaScriptFrameIterator it(CcTest::i_isolate());
JavaScriptFrame* frame = it.frame();
return args.GetReturnValue().Set(frame->is_optimized());
@@ -21,56 +20,99 @@ static void IsOptimized(const FunctionCallbackInfo<v8::Value>& args) {
static void InstallIsOptimizedHelper(v8::Isolate* isolate) {
- Local<v8::Context> context = isolate->GetCurrentContext();
- Local<v8::FunctionTemplate> t = FunctionTemplate::New(isolate, IsOptimized);
+ v8::Local<v8::Context> context = isolate->GetCurrentContext();
+ v8::Local<v8::FunctionTemplate> t =
+ v8::FunctionTemplate::New(isolate, IsOptimized);
context->Global()->Set(v8_str("IsOptimized"), t->GetFunction());
}
-TEST(TurboSimpleDeopt) {
+TEST(DeoptSimple) {
FLAG_allow_natives_syntax = true;
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function f(a) {"
- "var b = 1;"
- "if (!IsOptimized()) return 0;"
- "%DeoptimizeFunction(f);"
- "if (IsOptimized()) return 0;"
- "return a + b; })");
+ " var b = 1;"
+ " if (!IsOptimized()) return 0;"
+ " %DeoptimizeFunction(f);"
+ " if (IsOptimized()) return 0;"
+ " return a + b;"
+ "})");
InstallIsOptimizedHelper(CcTest::isolate());
T.CheckCall(T.Val(2), T.Val(1));
}
-TEST(TurboSimpleDeoptInExpr) {
+TEST(DeoptSimpleInExpr) {
FLAG_allow_natives_syntax = true;
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function f(a) {"
- "var b = 1;"
- "var c = 2;"
- "if (!IsOptimized()) return 0;"
- "var d = b + (%DeoptimizeFunction(f), c);"
- "if (IsOptimized()) return 0;"
- "return d + a; })");
+ " var b = 1;"
+ " var c = 2;"
+ " if (!IsOptimized()) return 0;"
+ " var d = b + (%DeoptimizeFunction(f), c);"
+ " if (IsOptimized()) return 0;"
+ " return d + a;"
+ "})");
InstallIsOptimizedHelper(CcTest::isolate());
T.CheckCall(T.Val(6), T.Val(3));
}
+
+TEST(DeoptExceptionHandlerCatch) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_try_catch = true;
+
+ FunctionTester T(
+ "(function f() {"
+ " var is_opt = IsOptimized;"
+ " try {"
+ " DeoptAndThrow(f);"
+ " } catch (e) {"
+ " return is_opt();"
+ " }"
+ "})");
+
+ CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
+ InstallIsOptimizedHelper(CcTest::isolate());
+ T.CheckCall(T.false_value());
+}
+
+
+TEST(DeoptExceptionHandlerFinally) {
+ FLAG_allow_natives_syntax = true;
+ FLAG_turbo_try_finally = true;
+
+ FunctionTester T(
+ "(function f() {"
+ " var is_opt = IsOptimized;"
+ " try {"
+ " DeoptAndThrow(f);"
+ " } finally {"
+ " return is_opt();"
+ " }"
+ "})");
+
+ CompileRun("function DeoptAndThrow(f) { %DeoptimizeFunction(f); throw 0; }");
+ InstallIsOptimizedHelper(CcTest::isolate());
+#if 0 // TODO(4195,mstarzinger): Reproduces on MIPS64, re-enable once fixed.
+ T.CheckCall(T.false_value());
+#endif
+}
+
#endif
-TEST(TurboTrivialDeopt) {
+TEST(DeoptTrivial) {
FLAG_allow_natives_syntax = true;
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function foo() {"
- "%DeoptimizeFunction(foo);"
- "return 1; })");
+ " %DeoptimizeFunction(foo);"
+ " return 1;"
+ "})");
T.CheckCall(T.Val(1));
}
diff --git a/deps/v8/test/cctest/compiler/test-run-inlining.cc b/deps/v8/test/cctest/compiler/test-run-inlining.cc
index a6d76e4d57..7f8ae25619 100644
--- a/deps/v8/test/cctest/compiler/test-run-inlining.cc
+++ b/deps/v8/test/cctest/compiler/test-run-inlining.cc
@@ -13,7 +13,7 @@ using namespace v8::internal::compiler;
namespace {
-// Helper to determine inline count via JavaScriptFrame::GetInlineCount.
+// Helper to determine inline count via JavaScriptFrame::GetFunctions.
// Note that a count of 1 indicates that no inlining has occured.
void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
StackTraceFrameIterator it(CcTest::i_isolate());
@@ -21,14 +21,17 @@ void AssertInlineCount(const v8::FunctionCallbackInfo<v8::Value>& args) {
JavaScriptFrame* topmost = it.frame();
while (!it.done()) {
JavaScriptFrame* frame = it.frame();
+ List<JSFunction*> functions(2);
+ frame->GetFunctions(&functions);
PrintF("%d %s, inline count: %d\n", frames_seen,
frame->function()->shared()->DebugName()->ToCString().get(),
- frame->GetInlineCount());
+ functions.length());
frames_seen++;
it.Advance();
}
- CHECK_EQ(args[0]->ToInt32(args.GetIsolate())->Value(),
- topmost->GetInlineCount());
+ List<JSFunction*> functions(2);
+ topmost->GetFunctions(&functions);
+ CHECK_EQ(args[0]->ToInt32(args.GetIsolate())->Value(), functions.length());
}
@@ -40,9 +43,8 @@ void InstallAssertInlineCountHelper(v8::Isolate* isolate) {
}
-const uint32_t kBuiltinInlineFlags = CompilationInfo::kBuiltinInliningEnabled |
- CompilationInfo::kContextSpecializing |
- CompilationInfo::kTypingEnabled;
+const uint32_t kRestrictedInliningFlags =
+ CompilationInfo::kContextSpecializing | CompilationInfo::kTypingEnabled;
const uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
CompilationInfo::kContextSpecializing |
@@ -52,7 +54,6 @@ const uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
TEST(SimpleInlining) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function(){"
" function foo(s) { AssertInlineCount(2); return s; };"
@@ -67,7 +68,6 @@ TEST(SimpleInlining) {
TEST(SimpleInliningDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function(){"
" function foo(s) { %DeoptimizeFunction(bar); return s; };"
@@ -81,8 +81,21 @@ TEST(SimpleInliningDeopt) {
}
+TEST(SimpleInliningDeoptSelf) {
+ FunctionTester T(
+ "(function(){"
+ " function foo(s) { %_DeoptimizeNow(); return s; };"
+ " function bar(s, t) { return foo(s); };"
+ " return bar;"
+ "})();",
+ kInlineFlags);
+
+ InstallAssertInlineCountHelper(CcTest::isolate());
+ T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
+}
+
+
TEST(SimpleInliningContext) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
@@ -97,7 +110,6 @@ TEST(SimpleInliningContext) {
TEST(SimpleInliningContextDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) {"
@@ -115,7 +127,6 @@ TEST(SimpleInliningContextDeopt) {
TEST(CaptureContext) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"var f = (function () {"
" var x = 42;"
@@ -133,7 +144,6 @@ TEST(CaptureContext) {
// TODO(sigurds) For now we do not inline any native functions. If we do at
// some point, change this test.
TEST(DontInlineEval) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"var x = 42;"
"(function () {"
@@ -148,7 +158,6 @@ TEST(DontInlineEval) {
TEST(InlineOmitArguments) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -163,7 +172,6 @@ TEST(InlineOmitArguments) {
TEST(InlineOmitArgumentsDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u,v) { AssertInlineCount(2);"
@@ -181,7 +189,6 @@ TEST(InlineOmitArgumentsDeopt) {
TEST(InlineSurplusArguments) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -197,7 +204,6 @@ TEST(InlineSurplusArguments) {
TEST(InlineSurplusArgumentsDeopt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar);"
@@ -217,7 +223,6 @@ TEST(InlineSurplusArgumentsDeopt) {
TEST(InlineTwice) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -232,7 +237,6 @@ TEST(InlineTwice) {
TEST(InlineTwiceDependent) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -248,7 +252,6 @@ TEST(InlineTwiceDependent) {
TEST(InlineTwiceDependentDiamond) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 41;"
@@ -265,7 +268,6 @@ TEST(InlineTwiceDependentDiamond) {
TEST(InlineTwiceDependentDiamondDifferent) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 41;"
@@ -282,7 +284,6 @@ TEST(InlineTwiceDependentDiamondDifferent) {
TEST(InlineLoopGuardedEmpty) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); if (s) while (s); return s; };"
@@ -297,7 +298,6 @@ TEST(InlineLoopGuardedEmpty) {
TEST(InlineLoopGuardedOnce) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
@@ -313,7 +313,6 @@ TEST(InlineLoopGuardedOnce) {
TEST(InlineLoopGuardedTwice) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
@@ -329,7 +328,6 @@ TEST(InlineLoopGuardedTwice) {
TEST(InlineLoopUnguardedEmpty) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); while (s); return s; };"
@@ -344,7 +342,6 @@ TEST(InlineLoopUnguardedEmpty) {
TEST(InlineLoopUnguardedOnce) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); while (s) {"
@@ -360,7 +357,6 @@ TEST(InlineLoopUnguardedOnce) {
TEST(InlineLoopUnguardedTwice) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s) { AssertInlineCount(2); while (s > 0) {"
@@ -376,7 +372,6 @@ TEST(InlineLoopUnguardedTwice) {
TEST(InlineStrictIntoNonStrict) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = Object.create({}, { y: { value:42, writable:false } });"
@@ -393,7 +388,6 @@ TEST(InlineStrictIntoNonStrict) {
TEST(InlineNonStrictIntoStrict) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = Object.create({}, { y: { value:42, writable:false } });"
@@ -409,7 +403,6 @@ TEST(InlineNonStrictIntoStrict) {
TEST(InlineIntrinsicIsSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -424,7 +417,6 @@ TEST(InlineIntrinsicIsSmi) {
TEST(InlineIntrinsicIsNonNegativeSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = 42;"
@@ -439,7 +431,6 @@ TEST(InlineIntrinsicIsNonNegativeSmi) {
TEST(InlineIntrinsicIsArray) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" var x = [1,2,3];"
@@ -474,7 +465,6 @@ TEST(InlineIntrinsicIsArray) {
TEST(InlineWithArguments) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u) { AssertInlineCount(2);"
@@ -494,15 +484,14 @@ TEST(InlineWithArguments) {
TEST(InlineBuiltin) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u) { AssertInlineCount(2); return true; }"
" function bar() { return foo(); };"
- " %SetInlineBuiltinFlag(foo);"
+ " %SetForceInlineFlag(foo);"
" return bar;"
"})();",
- kBuiltinInlineFlags);
+ kRestrictedInliningFlags);
InstallAssertInlineCountHelper(CcTest::isolate());
T.CheckCall(T.true_value());
@@ -510,20 +499,80 @@ TEST(InlineBuiltin) {
TEST(InlineNestedBuiltin) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u) { AssertInlineCount(3); return true; }"
" function baz(s,t,u) { return foo(s,t,u); }"
" function bar() { return baz(); };"
- " %SetInlineBuiltinFlag(foo);"
- " %SetInlineBuiltinFlag(baz);"
+ " %SetForceInlineFlag(foo);"
+ " %SetForceInlineFlag(baz);"
" return bar;"
"})();",
- kBuiltinInlineFlags);
+ kRestrictedInliningFlags);
InstallAssertInlineCountHelper(CcTest::isolate());
T.CheckCall(T.true_value());
}
+
+TEST(StrongModeArity) {
+ FLAG_strong_mode = true;
+ FunctionTester T(
+ "(function () {"
+ " function foo(x, y) { 'use strong'; return x; }"
+ " function bar(x, y) { return foo(x); }"
+ " return bar;"
+ "})();",
+ kInlineFlags);
+ T.CheckThrows(T.undefined(), T.undefined());
+}
+
+
+TEST(StrongModeArityOuter) {
+ FLAG_strong_mode = true;
+ FunctionTester T(
+ "(function () {"
+ " 'use strong';"
+ " function foo(x, y) { return x; }"
+ " function bar(x, y) { return foo(x); }"
+ " return bar;"
+ "})();",
+ kInlineFlags);
+ T.CheckThrows(T.undefined(), T.undefined());
+}
+
+
+TEST(InlineSelfRecursive) {
+ FunctionTester T(
+ "(function () {"
+ " function foo(x) { "
+ " AssertInlineCount(1);"
+ " if (x == 1) return foo(12);"
+ " return x;"
+ " }"
+ " return foo;"
+ "})();",
+ kInlineFlags);
+
+ InstallAssertInlineCountHelper(CcTest::isolate());
+ T.CheckCall(T.Val(12), T.Val(1));
+}
+
+
+TEST(InlineMutuallyRecursive) {
+ FunctionTester T(
+ "(function () {"
+ " function bar(x) { AssertInlineCount(2); return foo(x); }"
+ " function foo(x) { "
+ " if (x == 1) return bar(42);"
+ " return x;"
+ " }"
+ " return foo;"
+ "})();",
+ kInlineFlags);
+
+ InstallAssertInlineCountHelper(CcTest::isolate());
+ T.CheckCall(T.Val(42), T.Val(1));
+}
+
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
index 7fc5cc9758..1fa37748c6 100644
--- a/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
+++ b/deps/v8/test/cctest/compiler/test-run-intrinsics.cc
@@ -12,7 +12,6 @@ uint32_t flags = CompilationInfo::kInliningEnabled;
TEST(CallFunction) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_CallFunction(a, 1, 2, 3, b); })",
flags);
CompileRun("function f(a,b,c) { return a + b + c + this.d; }");
@@ -23,7 +22,6 @@ TEST(CallFunction) {
TEST(ClassOf) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_ClassOf(a); })", flags);
T.CheckCall(T.Val("Function"), T.NewObject("(function() {})"));
@@ -38,7 +36,6 @@ TEST(ClassOf) {
TEST(HeapObjectGetMap) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_HeapObjectGetMap(a); })", flags);
Factory* factory = T.main_isolate()->factory();
@@ -58,7 +55,6 @@ static int* LookupCounter(const char* name) {
TEST(IncrementStatsCounter) {
- FLAG_turbo_deoptimization = true;
FLAG_native_code_counters = true;
reinterpret_cast<v8::Isolate*>(CcTest::InitIsolateOnce())
->SetCounterFunction(LookupCounter);
@@ -76,9 +72,9 @@ TEST(IncrementStatsCounter) {
TEST(IsArray) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsArray(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
T.CheckFalse(T.NewObject("(function() {})"));
T.CheckTrue(T.NewObject("([1])"));
T.CheckFalse(T.NewObject("({})"));
@@ -90,10 +86,25 @@ TEST(IsArray) {
}
+TEST(IsDate) {
+ FunctionTester T("(function(a) { return %_IsDate(a); })", flags);
+
+ T.CheckTrue(T.NewObject("new Date()"));
+ T.CheckFalse(T.NewObject("(function() {})"));
+ T.CheckFalse(T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"));
+ T.CheckFalse(T.NewObject("(/x/)"));
+ T.CheckFalse(T.undefined());
+ T.CheckFalse(T.null());
+ T.CheckFalse(T.Val("x"));
+ T.CheckFalse(T.Val(1));
+}
+
+
TEST(IsFunction) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsFunction(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
T.CheckTrue(T.NewObject("(function() {})"));
T.CheckFalse(T.NewObject("([1])"));
T.CheckFalse(T.NewObject("({})"));
@@ -106,7 +117,6 @@ TEST(IsFunction) {
TEST(IsMinusZero) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
T.CheckFalse(T.Val(1));
@@ -119,7 +129,6 @@ TEST(IsMinusZero) {
TEST(IsNonNegativeSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })", flags);
T.CheckTrue(T.Val(1));
@@ -132,7 +141,6 @@ TEST(IsNonNegativeSmi) {
TEST(IsObject) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsObject(a); })", flags);
T.CheckFalse(T.NewObject("(function() {})"));
@@ -147,9 +155,9 @@ TEST(IsObject) {
TEST(IsRegExp) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
T.CheckFalse(T.NewObject("(function() {})"));
T.CheckFalse(T.NewObject("([1])"));
T.CheckFalse(T.NewObject("({})"));
@@ -162,20 +170,23 @@ TEST(IsRegExp) {
TEST(IsSmi) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_IsSmi(a); })", flags);
+ T.CheckFalse(T.NewObject("new Date()"));
+ T.CheckFalse(T.NewObject("(function() {})"));
+ T.CheckFalse(T.NewObject("([1])"));
+ T.CheckFalse(T.NewObject("({})"));
+ T.CheckFalse(T.NewObject("(/x/)"));
+ T.CheckFalse(T.undefined());
T.CheckTrue(T.Val(1));
T.CheckFalse(T.Val(1.1));
T.CheckFalse(T.Val(-0.0));
T.CheckTrue(T.Val(-2));
T.CheckFalse(T.Val(-2.3));
- T.CheckFalse(T.undefined());
}
TEST(MapGetInstanceType) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function(a) { return %_MapGetInstanceType(%_HeapObjectGetMap(a)); })",
flags);
@@ -189,7 +200,6 @@ TEST(MapGetInstanceType) {
TEST(ObjectEquals) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })", flags);
CompileRun("var o = {}");
@@ -203,7 +213,6 @@ TEST(ObjectEquals) {
TEST(OneByteSeqStringGetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_OneByteSeqStringGetChar(a,b); })",
flags);
@@ -219,7 +228,6 @@ TEST(OneByteSeqStringGetChar) {
TEST(OneByteSeqStringSetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { %_OneByteSeqStringSetChar(a,88,b); })",
flags);
@@ -236,7 +244,6 @@ TEST(OneByteSeqStringSetChar) {
TEST(NewConsString) {
- FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function() { "
" return %_NewConsString(14, true, 'abcdefghi', 'jklmn');"
@@ -248,7 +255,6 @@ TEST(NewConsString) {
TEST(SetValueOf) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })", flags);
T.CheckCall(T.Val("a"), T.NewObject("(new String)"), T.Val("a"));
@@ -258,7 +264,6 @@ TEST(SetValueOf) {
TEST(StringAdd) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })", flags);
T.CheckCall(T.Val("aaabbb"), T.Val("aaa"), T.Val("bbb"));
@@ -268,7 +273,6 @@ TEST(StringAdd) {
TEST(StringCharAt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringCharAt(a,b); })", flags);
T.CheckCall(T.Val("e"), T.Val("huge fan!"), T.Val(3));
@@ -278,7 +282,6 @@ TEST(StringCharAt) {
TEST(StringCharCodeAt) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringCharCodeAt(a,b); })",
flags);
@@ -289,7 +292,6 @@ TEST(StringCharCodeAt) {
TEST(StringCharFromCode) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_StringCharFromCode(a); })", flags);
T.CheckCall(T.Val("a"), T.Val(97));
@@ -299,7 +301,6 @@ TEST(StringCharFromCode) {
TEST(StringCompare) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_StringCompare(a,b); })", flags);
T.CheckCall(T.Val(-1), T.Val("aaa"), T.Val("bbb"));
@@ -309,7 +310,6 @@ TEST(StringCompare) {
TEST(SubString) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_SubString(a,b,b+3); })", flags);
T.CheckCall(T.Val("aaa"), T.Val("aaabbb"), T.Val(0.0));
@@ -319,7 +319,6 @@ TEST(SubString) {
TEST(TwoByteSeqStringGetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { return %_TwoByteSeqStringGetChar(a,b); })",
flags);
@@ -335,7 +334,6 @@ TEST(TwoByteSeqStringGetChar) {
TEST(TwoByteSeqStringSetChar) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a,b) { %_TwoByteSeqStringSetChar(a,88,b); })",
flags);
@@ -352,7 +350,6 @@ TEST(TwoByteSeqStringSetChar) {
TEST(ValueOf) {
- FLAG_turbo_deoptimization = true;
FunctionTester T("(function(a) { return %_ValueOf(a); })", flags);
T.CheckCall(T.Val("a"), T.Val("a"));
diff --git a/deps/v8/test/cctest/compiler/test-run-jscalls.cc b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
index a622af8995..8de2d7a214 100644
--- a/deps/v8/test/cctest/compiler/test-run-jscalls.cc
+++ b/deps/v8/test/cctest/compiler/test-run-jscalls.cc
@@ -242,6 +242,7 @@ TEST(ContextLoadedFromActivation) {
i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
jsfun->set_code(T.function->code());
+ jsfun->set_shared(T.function->shared());
context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
CompileRun("var x = 24;");
ExpectInt32("foo();", 24);
@@ -263,6 +264,7 @@ TEST(BuiltinLoadedFromActivation) {
i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
jsfun->set_code(T.function->code());
+ jsfun->set_shared(T.function->shared());
context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
CompileRun("var x = 24;");
ExpectObject("foo()", context->Global());
diff --git a/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
index 2e2e10e9de..0e1977b720 100644
--- a/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
+++ b/deps/v8/test/cctest/compiler/test-run-jsexceptions.cc
@@ -10,19 +10,14 @@ using namespace v8::internal;
using namespace v8::internal::compiler;
TEST(Throw) {
- i::FLAG_turbo_exceptions = true;
FunctionTester T("(function(a,b) { if (a) { throw b; } else { return b; }})");
-// TODO(mstarzinger)
-#if 0
T.CheckThrows(T.true_value(), T.NewObject("new Error"));
-#endif
T.CheckCall(T.Val(23), T.false_value(), T.Val(23));
}
TEST(ThrowMessagePosition) {
- i::FLAG_turbo_exceptions = true;
static const char* src =
"(function(a, b) { \n"
" if (a == 1) throw 1; \n"
@@ -48,7 +43,6 @@ TEST(ThrowMessagePosition) {
TEST(ThrowMessageDirectly) {
- i::FLAG_turbo_exceptions = true;
static const char* src =
"(function(a, b) {"
" if (a) { throw b; } else { throw new Error(b); }"
@@ -56,19 +50,17 @@ TEST(ThrowMessageDirectly) {
FunctionTester T(src);
v8::Handle<v8::Message> message;
-// TODO(mstarzinger)
-#if 0
message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
CHECK(message->Get()->Equals(v8_str("Uncaught Error: Wat?")));
message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
CHECK(message->Get()->Equals(v8_str("Uncaught Kaboom!")));
-#endif
}
TEST(ThrowMessageIndirectly) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
+ i::FLAG_turbo_try_finally = true;
static const char* src =
"(function(a, b) {"
" try {"
@@ -80,23 +72,16 @@ TEST(ThrowMessageIndirectly) {
FunctionTester T(src);
v8::Handle<v8::Message> message;
-// TODO(mstarzinger)
-#if 0
message = T.CheckThrowsReturnMessage(T.false_value(), T.Val("Wat?"));
CHECK(message->Get()->Equals(v8_str("Uncaught Error: Wat?")));
message = T.CheckThrowsReturnMessage(T.true_value(), T.Val("Kaboom!"));
CHECK(message->Get()->Equals(v8_str("Uncaught Kaboom!")));
-#endif
}
-// TODO(mstarzinger): Increase test coverage by having similar tests within the
-// mjsunit suite to also test integration with other components (e.g. OSR).
-
-
TEST(Catch) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -115,7 +100,7 @@ TEST(Catch) {
TEST(CatchNested) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -139,7 +124,7 @@ TEST(CatchNested) {
TEST(CatchBreak) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -164,7 +149,7 @@ TEST(CatchBreak) {
TEST(CatchCall) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function(fun) {"
" var r = '-';"
@@ -186,7 +171,7 @@ TEST(CatchCall) {
TEST(Finally) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -204,7 +189,7 @@ TEST(Finally) {
TEST(FinallyBreak) {
- i::FLAG_turbo_exceptions = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function(a,b) {"
" var r = '-';"
@@ -228,8 +213,7 @@ TEST(FinallyBreak) {
TEST(DeoptTry) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function f(a) {"
" try {"
@@ -246,8 +230,7 @@ TEST(DeoptTry) {
TEST(DeoptCatch) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_catch = true;
const char* src =
"(function f(a) {"
" try {"
@@ -264,8 +247,7 @@ TEST(DeoptCatch) {
TEST(DeoptFinallyReturn) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function f(a) {"
" try {"
@@ -282,8 +264,7 @@ TEST(DeoptFinallyReturn) {
TEST(DeoptFinallyReThrow) {
- i::FLAG_turbo_exceptions = true;
- i::FLAG_turbo_deoptimization = true;
+ i::FLAG_turbo_try_finally = true;
const char* src =
"(function f(a) {"
" try {"
diff --git a/deps/v8/test/cctest/compiler/test-run-jsops.cc b/deps/v8/test/cctest/compiler/test-run-jsops.cc
index 032db82db3..56ac31cbc9 100644
--- a/deps/v8/test/cctest/compiler/test-run-jsops.cc
+++ b/deps/v8/test/cctest/compiler/test-run-jsops.cc
@@ -523,9 +523,7 @@ TEST(RegExpLiteral) {
TEST(ClassLiteral) {
- FLAG_harmony_classes = true;
FLAG_harmony_sloppy = true;
- FLAG_harmony_object_literals = true;
const char* src =
"(function(a,b) {"
" class C {"
diff --git a/deps/v8/test/cctest/compiler/test-run-machops.cc b/deps/v8/test/cctest/compiler/test-run-machops.cc
index 8d051bc90b..b1fc36968f 100644
--- a/deps/v8/test/cctest/compiler/test-run-machops.cc
+++ b/deps/v8/test/cctest/compiler/test-run-machops.cc
@@ -82,6 +82,63 @@ TEST(CodeGenInt32Binop) {
}
+#if V8_TURBOFAN_BACKEND_64
+static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) {
+ switch (index) {
+ case 0:
+ return m->Parameter(0);
+ case 1:
+ return m->Parameter(1);
+ case 2:
+ return m->Int64Constant(0);
+ case 3:
+ return m->Int64Constant(1);
+ case 4:
+ return m->Int64Constant(-1);
+ case 5:
+ return m->Int64Constant(0xff);
+ case 6:
+ return m->Int64Constant(0x0123456789abcdefLL);
+ case 7:
+ return m->Load(kMachInt64, m->PointerConstant(NULL));
+ default:
+ return NULL;
+ }
+}
+
+
+TEST(CodeGenInt64Binop) {
+ RawMachineAssemblerTester<void> m;
+
+ const Operator* kOps[] = {
+ m.machine()->Word64And(), m.machine()->Word64Or(),
+ m.machine()->Word64Xor(), m.machine()->Word64Shl(),
+ m.machine()->Word64Shr(), m.machine()->Word64Sar(),
+ m.machine()->Word64Equal(), m.machine()->Int64Add(),
+ m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(),
+ m.machine()->Uint64Div(), m.machine()->Int64Mod(),
+ m.machine()->Uint64Mod(), m.machine()->Int64LessThan(),
+ m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(),
+ m.machine()->Uint64LessThanOrEqual()};
+
+ for (size_t i = 0; i < arraysize(kOps); ++i) {
+ for (int j = 0; j < 8; j++) {
+ for (int k = 0; k < 8; k++) {
+ RawMachineAssemblerTester<int64_t> m(kMachInt64, kMachInt64);
+ Node* a = Int64Input(&m, j);
+ Node* b = Int64Input(&m, k);
+ m.Return(m.NewNode(kOps[i], a, b));
+ m.GenerateCode();
+ }
+ }
+ }
+}
+
+
+// TODO(titzer): add tests that run 64-bit integer operations.
+#endif // V8_TURBOFAN_BACKEND_64
+
+
TEST(RunGoto) {
RawMachineAssemblerTester<int32_t> m;
int constant = 99999;
@@ -164,15 +221,14 @@ template <typename R>
static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node,
MachineType type, Node* true_node,
Node* false_node) {
- MLabel blocka, blockb;
- MLabel* end = m->Exit();
+ MLabel blocka, blockb, end;
m->Branch(cond_node, &blocka, &blockb);
m->Bind(&blocka);
- m->Goto(end);
+ m->Goto(&end);
m->Bind(&blockb);
- m->Goto(end);
+ m->Goto(&end);
- m->Bind(end);
+ m->Bind(&end);
Node* phi = m->Phi(type, true_node, false_node);
m->Return(phi);
}
@@ -237,16 +293,15 @@ TEST(RunLoopPhiConst) {
Node* false_node = m.Int32Constant(false_val);
// x = false_val; while(false) { x = true_val; } return x;
- MLabel body, header;
- MLabel* end = m.Exit();
+ MLabel body, header, end;
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, false_node, true_node);
- m.Branch(cond_node, &body, end);
+ m.Branch(cond_node, &body, &end);
m.Bind(&body);
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
m.Return(phi);
CHECK_EQ(false_val, m.Call());
@@ -256,20 +311,19 @@ TEST(RunLoopPhiConst) {
TEST(RunLoopPhiParam) {
RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
- MLabel blocka, blockb;
- MLabel* end = m.Exit();
+ MLabel blocka, blockb, end;
m.Goto(&blocka);
m.Bind(&blocka);
Node* phi = m.Phi(kMachInt32, m.Parameter(1), m.Parameter(2));
Node* cond = m.Phi(kMachInt32, m.Parameter(0), m.Int32Constant(0));
- m.Branch(cond, &blockb, end);
+ m.Branch(cond, &blockb, &end);
m.Bind(&blockb);
m.Goto(&blocka);
- m.Bind(end);
+ m.Bind(&end);
m.Return(phi);
int32_t c1 = 0xa81903b4;
@@ -287,22 +341,21 @@ TEST(RunLoopPhiInduction) {
int false_val = 0x10777;
// x = false_val; while(false) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* false_node = m.Int32Constant(false_val);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, false_node, false_node);
- m.Branch(m.Int32Constant(0), &body, end);
+ m.Branch(m.Int32Constant(0), &body, &end);
m.Bind(&body);
Node* add = m.Int32Add(phi, m.Int32Constant(1));
phi->ReplaceInput(1, add);
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
m.Return(phi);
CHECK_EQ(false_val, m.Call());
@@ -314,21 +367,20 @@ TEST(RunLoopIncrement) {
Int32BinopTester bt(&m);
// x = 0; while(x ^ param) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* zero = m.Int32Constant(0);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, zero, zero);
- m.Branch(m.WordXor(phi, bt.param0), &body, end);
+ m.Branch(m.WordXor(phi, bt.param0), &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(11, bt.call(11, 0));
@@ -342,21 +394,20 @@ TEST(RunLoopIncrement2) {
Int32BinopTester bt(&m);
// x = 0; while(x < param) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* zero = m.Int32Constant(0);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, zero, zero);
- m.Branch(m.Int32LessThan(phi, bt.param0), &body, end);
+ m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(11, bt.call(11, 0));
@@ -371,21 +422,20 @@ TEST(RunLoopIncrement3) {
Int32BinopTester bt(&m);
// x = 0; while(x < param) { x++; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* zero = m.Int32Constant(0);
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, zero, zero);
- m.Branch(m.Uint32LessThan(phi, bt.param0), &body, end);
+ m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(11, bt.call(11, 0));
@@ -400,20 +450,19 @@ TEST(RunLoopDecrement) {
Int32BinopTester bt(&m);
// x = param; while(x) { x--; } return x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
m.Goto(&header);
m.Bind(&header);
Node* phi = m.Phi(kMachInt32, bt.param0, m.Int32Constant(0));
- m.Branch(phi, &body, end);
+ m.Branch(phi, &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
bt.AddReturn(phi);
CHECK_EQ(0, bt.call(11, 0));
@@ -426,8 +475,7 @@ TEST(RunLoopIncrementFloat32) {
RawMachineAssemblerTester<int32_t> m;
// x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* minus_3 = m.Float32Constant(-3.0f);
Node* ten = m.Float32Constant(10.0f);
@@ -435,13 +483,13 @@ TEST(RunLoopIncrementFloat32) {
m.Bind(&header);
Node* phi = m.Phi(kMachFloat32, minus_3, ten);
- m.Branch(m.Float32LessThan(phi, ten), &body, end);
+ m.Branch(m.Float32LessThan(phi, ten), &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi)));
CHECK_EQ(10, m.Call());
@@ -452,8 +500,7 @@ TEST(RunLoopIncrementFloat64) {
RawMachineAssemblerTester<int32_t> m;
// x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x;
- MLabel header, body;
- MLabel* end = m.Exit();
+ MLabel header, body, end;
Node* minus_3 = m.Float64Constant(-3.0);
Node* ten = m.Float64Constant(10.0);
@@ -461,13 +508,13 @@ TEST(RunLoopIncrementFloat64) {
m.Bind(&header);
Node* phi = m.Phi(kMachFloat64, minus_3, ten);
- m.Branch(m.Float64LessThan(phi, ten), &body, end);
+ m.Branch(m.Float64LessThan(phi, ten), &body, &end);
m.Bind(&body);
phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5)));
m.Goto(&header);
- m.Bind(end);
+ m.Bind(&end);
m.Return(m.ChangeFloat64ToInt32(phi));
CHECK_EQ(10, m.Call());
@@ -4395,7 +4442,7 @@ TEST(RunTestIntPtrArithmetic) {
RawMachineAssemblerTester<int32_t*> m;
Node* input = m.PointerConstant(&inputs[0]);
Node* output = m.PointerConstant(&outputs[kInputSize - 1]);
- Node* elem_size = m.ConvertInt32ToIntPtr(m.Int32Constant(sizeof(inputs[0])));
+ Node* elem_size = m.IntPtrConstant(sizeof(inputs[0]));
for (int i = 0; i < kInputSize; i++) {
m.Store(kMachInt32, output, m.Load(kMachInt32, input));
input = m.IntPtrAdd(input, elem_size);
@@ -4412,7 +4459,7 @@ TEST(RunTestIntPtrArithmetic) {
TEST(RunSpillLotsOfThings) {
static const int kInputSize = 1000;
- RawMachineAssemblerTester<void> m;
+ RawMachineAssemblerTester<int32_t> m;
Node* accs[kInputSize];
int32_t outputs[kInputSize];
Node* one = m.Int32Constant(1);
@@ -4793,7 +4840,8 @@ TEST(RunTruncateFloat64ToInt32P) {
{-1.7976931348623157e+308, 0}};
double input = -1.0;
RawMachineAssemblerTester<int32_t> m;
- m.Return(m.TruncateFloat64ToInt32(m.LoadFromPointer(&input, kMachFloat64)));
+ m.Return(m.TruncateFloat64ToInt32(TruncationMode::kJavaScript,
+ m.LoadFromPointer(&input, kMachFloat64)));
for (size_t i = 0; i < arraysize(kValues); ++i) {
input = kValues[i].from;
uint64_t expected = static_cast<int64_t>(kValues[i].raw);
@@ -5080,7 +5128,7 @@ TEST(RunFloat64RoundDown1) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundDown()) return;
+ if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64,
m.Float64RoundDown(m.LoadFromPointer(&input, kMachFloat64)));
m.Return(m.Int32Constant(0));
@@ -5097,7 +5145,7 @@ TEST(RunFloat64RoundDown2) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundDown()) return;
+ if (!m.machine()->Float64RoundDown().IsSupported()) return;
m.StoreToPointer(&result, kMachFloat64,
m.Float64Sub(m.Float64Constant(-0.0),
m.Float64RoundDown(m.Float64Sub(
@@ -5117,7 +5165,7 @@ TEST(RunFloat64RoundTruncate) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundTruncate()) return;
+ if (!m.machine()->Float64RoundTruncate().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
@@ -5135,7 +5183,7 @@ TEST(RunFloat64RoundTiesAway) {
double input = -1.0;
double result = 0.0;
RawMachineAssemblerTester<int32_t> m;
- if (!m.machine()->HasFloat64RoundTiesAway()) return;
+ if (!m.machine()->Float64RoundTiesAway().IsSupported()) return;
m.StoreToPointer(
&result, kMachFloat64,
m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
@@ -5148,4 +5196,83 @@ TEST(RunFloat64RoundTiesAway) {
}
}
+
+#if !USE_SIMULATOR
+
+namespace {
+
+int32_t const kMagicFoo0 = 0xdeadbeef;
+
+
+int32_t foo0() { return kMagicFoo0; }
+
+
+int32_t foo1(int32_t x) { return x; }
+
+
+int32_t foo2(int32_t x, int32_t y) { return x - y; }
+
+
+int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f,
+ int32_t g, int32_t h) {
+ return a + b + c + d + e + f + g + h;
+}
+
+} // namespace
+
+
+TEST(RunCallCFunction0) {
+ auto* foo0_ptr = &foo0;
+ RawMachineAssemblerTester<int32_t> m;
+ Node* function = m.LoadFromPointer(&foo0_ptr, kMachPtr);
+ m.Return(m.CallCFunction0(kMachInt32, function));
+ CHECK_EQ(kMagicFoo0, m.Call());
+}
+
+
+TEST(RunCallCFunction1) {
+ auto* foo1_ptr = &foo1;
+ RawMachineAssemblerTester<int32_t> m(kMachInt32);
+ Node* function = m.LoadFromPointer(&foo1_ptr, kMachPtr);
+ m.Return(m.CallCFunction1(kMachInt32, kMachInt32, function, m.Parameter(0)));
+ FOR_INT32_INPUTS(i) {
+ int32_t const expected = *i;
+ CHECK_EQ(expected, m.Call(expected));
+ }
+}
+
+
+TEST(RunCallCFunction2) {
+ auto* foo2_ptr = &foo2;
+ RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+ Node* function = m.LoadFromPointer(&foo2_ptr, kMachPtr);
+ m.Return(m.CallCFunction2(kMachInt32, kMachInt32, kMachInt32, function,
+ m.Parameter(0), m.Parameter(1)));
+ FOR_INT32_INPUTS(i) {
+ int32_t const x = *i;
+ FOR_INT32_INPUTS(j) {
+ int32_t const y = *j;
+ CHECK_EQ(x - y, m.Call(x, y));
+ }
+ }
+}
+
+
+TEST(RunCallCFunction8) {
+ auto* foo8_ptr = &foo8;
+ RawMachineAssemblerTester<int32_t> m(kMachInt32);
+ Node* function = m.LoadFromPointer(&foo8_ptr, kMachPtr);
+ Node* param = m.Parameter(0);
+ m.Return(m.CallCFunction8(kMachInt32, kMachInt32, kMachInt32, kMachInt32,
+ kMachInt32, kMachInt32, kMachInt32, kMachInt32,
+ kMachInt32, function, param, param, param, param,
+ param, param, param, param));
+ FOR_INT32_INPUTS(i) {
+ int32_t const x = *i;
+ CHECK_EQ(x * 8, m.Call(x));
+ }
+}
+
+#endif // USE_SIMULATOR
+
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-run-stubs.cc b/deps/v8/test/cctest/compiler/test-run-stubs.cc
index c81f0f184d..9c7998d7af 100644
--- a/deps/v8/test/cctest/compiler/test-run-stubs.cc
+++ b/deps/v8/test/cctest/compiler/test-run-stubs.cc
@@ -6,7 +6,10 @@
#include "src/code-stubs.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
#include "src/compiler/linkage.h"
+#include "src/compiler/machine-operator.h"
#include "src/compiler/pipeline.h"
#include "src/parser.h"
#include "test/cctest/compiler/function-tester.h"
@@ -17,60 +20,54 @@ using namespace v8::internal;
using namespace v8::internal::compiler;
-static Handle<JSFunction> GetFunction(Isolate* isolate, const char* name) {
- v8::ExtensionConfiguration no_extensions;
- Handle<Context> ctx = isolate->bootstrapper()->CreateEnvironment(
- MaybeHandle<JSGlobalProxy>(), v8::Handle<v8::ObjectTemplate>(),
- &no_extensions);
- Handle<JSBuiltinsObject> builtins = handle(ctx->builtins());
- MaybeHandle<Object> fun = Object::GetProperty(isolate, builtins, name);
- Handle<JSFunction> function = Handle<JSFunction>::cast(fun.ToHandleChecked());
- // Just to make sure nobody calls this...
- function->set_code(isolate->builtins()->builtin(Builtins::kIllegal));
- return function;
-}
-
-
-class StringLengthStubTF : public CodeStub {
- public:
- explicit StringLengthStubTF(Isolate* isolate) : CodeStub(isolate) {}
+TEST(RunMathFloorStub) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
- StringLengthStubTF(uint32_t key, Isolate* isolate) : CodeStub(key, isolate) {}
+ // Create code and an accompanying descriptor.
+ MathFloorStub stub(isolate);
+ Handle<Code> code = stub.GenerateCode();
+ Zone* zone = scope.main_zone();
- CallInterfaceDescriptor GetCallInterfaceDescriptor() override {
- return LoadDescriptor(isolate());
- };
+ CompilationInfo info(&stub, isolate, zone);
+ CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
- Handle<Code> GenerateCode() override {
- Zone zone;
- // Build a "hybrid" CompilationInfo for a JSFunction/CodeStub pair.
- ParseInfo parse_info(&zone, GetFunction(isolate(), "STRING_LENGTH_STUB"));
- CompilationInfo info(&parse_info);
- info.SetStub(this);
- // Run a "mini pipeline", extracted from compiler.cc.
- CHECK(Parser::ParseStatic(info.parse_info()));
- CHECK(Compiler::Analyze(info.parse_info()));
- return Pipeline(&info).GenerateCode();
- }
+ // Create a function to call the code using the descriptor.
+ Graph graph(zone);
+ CommonOperatorBuilder common(zone);
+ JSOperatorBuilder javascript(zone);
+ MachineOperatorBuilder machine(zone);
+ JSGraph js(isolate, &graph, &common, &javascript, &machine);
- Major MajorKey() const override { return StringLength; };
- Code::Kind GetCodeKind() const override { return Code::HANDLER; }
- InlineCacheState GetICState() const override { return MONOMORPHIC; }
- ExtraICState GetExtraICState() const override { return Code::LOAD_IC; }
- Code::StubType GetStubType() const override { return Code::FAST; }
+ // FunctionTester (ab)uses a 2-argument function
+ Node* start = graph.NewNode(common.Start(4));
+ // Parameter 0 is the number to round
+ Node* numberParam = graph.NewNode(common.Parameter(1), start);
+ Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code);
+ Node* theCode = graph.NewNode(common.HeapConstant(u));
+ Node* dummyContext = graph.NewNode(common.NumberConstant(0.0));
+ Node* call = graph.NewNode(common.Call(descriptor), theCode,
+ js.UndefinedConstant(), js.UndefinedConstant(),
+ numberParam, dummyContext, start, start);
+ Node* ret = graph.NewNode(common.Return(), call, call, start);
+ Node* end = graph.NewNode(common.End(1), ret);
+ graph.SetStart(start);
+ graph.SetEnd(end);
+ FunctionTester ft(&graph);
- private:
- DISALLOW_COPY_AND_ASSIGN(StringLengthStubTF);
-};
+ Handle<Object> value = ft.Val(1.5);
+ Handle<Object> result = ft.Call(value, value).ToHandleChecked();
+ CHECK_EQ(1, Smi::cast(*result)->value());
+}
-TEST(RunStringLengthStubTF) {
+TEST(RunStringLengthTFStub) {
HandleAndZoneScope scope;
Isolate* isolate = scope.main_isolate();
Zone* zone = scope.main_zone();
// Create code and an accompanying descriptor.
- StringLengthStubTF stub(isolate);
+ StringLengthTFStub stub(isolate);
Handle<Code> code = stub.GenerateCode();
CompilationInfo info(&stub, isolate, zone);
CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
@@ -78,18 +75,21 @@ TEST(RunStringLengthStubTF) {
// Create a function to call the code using the descriptor.
Graph graph(zone);
CommonOperatorBuilder common(zone);
- // FunctionTester (ab)uses a 2-argument function
- Node* start = graph.NewNode(common.Start(2));
+ // FunctionTester (ab)uses a 4-argument function
+ Node* start = graph.NewNode(common.Start(6));
// Parameter 0 is the receiver
Node* receiverParam = graph.NewNode(common.Parameter(1), start);
Node* nameParam = graph.NewNode(common.Parameter(2), start);
+ Node* slotParam = graph.NewNode(common.Parameter(3), start);
+ Node* vectorParam = graph.NewNode(common.Parameter(4), start);
Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code);
Node* theCode = graph.NewNode(common.HeapConstant(u));
Node* dummyContext = graph.NewNode(common.NumberConstant(0.0));
- Node* call = graph.NewNode(common.Call(descriptor), theCode, receiverParam,
- nameParam, dummyContext, start, start);
+ Node* call =
+ graph.NewNode(common.Call(descriptor), theCode, receiverParam, nameParam,
+ slotParam, vectorParam, dummyContext, start, start);
Node* ret = graph.NewNode(common.Return(), call, call, start);
- Node* end = graph.NewNode(common.End(), ret);
+ Node* end = graph.NewNode(common.End(1), ret);
graph.SetStart(start);
graph.SetEnd(end);
FunctionTester ft(&graph);
@@ -99,8 +99,49 @@ TEST(RunStringLengthStubTF) {
Handle<JSReceiver> receiverArg =
Object::ToObject(isolate, ft.Val(testString)).ToHandleChecked();
Handle<String> nameArg = ft.Val("length");
- Handle<Object> result = ft.Call(receiverArg, nameArg).ToHandleChecked();
+ Handle<Object> slot = ft.Val(0.0);
+ Handle<Object> vector = ft.Val(0.0);
+ Handle<Object> result =
+ ft.Call(receiverArg, nameArg, slot, vector).ToHandleChecked();
CHECK_EQ(static_cast<int>(strlen(testString)), Smi::cast(*result)->value());
}
+
+TEST(RunStringAddTFStub) {
+ HandleAndZoneScope scope;
+ Isolate* isolate = scope.main_isolate();
+ Zone* zone = scope.main_zone();
+
+ // Create code and an accompanying descriptor.
+ StringAddTFStub stub(isolate, STRING_ADD_CHECK_BOTH, NOT_TENURED);
+ Handle<Code> code = stub.GenerateCode();
+ CompilationInfo info(&stub, isolate, zone);
+ CallDescriptor* descriptor = Linkage::ComputeIncoming(zone, &info);
+
+ // Create a function to call the code using the descriptor.
+ Graph graph(zone);
+ CommonOperatorBuilder common(zone);
+ // FunctionTester (ab)uses a 2-argument function
+ Node* start = graph.NewNode(common.Start(4));
+ // Parameter 0 is the receiver
+ Node* leftParam = graph.NewNode(common.Parameter(1), start);
+ Node* rightParam = graph.NewNode(common.Parameter(2), start);
+ Unique<HeapObject> u = Unique<HeapObject>::CreateImmovable(code);
+ Node* theCode = graph.NewNode(common.HeapConstant(u));
+ Node* dummyContext = graph.NewNode(common.NumberConstant(0.0));
+ Node* call = graph.NewNode(common.Call(descriptor), theCode, leftParam,
+ rightParam, dummyContext, start, start);
+ Node* ret = graph.NewNode(common.Return(), call, call, start);
+ Node* end = graph.NewNode(common.End(1), ret);
+ graph.SetStart(start);
+ graph.SetEnd(end);
+ FunctionTester ft(&graph);
+
+ // Actuall call through to the stub, verifying its result.
+ Handle<String> leftArg = ft.Val("links");
+ Handle<String> rightArg = ft.Val("rechts");
+ Handle<Object> result = ft.Call(leftArg, rightArg).ToHandleChecked();
+ CHECK(String::Equals(ft.Val("linksrechts"), Handle<String>::cast(result)));
+}
+
#endif // V8_TURBOFAN_TARGET
diff --git a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
index 9242248d60..022e01690b 100644
--- a/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-simplified-lowering.cc
@@ -33,12 +33,9 @@ template <typename ReturnType>
class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
public:
SimplifiedLoweringTester(MachineType p0 = kMachNone,
- MachineType p1 = kMachNone,
- MachineType p2 = kMachNone,
- MachineType p3 = kMachNone,
- MachineType p4 = kMachNone)
- : GraphBuilderTester<ReturnType>(p0, p1, p2, p3, p4),
- typer(this->isolate(), this->graph(), MaybeHandle<Context>()),
+ MachineType p1 = kMachNone)
+ : GraphBuilderTester<ReturnType>(p0, p1),
+ typer(this->isolate(), this->graph()),
javascript(this->zone()),
jsgraph(this->isolate(), this->graph(), this->common(), &javascript,
this->machine()),
@@ -63,7 +60,7 @@ class SimplifiedLoweringTester : public GraphBuilderTester<ReturnType> {
lowering.LowerAllNodes();
ChangeLowering lowering(&jsgraph);
- GraphReducer reducer(this->graph(), this->zone());
+ GraphReducer reducer(this->zone(), this->graph());
reducer.AddReducer(&lowering);
reducer.ReduceGraph();
Verifier::Run(this->graph());
@@ -538,8 +535,7 @@ class AccessTester : public HandleAndZoneScope {
E GetElement(int index) {
BoundsCheck(index);
if (tagged) {
- E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
- return raw[index];
+ return GetTaggedElement(index);
} else {
return untagged_array[index];
}
@@ -572,8 +568,19 @@ class AccessTester : public HandleAndZoneScope {
CHECK_LT(index, static_cast<int>(num_elements));
CHECK_EQ(static_cast<int>(ByteSize()), tagged_array->length());
}
+
+ E GetTaggedElement(int index) {
+ E* raw = reinterpret_cast<E*>(tagged_array->GetDataStartAddress());
+ return raw[index];
+ }
};
+template <>
+double AccessTester<double>::GetTaggedElement(int index) {
+ return ReadDoubleValue(tagged_array->GetDataStartAddress() +
+ index * sizeof(double));
+}
+
template <typename E>
static void RunAccessTest(MachineType rep, E* original_elements, size_t num) {
@@ -703,14 +710,14 @@ class TestingGraph : public HandleAndZoneScope, public GraphAndBuilders {
explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(),
Type* p2_type = Type::None())
: GraphAndBuilders(main_zone()),
- typer(main_isolate(), graph(), MaybeHandle<Context>()),
+ typer(main_isolate(), graph()),
javascript(main_zone()),
jsgraph(main_isolate(), graph(), common(), &javascript, machine()) {
start = graph()->NewNode(common()->Start(2));
graph()->SetStart(start);
ret =
graph()->NewNode(common()->Return(), jsgraph.Constant(0), start, start);
- end = graph()->NewNode(common()->End(), ret);
+ end = graph()->NewNode(common()->End(1), ret);
graph()->SetEnd(end);
p0 = graph()->NewNode(common()->Parameter(0), start);
p1 = graph()->NewNode(common()->Parameter(1), start);
@@ -1269,7 +1276,6 @@ TEST(LowerStringOps_to_call_and_compare) {
t.CheckLoweringBinop(compare_eq, t.simplified()->StringEqual());
t.CheckLoweringBinop(compare_lt, t.simplified()->StringLessThan());
t.CheckLoweringBinop(compare_le, t.simplified()->StringLessThanOrEqual());
- t.CheckLoweringBinop(IrOpcode::kCall, t.simplified()->StringAdd());
}
}
@@ -1443,8 +1449,8 @@ TEST(LowerLoadField_to_load) {
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), Type::Any(), kMachineReps[i]};
- Node* load =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+ Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+ t.start, t.start);
Node* use = t.Use(load, kMachineReps[i]);
t.Return(use);
t.Lower();
@@ -1624,8 +1630,8 @@ TEST(InsertChangeForLoadField) {
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), Type::Any(), kMachFloat64};
- Node* load =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
+ Node* load = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+ t.start, t.start);
t.Return(load);
t.Lower();
CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1679,10 +1685,10 @@ TEST(UpdatePhi) {
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), kTypes[i], kMachineTypes[i]};
- Node* load0 =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
- Node* load1 =
- t.graph()->NewNode(t.simplified()->LoadField(access), t.p1, t.start);
+ Node* load0 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p0,
+ t.start, t.start);
+ Node* load1 = t.graph()->NewNode(t.simplified()->LoadField(access), t.p1,
+ t.start, t.start);
Node* phi = t.graph()->NewNode(t.common()->Phi(kMachAnyTagged, 2), load0,
load1, t.start);
t.Return(t.Use(phi, kMachineTypes[i]));