summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest
diff options
context:
space:
mode:
authorAli Ijaz Sheikh <ofrobots@google.com>2015-08-23 06:09:40 -0700
committerRod Vagg <rod@vagg.org>2015-09-06 21:38:01 +1000
commit9fddd83cf9adf505bce2e2373881df0c4d41b261 (patch)
tree4272ce14c10fea496af2e78fc6debb187d613451 /deps/v8/test/cctest
parent46b7d151674d138e7ea4342d5f3ada1208b87ff2 (diff)
downloadnode-new-9fddd83cf9adf505bce2e2373881df0c4d41b261.tar.gz
deps: upgrade V8 to 4.5.103.24
Upgrade to the latest branch-head for V8 4.5. For the full commit log see https://github.com/v8/v8-git-mirror/commits/4.5.103.24 PR-URL: https://github.com/nodejs/node/pull/2509 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/test/cctest')
-rw-r--r--deps/v8/test/cctest/cctest.gyp2
-rw-r--r--deps/v8/test/cctest/cctest.h28
-rw-r--r--deps/v8/test/cctest/cctest.status36
-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
-rw-r--r--deps/v8/test/cctest/gay-fixed.cc3
-rw-r--r--deps/v8/test/cctest/gay-precision.cc3
-rw-r--r--deps/v8/test/cctest/gay-shortest.cc3
-rw-r--r--deps/v8/test/cctest/print-extension.cc3
-rw-r--r--deps/v8/test/cctest/profiler-extension.cc3
-rw-r--r--deps/v8/test/cctest/test-accessors.cc2
-rw-r--r--deps/v8/test/cctest/test-api-interceptors.cc113
-rw-r--r--deps/v8/test/cctest/test-api.cc1494
-rw-r--r--deps/v8/test/cctest/test-assembler-arm.cc184
-rw-r--r--deps/v8/test/cctest/test-assembler-mips.cc3670
-rw-r--r--deps/v8/test/cctest/test-assembler-mips64.cc3965
-rw-r--r--deps/v8/test/cctest/test-assembler-ppc.cc88
-rw-r--r--deps/v8/test/cctest/test-code-stubs-arm64.cc4
-rw-r--r--deps/v8/test/cctest/test-code-stubs-mips64.cc3
-rw-r--r--deps/v8/test/cctest/test-compiler.cc95
-rw-r--r--deps/v8/test/cctest/test-constantpool.cc502
-rw-r--r--deps/v8/test/cctest/test-debug.cc379
-rw-r--r--deps/v8/test/cctest/test-decls.cc8
-rw-r--r--deps/v8/test/cctest/test-deoptimization.cc19
-rw-r--r--deps/v8/test/cctest/test-disasm-arm64.cc9
-rw-r--r--deps/v8/test/cctest/test-disasm-mips.cc567
-rw-r--r--deps/v8/test/cctest/test-disasm-mips64.cc601
-rw-r--r--deps/v8/test/cctest/test-extra.js14
-rw-r--r--deps/v8/test/cctest/test-feedback-vector.cc23
-rw-r--r--deps/v8/test/cctest/test-fuzz-arm64.cc4
-rw-r--r--deps/v8/test/cctest/test-global-object.cc6
-rw-r--r--deps/v8/test/cctest/test-hashing.cc2
-rw-r--r--deps/v8/test/cctest/test-hashmap.cc2
-rw-r--r--deps/v8/test/cctest/test-heap.cc942
-rw-r--r--deps/v8/test/cctest/test-hydrogen-types.cc1
-rw-r--r--deps/v8/test/cctest/test-log.cc2
-rw-r--r--deps/v8/test/cctest/test-microtask-delivery.cc25
-rw-r--r--deps/v8/test/cctest/test-migrations.cc3
-rw-r--r--deps/v8/test/cctest/test-parsing.cc682
-rw-r--r--deps/v8/test/cctest/test-profile-generator.cc17
-rw-r--r--deps/v8/test/cctest/test-reloc-info.cc7
-rw-r--r--deps/v8/test/cctest/test-serialize.cc42
-rw-r--r--deps/v8/test/cctest/test-spaces.cc16
-rw-r--r--deps/v8/test/cctest/test-strings.cc2
-rw-r--r--deps/v8/test/cctest/test-thread-termination.cc16
-rw-r--r--deps/v8/test/cctest/test-threads.cc11
-rw-r--r--deps/v8/test/cctest/test-typedarrays.cc2
-rw-r--r--deps/v8/test/cctest/test-types.cc78
-rw-r--r--deps/v8/test/cctest/test-unboxed-doubles.cc10
-rw-r--r--deps/v8/test/cctest/test-utils-arm64.h6
-rw-r--r--deps/v8/test/cctest/test-version.cc3
-rw-r--r--deps/v8/test/cctest/test-weakmaps.cc16
-rw-r--r--deps/v8/test/cctest/test-weaksets.cc13
-rw-r--r--deps/v8/test/cctest/trace-extension.cc3
82 files changed, 12316 insertions, 4980 deletions
diff --git a/deps/v8/test/cctest/cctest.gyp b/deps/v8/test/cctest/cctest.gyp
index 276ebd2f97..bcbbe7b226 100644
--- a/deps/v8/test/cctest/cctest.gyp
+++ b/deps/v8/test/cctest/cctest.gyp
@@ -54,8 +54,6 @@
'compiler/test-basic-block-profiler.cc',
'compiler/test-branch-combine.cc',
'compiler/test-changes-lowering.cc',
- 'compiler/test-codegen-deopt.cc',
- 'compiler/test-control-reducer.cc',
'compiler/test-gap-resolver.cc',
'compiler/test-graph-visualizer.cc',
'compiler/test-instruction.cc',
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index bade26308f..cc9edc801f 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -93,6 +93,7 @@ class TestHeap : public i::Heap {
using i::Heap::AllocateByteArray;
using i::Heap::AllocateFixedArray;
using i::Heap::AllocateHeapNumber;
+ using i::Heap::AllocateFloat32x4;
using i::Heap::AllocateJSObject;
using i::Heap::AllocateJSObjectFromMap;
using i::Heap::AllocateMap;
@@ -397,6 +398,13 @@ static inline v8::Local<v8::Value> CompileRun(const char* source) {
}
+// Helper functions that compile and run the source.
+static inline v8::MaybeLocal<v8::Value> CompileRun(
+ v8::Local<v8::Context> context, const char* source) {
+ return v8::Script::Compile(v8_str(source))->Run(context);
+}
+
+
// Compiles source as an ES6 module.
static inline v8::Local<v8::Value> CompileRunModule(const char* source) {
v8::ScriptCompiler::Source script_source(v8_str(source));
@@ -504,8 +512,8 @@ static inline void ExpectUndefined(const char* code) {
// Helper function that simulates a full new-space in the heap.
static inline bool FillUpOnePage(v8::internal::NewSpace* space) {
- v8::internal::AllocationResult allocation =
- space->AllocateRaw(v8::internal::Page::kMaxRegularHeapObjectSize);
+ v8::internal::AllocationResult allocation = space->AllocateRawUnaligned(
+ v8::internal::Page::kMaxRegularHeapObjectSize);
if (allocation.IsRetry()) return false;
v8::internal::HeapObject* free_space = NULL;
CHECK(allocation.To(&free_space));
@@ -524,7 +532,7 @@ static inline void AllocateAllButNBytes(v8::internal::NewSpace* space,
int new_linear_size = space_remaining - extra_bytes;
if (new_linear_size == 0) return;
v8::internal::AllocationResult allocation =
- space->AllocateRaw(new_linear_size);
+ space->AllocateRawUnaligned(new_linear_size);
v8::internal::HeapObject* free_space = NULL;
CHECK(allocation.To(&free_space));
space->heap()->CreateFillerObjectAt(free_space->address(), new_linear_size);
@@ -561,7 +569,7 @@ static inline void SimulateIncrementalMarking(i::Heap* heap) {
}
CHECK(marking->IsMarking() || marking->IsStopped());
if (marking->IsStopped()) {
- marking->Start();
+ marking->Start(i::Heap::kNoGCFlags);
}
CHECK(marking->IsMarking());
while (!marking->IsComplete()) {
@@ -574,6 +582,18 @@ static inline void SimulateIncrementalMarking(i::Heap* heap) {
}
+static void DummyDebugEventListener(
+ const v8::Debug::EventDetails& event_details) {}
+
+
+static inline void EnableDebugger() {
+ v8::Debug::SetDebugEventListener(&DummyDebugEventListener);
+}
+
+
+static inline void DisableDebugger() { v8::Debug::SetDebugEventListener(NULL); }
+
+
// Helper class for new allocations tracking and checking.
// To use checking of JS allocations tracking in a test,
// just create an instance of this class.
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index 9c4f6ccf05..68c570edcc 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -64,11 +64,13 @@
# are actually 13 * 38 * 5 * 128 = 316160 individual tests hidden here.
'test-parsing/ParserSync': [PASS, NO_VARIANTS],
- # This tests only the type system, so there is no point in running several
- # variants.
+ # This tests only the type system, no point in running several variants.
'test-hydrogen-types/*': [PASS, NO_VARIANTS],
'test-types/*': [PASS, NO_VARIANTS],
+ # This tests API threading, no point in running several variants.
+ 'test-api/Threading*': [PASS, NO_VARIANTS],
+
# The cpu profiler tests are notoriously flaky.
# BUG(2999). (test/cpu-profiler/CollectCpuProfile)
# BUG(3287). (test-cpu-profiler/SampleWhenFrameIsNotSetup)
@@ -97,11 +99,7 @@
##############################################################################
# TurboFan compiler failures.
- # TODO(mstarzinger): control edges are messed up in exception tests.
- 'test-run-jsexceptions/*': [PASS, NO_VARIANTS],
-
# Some tests are just too slow to run for now.
- 'test-api/Threading*': [PASS, NO_VARIANTS],
'test-heap/IncrementalMarkingStepMakesBigProgressWithLargeObjects': [PASS, NO_VARIANTS],
'test-heap-profiler/ManyLocalsInSharedContext': [PASS, NO_VARIANTS],
'test-serialize/SerializeToplevelLargeCodeObject': [PASS, NO_VARIANTS],
@@ -119,12 +117,6 @@
'test-debug/ScriptBreakPointByIdThroughJavaScript': [PASS, NO_VARIANTS],
'test-debug/ScriptBreakPointByNameThroughJavaScript': [PASS, NO_VARIANTS],
- # TODO(jarin): Cannot lazy-deoptimize from conversions before comparisons.
- 'test-js-typed-lowering/OrderCompareEffects': [SKIP],
-
- # TODO(jochen): Reenable after we removed the CHECK() from the marking queue.
- 'test-mark-compact/MarkingDeque': [SKIP],
-
############################################################################
# Slow tests.
'test-api/Threading1': [PASS, ['mode == debug', SLOW]],
@@ -194,6 +186,12 @@
['msan == True', {
# ICU upstream issues.
'test-strings/CountBreakIterator': [SKIP],
+
+ # Slow tests.
+ 'test-api/Threading1': [PASS, SLOW],
+ 'test-api/Threading2': [PASS, SLOW],
+ 'test-api/Threading3': [PASS, SLOW],
+ 'test-api/Threading4': [PASS, SLOW],
}], # 'msan == True'
##############################################################################
@@ -258,6 +256,9 @@
['arch == mipsel or arch == mips', {
'test-cpu-profiler/CollectDeoptEvents': [PASS, FAIL],
+ # TODO(mips-team): Improve code-size on large RegExp's.
+ 'test-heap/TestSizeOfRegExpCode': [SKIP],
+
# BUG(1075): Unresolved crashes on MIPS also.
'test-serialize/Deserialize': [SKIP],
'test-serialize/DeserializeFromSecondSerializationAndRunScript2': [SKIP],
@@ -271,12 +272,8 @@
'test-api/ExternalArrays': [PASS, NO_VARIANTS],
# TODO(mips-team): Currently fails on mips board.
- 'test-simplified-lowering/RunNumberMultiply_TruncatingToUint32': [SKIP],
- 'test-simplified-lowering/RunNumberDivide_2_TruncatingToUint32': [SKIP],
'test-parsing/TooManyArguments': [SKIP],
'test-api/Threading3': [SKIP],
- 'test-api/RequestInterruptTestWithNativeAccessor': [SKIP],
- 'test-api/RequestInterruptTestWithAccessor': [SKIP],
}], # 'arch == mips'
##############################################################################
@@ -295,12 +292,7 @@
##############################################################################
['arch == x87', {
-
- # Test requires turbofan:
- 'codegen-tester/CompareWrapper': [SKIP],
- 'codegen-tester/ParametersEqual': [SKIP],
- 'test-simplified-lowering/LowerStringOps_to_call_and_compare': [SKIP],
- 'test-serialize/SerializeInternalReference': [FAIL],
+ 'test-run-machops/RunFloat64InsertLowWord32': [SKIP]
}], # 'arch == x87'
##############################################################################
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]));
diff --git a/deps/v8/test/cctest/gay-fixed.cc b/deps/v8/test/cctest/gay-fixed.cc
index 81463ac1fa..86ebb24cd8 100644
--- a/deps/v8/test/cctest/gay-fixed.cc
+++ b/deps/v8/test/cctest/gay-fixed.cc
@@ -100046,4 +100046,5 @@ Vector<const PrecomputedFixed> PrecomputedFixedRepresentations() {
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/gay-precision.cc b/deps/v8/test/cctest/gay-precision.cc
index 6ab2715fea..68d29f8cd5 100644
--- a/deps/v8/test/cctest/gay-precision.cc
+++ b/deps/v8/test/cctest/gay-precision.cc
@@ -100047,4 +100047,5 @@ Vector<const PrecomputedPrecision> PrecomputedPrecisionRepresentations() {
number_elements);
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/gay-shortest.cc b/deps/v8/test/cctest/gay-shortest.cc
index 896ea4c514..456055392c 100644
--- a/deps/v8/test/cctest/gay-shortest.cc
+++ b/deps/v8/test/cctest/gay-shortest.cc
@@ -100047,4 +100047,5 @@ Vector<const PrecomputedShortest> PrecomputedShortestRepresentations() {
number_elements);
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/print-extension.cc b/deps/v8/test/cctest/print-extension.cc
index d1af3596e8..33f33cafc2 100644
--- a/deps/v8/test/cctest/print-extension.cc
+++ b/deps/v8/test/cctest/print-extension.cc
@@ -48,4 +48,5 @@ void PrintExtension::Print(const v8::FunctionCallbackInfo<v8::Value>& args) {
printf("\n");
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/profiler-extension.cc b/deps/v8/test/cctest/profiler-extension.cc
index 263fc4f38d..c8cb0fb7ca 100644
--- a/deps/v8/test/cctest/profiler-extension.cc
+++ b/deps/v8/test/cctest/profiler-extension.cc
@@ -72,4 +72,5 @@ void ProfilerExtension::StopProfiling(
: v8::String::Empty(args.GetIsolate()));
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/test-accessors.cc b/deps/v8/test/cctest/test-accessors.cc
index ac631757b2..14303e2371 100644
--- a/deps/v8/test/cctest/test-accessors.cc
+++ b/deps/v8/test/cctest/test-accessors.cc
@@ -552,7 +552,7 @@ THREADED_TEST(AccessorPropertyCrossContext) {
v8::Handle<v8::Function> fun = v8::Function::New(isolate, check_contexts);
LocalContext switch_context;
switch_context->Global()->Set(v8_str("fun"), fun);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
expected_current_context = env.local();
expected_calling_context = switch_context.local();
CompileRun(
diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc
index aba08e23d7..2e9bc74a92 100644
--- a/deps/v8/test/cctest/test-api-interceptors.cc
+++ b/deps/v8/test/cctest/test-api-interceptors.cc
@@ -1007,10 +1007,11 @@ THREADED_TEST(PropertyHandlerInPrototype) {
}
+bool is_bootstrapping = false;
static void PrePropertyHandlerGet(
Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
- if (v8_str("pre")->Equals(key)) {
+ if (!is_bootstrapping && v8_str("pre")->Equals(key)) {
info.GetReturnValue().Set(v8_str("PrePropertyHandler: pre"));
}
}
@@ -1018,7 +1019,7 @@ static void PrePropertyHandlerGet(
static void PrePropertyHandlerQuery(
Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
- if (v8_str("pre")->Equals(key)) {
+ if (!is_bootstrapping && v8_str("pre")->Equals(key)) {
info.GetReturnValue().Set(static_cast<int32_t>(v8::None));
}
}
@@ -1030,7 +1031,9 @@ THREADED_TEST(PrePropertyHandler) {
v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
desc->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
PrePropertyHandlerGet, 0, PrePropertyHandlerQuery));
+ is_bootstrapping = true;
LocalContext env(NULL, desc->InstanceTemplate());
+ is_bootstrapping = false;
CompileRun("var pre = 'Object: pre'; var on = 'Object: on';");
v8::Handle<Value> result_pre = CompileRun("pre");
CHECK(v8_str("PrePropertyHandler: pre")->Equals(result_pre));
@@ -1658,6 +1661,12 @@ THREADED_TEST(IndexedInterceptorWithNoSetter) {
}
+static bool AccessAlwaysBlocked(Local<v8::Object> global, Local<Value> name,
+ v8::AccessType type, Local<Value> data) {
+ return false;
+}
+
+
THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -1665,9 +1674,10 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
templ->SetHandler(
v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
+ templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, nullptr);
+
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
- obj->TurnOnAccessCheck();
context->Global()->Set(v8_str("obj"), obj);
const char* code =
@@ -1686,46 +1696,6 @@ THREADED_TEST(IndexedInterceptorWithAccessorCheck) {
}
-THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) {
- i::FLAG_allow_natives_syntax = true;
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope scope(isolate);
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetHandler(
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
-
- LocalContext context;
- Local<v8::Object> obj = templ->NewInstance();
- context->Global()->Set(v8_str("obj"), obj);
-
- const char* code =
- "var result = 'PASSED';"
- "for (var i = 0; i < 100; i++) {"
- " var expected = i;"
- " if (i == 5) {"
- " %EnableAccessChecks(obj);"
- " }"
- " try {"
- " var v = obj[i];"
- " if (i == 5) {"
- " result = 'Should not have reached this!';"
- " break;"
- " } else if (v != expected) {"
- " result = 'Wrong value ' + v + ' at iteration ' + i;"
- " break;"
- " }"
- " } catch (e) {"
- " if (i != 5) {"
- " result = e;"
- " }"
- " }"
- " if (i == 5) %DisableAccessChecks(obj);"
- "}"
- "result";
- ExpectString(code, "PASSED");
-}
-
-
THREADED_TEST(IndexedInterceptorWithDifferentIndices) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -2021,9 +1991,9 @@ THREADED_TEST(Enumerators) {
"k.a = 0;"
"k[5] = 0;"
"k.b = 0;"
- "k[4294967295] = 0;"
+ "k[4294967294] = 0;"
"k.c = 0;"
- "k[4294967296] = 0;"
+ "k[4294967295] = 0;"
"k.d = 0;"
"k[140000] = 0;"
"k.e = 0;"
@@ -2046,7 +2016,7 @@ THREADED_TEST(Enumerators) {
CHECK(v8_str("10")->Equals(result->Get(v8::Integer::New(isolate, 1))));
CHECK(v8_str("140000")->Equals(result->Get(v8::Integer::New(isolate, 2))));
CHECK(
- v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 3))));
+ v8_str("4294967294")->Equals(result->Get(v8::Integer::New(isolate, 3))));
// Indexed interceptor properties in the order they are returned
// from the enumerator interceptor.
CHECK(v8_str("0")->Equals(result->Get(v8::Integer::New(isolate, 4))));
@@ -2056,7 +2026,7 @@ THREADED_TEST(Enumerators) {
CHECK(v8_str("b")->Equals(result->Get(v8::Integer::New(isolate, 7))));
CHECK(v8_str("c")->Equals(result->Get(v8::Integer::New(isolate, 8))));
CHECK(
- v8_str("4294967296")->Equals(result->Get(v8::Integer::New(isolate, 9))));
+ v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 9))));
CHECK(v8_str("d")->Equals(result->Get(v8::Integer::New(isolate, 10))));
CHECK(v8_str("e")->Equals(result->Get(v8::Integer::New(isolate, 11))));
CHECK(v8_str("30000000000")
@@ -2533,7 +2503,8 @@ static int interceptor_call_count = 0;
static void InterceptorICRefErrorGetter(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
- if (v8_str("x")->Equals(name) && interceptor_call_count++ < 20) {
+ if (!is_bootstrapping && v8_str("x")->Equals(name) &&
+ interceptor_call_count++ < 20) {
info.GetReturnValue().Set(call_ic_function2);
}
}
@@ -2548,7 +2519,9 @@ THREADED_TEST(InterceptorICReferenceErrors) {
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetHandler(
v8::NamedPropertyHandlerConfiguration(InterceptorICRefErrorGetter));
+ is_bootstrapping = true;
LocalContext context(0, templ, v8::Handle<Value>());
+ is_bootstrapping = false;
call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run();
v8::Handle<Value> value = CompileRun(
"function f() {"
@@ -2577,6 +2550,7 @@ static int interceptor_ic_exception_get_count = 0;
static void InterceptorICExceptionGetter(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
+ if (is_bootstrapping) return;
if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) {
info.GetReturnValue().Set(call_ic_function3);
}
@@ -2596,7 +2570,9 @@ THREADED_TEST(InterceptorICGetterExceptions) {
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->SetHandler(
v8::NamedPropertyHandlerConfiguration(InterceptorICExceptionGetter));
+ is_bootstrapping = true;
LocalContext context(0, templ, v8::Handle<Value>());
+ is_bootstrapping = false;
call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run();
v8::Handle<Value> value = CompileRun(
"function f() {"
@@ -2975,7 +2951,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
LocalContext context;
AccessCheckData access_check_data;
- access_check_data.result = false;
+ access_check_data.result = true;
access_check_data.count = 0;
ShouldInterceptData intercept_data_0;
@@ -3007,7 +2983,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
auto checked = v8::ObjectTemplate::New(isolate);
checked->SetAccessCheckCallbacks(
SimpleAccessChecker, nullptr,
- BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false);
+ BuildWrappedObject<AccessCheckData>(isolate, &access_check_data));
context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance());
context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance());
@@ -3018,14 +2994,12 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
"checked.__proto__ = intercepted_1;"
"intercepted_1.__proto__ = intercepted_0;");
- checked_instance->TurnOnAccessCheck();
- CHECK_EQ(0, access_check_data.count);
+ CHECK_EQ(3, access_check_data.count);
- access_check_data.result = true;
ExpectInt32("checked.whatever", 17);
CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')")
->IsUndefined());
- CHECK_EQ(2, access_check_data.count);
+ CHECK_EQ(5, access_check_data.count);
access_check_data.result = false;
ExpectInt32("checked.whatever", intercept_data_0.value);
@@ -3034,7 +3008,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(4, access_check_data.count);
+ CHECK_EQ(7, access_check_data.count);
intercept_data_1.should_intercept = true;
ExpectInt32("checked.whatever", intercept_data_1.value);
@@ -3043,7 +3017,7 @@ THREADED_TEST(NamedAllCanReadInterceptor) {
CompileRun("Object.getOwnPropertyDescriptor(checked, 'whatever')");
CHECK(try_catch.HasCaught());
}
- CHECK_EQ(6, access_check_data.count);
+ CHECK_EQ(9, access_check_data.count);
}
@@ -3053,7 +3027,7 @@ THREADED_TEST(IndexedAllCanReadInterceptor) {
LocalContext context;
AccessCheckData access_check_data;
- access_check_data.result = false;
+ access_check_data.result = true;
access_check_data.count = 0;
ShouldInterceptData intercept_data_0;
@@ -3085,7 +3059,7 @@ THREADED_TEST(IndexedAllCanReadInterceptor) {
auto checked = v8::ObjectTemplate::New(isolate);
checked->SetAccessCheckCallbacks(
SimpleAccessChecker, nullptr,
- BuildWrappedObject<AccessCheckData>(isolate, &access_check_data), false);
+ BuildWrappedObject<AccessCheckData>(isolate, &access_check_data));
context->Global()->Set(v8_str("intercepted_0"), intercepted_0->NewInstance());
context->Global()->Set(v8_str("intercepted_1"), intercepted_1->NewInstance());
@@ -3096,27 +3070,30 @@ THREADED_TEST(IndexedAllCanReadInterceptor) {
"checked.__proto__ = intercepted_1;"
"intercepted_1.__proto__ = intercepted_0;");
- checked_instance->TurnOnAccessCheck();
- CHECK_EQ(0, access_check_data.count);
+ CHECK_EQ(3, access_check_data.count);
access_check_data.result = true;
ExpectInt32("checked[15]", 17);
CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')")
->IsUndefined());
- CHECK_EQ(3, access_check_data.count);
+ CHECK_EQ(5, access_check_data.count);
access_check_data.result = false;
ExpectInt32("checked[15]", intercept_data_0.value);
- // Note: this should throw but without a LookupIterator it's complicated.
- CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')")
- ->IsUndefined());
- CHECK_EQ(6, access_check_data.count);
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("Object.getOwnPropertyDescriptor(checked, '15')");
+ CHECK(try_catch.HasCaught());
+ }
+ CHECK_EQ(7, access_check_data.count);
intercept_data_1.should_intercept = true;
ExpectInt32("checked[15]", intercept_data_1.value);
- // Note: this should throw but without a LookupIterator it's complicated.
- CHECK(!CompileRun("Object.getOwnPropertyDescriptor(checked, '15')")
- ->IsUndefined());
+ {
+ v8::TryCatch try_catch(isolate);
+ CompileRun("Object.getOwnPropertyDescriptor(checked, '15')");
+ CHECK(try_catch.HasCaught());
+ }
CHECK_EQ(9, access_check_data.count);
}
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 145d9bc64d..e464a67e00 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -190,7 +190,7 @@ static void TestSignature(const char* loop_js, Local<Value> receiver,
signature_callback_count = 0;
signature_expected_receiver = receiver;
bool expected_to_throw = receiver.IsEmpty();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(source.start());
CHECK_EQ(expected_to_throw, try_catch.HasCaught());
if (!expected_to_throw) {
@@ -697,7 +697,7 @@ THREADED_TEST(NewExternalForVeryLongString) {
auto isolate = CcTest::isolate();
{
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
RandomLengthOneByteResource r(1 << 30);
v8::Local<v8::String> str = v8::String::NewExternal(isolate, &r);
CHECK(str.IsEmpty());
@@ -706,7 +706,7 @@ THREADED_TEST(NewExternalForVeryLongString) {
{
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
RandomLengthResource r(1 << 30);
v8::Local<v8::String> str = v8::String::NewExternal(isolate, &r);
CHECK(str.IsEmpty());
@@ -1590,6 +1590,17 @@ THREADED_TEST(StringObject) {
}
+TEST(StringObjectDelete) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+ v8::Handle<Value> boxed_string = CompileRun("new String(\"test\")");
+ CHECK(boxed_string->IsStringObject());
+ v8::Handle<v8::Object> str_obj = boxed_string.As<v8::Object>();
+ CHECK(!str_obj->Delete(2));
+ CHECK(!str_obj->Delete(v8_num(2)));
+}
+
+
THREADED_TEST(NumberObject) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -2248,12 +2259,24 @@ THREADED_TEST(IdentityHash) {
}
-THREADED_TEST(GlobalProxyIdentityHash) {
+void GlobalProxyIdentityHash(bool set_in_js) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
v8::HandleScope scope(isolate);
Handle<Object> global_proxy = env->Global();
- int hash1 = global_proxy->GetIdentityHash();
+ i::Handle<i::Object> i_global_proxy = v8::Utils::OpenHandle(*global_proxy);
+ env->Global()->Set(v8_str("global"), global_proxy);
+ i::Handle<i::Object> original_hash;
+ if (set_in_js) {
+ CompileRun("var m = new Set(); m.add(global);");
+ original_hash = i::Handle<i::Object>(i_global_proxy->GetHash(), i_isolate);
+ } else {
+ original_hash = i::Handle<i::Object>(
+ i::Object::GetOrCreateHash(i_isolate, i_global_proxy));
+ }
+ CHECK(original_hash->IsSmi());
+ int32_t hash1 = i::Handle<i::Smi>::cast(original_hash)->value();
// Hash should be retained after being detached.
env->DetachGlobal();
int hash2 = global_proxy->GetIdentityHash();
@@ -2267,6 +2290,12 @@ THREADED_TEST(GlobalProxyIdentityHash) {
}
+THREADED_TEST(GlobalProxyIdentityHash) {
+ GlobalProxyIdentityHash(true);
+ GlobalProxyIdentityHash(false);
+}
+
+
TEST(SymbolIdentityHash) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -2434,65 +2463,6 @@ THREADED_TEST(SymbolTemplateProperties) {
}
-THREADED_TEST(PrivateProperties) {
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
-
- v8::Local<v8::Object> obj = v8::Object::New(isolate);
- v8::Local<v8::Private> priv1 = v8::Private::New(isolate);
- v8::Local<v8::Private> priv2 =
- v8::Private::New(isolate, v8_str("my-private"));
-
- CcTest::heap()->CollectAllGarbage();
-
- CHECK(priv2->Name()->Equals(v8::String::NewFromUtf8(isolate, "my-private")));
-
- // Make sure delete of a non-existent private symbol property works.
- CHECK(obj->DeletePrivate(priv1));
- CHECK(!obj->HasPrivate(priv1));
-
- CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 1503)));
- CHECK(obj->HasPrivate(priv1));
- CHECK_EQ(1503, obj->GetPrivate(priv1)->Int32Value());
- CHECK(obj->SetPrivate(priv1, v8::Integer::New(isolate, 2002)));
- CHECK(obj->HasPrivate(priv1));
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
-
- CHECK_EQ(0u, obj->GetOwnPropertyNames()->Length());
- unsigned num_props = obj->GetPropertyNames()->Length();
- CHECK(obj->Set(v8::String::NewFromUtf8(isolate, "bla"),
- v8::Integer::New(isolate, 20)));
- CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length());
- CHECK_EQ(num_props + 1, obj->GetPropertyNames()->Length());
-
- CcTest::heap()->CollectAllGarbage();
-
- // Add another property and delete it afterwards to force the object in
- // slow case.
- CHECK(obj->SetPrivate(priv2, v8::Integer::New(isolate, 2008)));
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(2008, obj->GetPrivate(priv2)->Int32Value());
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length());
-
- CHECK(obj->HasPrivate(priv1));
- CHECK(obj->HasPrivate(priv2));
- CHECK(obj->DeletePrivate(priv2));
- CHECK(obj->HasPrivate(priv1));
- CHECK(!obj->HasPrivate(priv2));
- CHECK_EQ(2002, obj->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(1u, obj->GetOwnPropertyNames()->Length());
-
- // Private properties are inherited (for the time being).
- v8::Local<v8::Object> child = v8::Object::New(isolate);
- child->SetPrototype(obj);
- CHECK(child->HasPrivate(priv1));
- CHECK_EQ(2002, child->GetPrivate(priv1)->Int32Value());
- CHECK_EQ(0u, child->GetOwnPropertyNames()->Length());
-}
-
-
THREADED_TEST(GlobalSymbols) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -2541,28 +2511,6 @@ THREADED_TEST(WellKnownSymbols) {
}
-THREADED_TEST(GlobalPrivates) {
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(isolate);
-
- v8::Local<String> name = v8_str("my-private");
- v8::Local<v8::Private> glob = v8::Private::ForApi(isolate, name);
- v8::Local<v8::Object> obj = v8::Object::New(isolate);
- CHECK(obj->SetPrivate(glob, v8::Integer::New(isolate, 3)));
-
- v8::Local<v8::Private> glob2 = v8::Private::ForApi(isolate, name);
- CHECK(obj->HasPrivate(glob2));
-
- v8::Local<v8::Private> priv = v8::Private::New(isolate, name);
- CHECK(!obj->HasPrivate(priv));
-
- CompileRun("var intern = %CreateGlobalPrivateSymbol('my-private')");
- v8::Local<Value> intern = env->Global()->Get(v8_str("intern"));
- CHECK(!obj->Has(intern));
-}
-
-
class ScopedArrayBufferContents {
public:
explicit ScopedArrayBufferContents(const v8::ArrayBuffer::Contents& contents)
@@ -2846,6 +2794,136 @@ THREADED_TEST(ArrayBuffer_NeuteringScript) {
}
+class ScopedSharedArrayBufferContents {
+ public:
+ explicit ScopedSharedArrayBufferContents(
+ const v8::SharedArrayBuffer::Contents& contents)
+ : contents_(contents) {}
+ ~ScopedSharedArrayBufferContents() { free(contents_.Data()); }
+ void* Data() const { return contents_.Data(); }
+ size_t ByteLength() const { return contents_.ByteLength(); }
+
+ private:
+ const v8::SharedArrayBuffer::Contents contents_;
+};
+
+
+THREADED_TEST(SharedArrayBuffer_ApiInternalToExternal) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ Local<v8::SharedArrayBuffer> ab = v8::SharedArrayBuffer::New(isolate, 1024);
+ CheckInternalFieldsAreZero(ab);
+ CHECK_EQ(1024, static_cast<int>(ab->ByteLength()));
+ CHECK(!ab->IsExternal());
+ CcTest::heap()->CollectAllGarbage();
+
+ ScopedSharedArrayBufferContents ab_contents(ab->Externalize());
+ CHECK(ab->IsExternal());
+
+ CHECK_EQ(1024, static_cast<int>(ab_contents.ByteLength()));
+ uint8_t* data = static_cast<uint8_t*>(ab_contents.Data());
+ DCHECK(data != NULL);
+ env->Global()->Set(v8_str("ab"), ab);
+
+ v8::Handle<v8::Value> result = CompileRun("ab.byteLength");
+ CHECK_EQ(1024, result->Int32Value());
+
+ result = CompileRun(
+ "var u8 = new Uint8Array(ab);"
+ "u8[0] = 0xFF;"
+ "u8[1] = 0xAA;"
+ "u8.length");
+ CHECK_EQ(1024, result->Int32Value());
+ CHECK_EQ(0xFF, data[0]);
+ CHECK_EQ(0xAA, data[1]);
+ data[0] = 0xCC;
+ data[1] = 0x11;
+ result = CompileRun("u8[0] + u8[1]");
+ CHECK_EQ(0xDD, result->Int32Value());
+}
+
+
+THREADED_TEST(SharedArrayBuffer_JSInternalToExternal) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+
+ v8::Local<v8::Value> result = CompileRun(
+ "var ab1 = new SharedArrayBuffer(2);"
+ "var u8_a = new Uint8Array(ab1);"
+ "u8_a[0] = 0xAA;"
+ "u8_a[1] = 0xFF; u8_a.buffer");
+ Local<v8::SharedArrayBuffer> ab1 = Local<v8::SharedArrayBuffer>::Cast(result);
+ CheckInternalFieldsAreZero(ab1);
+ CHECK_EQ(2, static_cast<int>(ab1->ByteLength()));
+ CHECK(!ab1->IsExternal());
+ ScopedSharedArrayBufferContents ab1_contents(ab1->Externalize());
+ CHECK(ab1->IsExternal());
+
+ result = CompileRun("ab1.byteLength");
+ CHECK_EQ(2, result->Int32Value());
+ result = CompileRun("u8_a[0]");
+ CHECK_EQ(0xAA, result->Int32Value());
+ result = CompileRun("u8_a[1]");
+ CHECK_EQ(0xFF, result->Int32Value());
+ result = CompileRun(
+ "var u8_b = new Uint8Array(ab1);"
+ "u8_b[0] = 0xBB;"
+ "u8_a[0]");
+ CHECK_EQ(0xBB, result->Int32Value());
+ result = CompileRun("u8_b[1]");
+ CHECK_EQ(0xFF, result->Int32Value());
+
+ CHECK_EQ(2, static_cast<int>(ab1_contents.ByteLength()));
+ uint8_t* ab1_data = static_cast<uint8_t*>(ab1_contents.Data());
+ CHECK_EQ(0xBB, ab1_data[0]);
+ CHECK_EQ(0xFF, ab1_data[1]);
+ ab1_data[0] = 0xCC;
+ ab1_data[1] = 0x11;
+ result = CompileRun("u8_a[0] + u8_a[1]");
+ CHECK_EQ(0xDD, result->Int32Value());
+}
+
+
+THREADED_TEST(SharedArrayBuffer_External) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ i::ScopedVector<uint8_t> my_data(100);
+ memset(my_data.start(), 0, 100);
+ Local<v8::SharedArrayBuffer> ab3 =
+ v8::SharedArrayBuffer::New(isolate, my_data.start(), 100);
+ CheckInternalFieldsAreZero(ab3);
+ CHECK_EQ(100, static_cast<int>(ab3->ByteLength()));
+ CHECK(ab3->IsExternal());
+
+ env->Global()->Set(v8_str("ab3"), ab3);
+
+ v8::Handle<v8::Value> result = CompileRun("ab3.byteLength");
+ CHECK_EQ(100, result->Int32Value());
+
+ result = CompileRun(
+ "var u8_b = new Uint8Array(ab3);"
+ "u8_b[0] = 0xBB;"
+ "u8_b[1] = 0xCC;"
+ "u8_b.length");
+ CHECK_EQ(100, result->Int32Value());
+ CHECK_EQ(0xBB, my_data[0]);
+ CHECK_EQ(0xCC, my_data[1]);
+ my_data[0] = 0xCC;
+ my_data[1] = 0x11;
+ result = CompileRun("u8_b[0] + u8_b[1]");
+ CHECK_EQ(0xDD, result->Int32Value());
+}
+
+
THREADED_TEST(HiddenProperties) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -3934,7 +4012,7 @@ THREADED_TEST(ScriptException) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
Local<Script> script = v8_compile("throw 'panama!';");
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
Local<Value> result = script->Run();
CHECK(result.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -3947,7 +4025,7 @@ TEST(TryCatchCustomException) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"function CustomError() { this.a = 'b'; }"
"(function f() { throw new CustomError(); })();");
@@ -4039,8 +4117,9 @@ TEST(MessageHandler2) {
static void check_message_3(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
CHECK(message->IsSharedCrossOrigin());
- CHECK(message->GetScriptOrigin().ResourceIsSharedCrossOrigin()->Value());
- CHECK(message->GetScriptOrigin().ResourceIsEmbedderDebugScript()->Value());
+ CHECK(message->GetScriptOrigin().Options().IsSharedCrossOrigin());
+ CHECK(message->GetScriptOrigin().Options().IsEmbedderDebugScript());
+ CHECK(message->GetScriptOrigin().Options().IsOpaque());
CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue());
CHECK_EQ(7.40, message->GetScriptOrigin().SourceMapUrl()->NumberValue());
message_received = true;
@@ -4057,7 +4136,7 @@ TEST(MessageHandler3) {
v8::ScriptOrigin origin = v8::ScriptOrigin(
v8_str("6.75"), v8::Integer::New(isolate, 1),
v8::Integer::New(isolate, 2), v8::True(isolate), Handle<v8::Integer>(),
- v8::True(isolate), v8_str("7.40"));
+ v8::True(isolate), v8_str("7.40"), v8::True(isolate));
v8::Handle<v8::Script> script =
Script::Compile(v8_str("throw 'error'"), &origin);
script->Run();
@@ -4117,11 +4196,11 @@ TEST(MessageHandler5) {
CHECK(!message_received);
v8::V8::AddMessageListener(check_message_5a);
LocalContext context;
- v8::ScriptOrigin origin =
+ v8::ScriptOrigin origin1 =
v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
v8::Integer::New(isolate, 2), v8::True(isolate));
v8::Handle<v8::Script> script =
- Script::Compile(v8_str("throw 'error'"), &origin);
+ Script::Compile(v8_str("throw 'error'"), &origin1);
script->Run();
CHECK(message_received);
// clear out the message listener
@@ -4129,9 +4208,10 @@ TEST(MessageHandler5) {
message_received = false;
v8::V8::AddMessageListener(check_message_5b);
- origin = v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
- v8::Integer::New(isolate, 2), v8::False(isolate));
- script = Script::Compile(v8_str("throw 'error'"), &origin);
+ v8::ScriptOrigin origin2 =
+ v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1),
+ v8::Integer::New(isolate, 2), v8::False(isolate));
+ script = Script::Compile(v8_str("throw 'error'"), &origin2);
script->Run();
CHECK(message_received);
// clear out the message listener
@@ -4277,7 +4357,7 @@ THREADED_TEST(PropertyAttributes) {
Local<Value> fake_prop = v8_num(1);
CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(fake_prop));
// exception
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
Local<Value> exception =
CompileRun("({ toString: function() { throw 'exception';} })");
CHECK_EQ(v8::None, context->Global()->GetPropertyAttributes(exception));
@@ -4672,7 +4752,7 @@ void CCatcher(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
v8::HandleScope scope(args.GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
Local<Value> result = CompileRun(args[0]->ToString(args.GetIsolate()));
CHECK(!try_catch.HasCaught() || result.IsEmpty());
args.GetReturnValue().Set(try_catch.HasCaught());
@@ -4705,7 +4785,7 @@ THREADED_TEST(APIThrowTryCatch) {
templ->Set(v8_str("ThrowFromC"),
v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("ThrowFromC();");
CHECK(try_catch.HasCaught());
}
@@ -4870,6 +4950,26 @@ TEST(CustomErrorMessage) {
}
+static void check_custom_rethrowing_message(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ const char* uncaught_error = "Uncaught exception";
+ CHECK(message->Get()->Equals(v8_str(uncaught_error)));
+}
+
+
+TEST(CustomErrorRethrowsOnToString) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+ v8::V8::AddMessageListener(check_custom_rethrowing_message);
+
+ CompileRun(
+ "var e = { toString: function() { throw e; } };"
+ "try { throw e; } finally {}");
+
+ v8::V8::RemoveMessageListeners(check_custom_rethrowing_message);
+}
+
+
static void receive_message(v8::Handle<v8::Message> message,
v8::Handle<v8::Value> data) {
message->Get();
@@ -4901,7 +5001,7 @@ TEST(APIThrowMessageAndVerboseTryCatch) {
templ->Set(v8_str("ThrowFromC"),
v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
Local<Value> result = CompileRun("ThrowFromC();");
CHECK(try_catch.HasCaught());
@@ -4916,7 +5016,7 @@ TEST(APIStackOverflowAndVerboseTryCatch) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
v8::V8::AddMessageListener(receive_message);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
try_catch.SetVerbose(true);
Local<Value> result = CompileRun("function foo() { foo(); } foo();");
CHECK(try_catch.HasCaught());
@@ -4934,7 +5034,7 @@ THREADED_TEST(ExternalScriptException) {
v8::FunctionTemplate::New(isolate, ThrowFromC));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> result = CompileRun("ThrowFromC(); throw 'panama';");
CHECK(result.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -4956,7 +5056,7 @@ void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) {
Local<Value> fun = global->Get(v8_str("JSThrowCountDown"));
v8::Handle<Value> argv[] = {v8_num(count - 1), args[1], args[2], args[3]};
if (count % cInterval == 0) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
Local<Value> result = fun.As<Function>()->Call(global, 4, argv);
int expected = args[3]->Int32Value();
if (try_catch.HasCaught()) {
@@ -4993,7 +5093,7 @@ void JSCheck(const v8::FunctionCallbackInfo<v8::Value>& args) {
THREADED_TEST(EvalInTryFinally) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRun(
"(function() {"
" try {"
@@ -5121,7 +5221,7 @@ THREADED_TEST(ThrowValues) {
THREADED_TEST(CatchZero) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CHECK(!try_catch.HasCaught());
CompileRun("throw 10");
CHECK(try_catch.HasCaught());
@@ -5137,7 +5237,7 @@ THREADED_TEST(CatchZero) {
THREADED_TEST(CatchExceptionFromWith) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CHECK(!try_catch.HasCaught());
CompileRun("var o = {}; with (o) { throw 42; }");
CHECK(try_catch.HasCaught());
@@ -5147,7 +5247,7 @@ THREADED_TEST(CatchExceptionFromWith) {
THREADED_TEST(TryCatchAndFinallyHidingException) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CHECK(!try_catch.HasCaught());
CompileRun("function f(k) { try { this[k]; } finally { return 0; } };");
CompileRun("f({toString: function() { throw 42; }});");
@@ -5156,7 +5256,7 @@ THREADED_TEST(TryCatchAndFinallyHidingException) {
void WithTryCatch(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
}
@@ -5167,7 +5267,7 @@ THREADED_TEST(TryCatchAndFinally) {
context->Global()->Set(
v8_str("native_with_try_catch"),
v8::FunctionTemplate::New(isolate, WithTryCatch)->GetFunction());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!try_catch.HasCaught());
CompileRun(
"try {\n"
@@ -5181,7 +5281,7 @@ THREADED_TEST(TryCatchAndFinally) {
static void TryCatchNested1Helper(int depth) {
if (depth > 0) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
try_catch.SetVerbose(true);
TryCatchNested1Helper(depth - 1);
CHECK(try_catch.HasCaught());
@@ -5194,7 +5294,7 @@ static void TryCatchNested1Helper(int depth) {
static void TryCatchNested2Helper(int depth) {
if (depth > 0) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
try_catch.SetVerbose(true);
TryCatchNested2Helper(depth - 1);
CHECK(try_catch.HasCaught());
@@ -5212,7 +5312,7 @@ TEST(TryCatchNested) {
{
// Test nested try-catch with a native throw in the end.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
TryCatchNested1Helper(5);
CHECK(try_catch.HasCaught());
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E1"));
@@ -5220,7 +5320,7 @@ TEST(TryCatchNested) {
{
// Test nested try-catch with a JavaScript throw in the end.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
TryCatchNested2Helper(5);
CHECK(try_catch.HasCaught());
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "E2"));
@@ -5243,7 +5343,7 @@ void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) {
void TryCatchMixedNestingHelper(
const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CompileRunWithOrigin("throw new Error('a');\n", "inner", 0, 0);
CHECK(try_catch.HasCaught());
TryCatchMixedNestingCheck(&try_catch);
@@ -5260,7 +5360,7 @@ TEST(TryCatchMixedNesting) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::V8::Initialize();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("TryCatchMixedNestingHelper"),
v8::FunctionTemplate::New(isolate, TryCatchMixedNestingHelper));
@@ -5272,7 +5372,7 @@ TEST(TryCatchMixedNesting) {
void TryCatchNativeHelper(const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
args.GetIsolate()->ThrowException(v8_str("boom"));
CHECK(try_catch.HasCaught());
}
@@ -5282,7 +5382,7 @@ TEST(TryCatchNative) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::V8::Initialize();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("TryCatchNativeHelper"),
v8::FunctionTemplate::New(isolate, TryCatchNativeHelper));
@@ -5295,7 +5395,7 @@ TEST(TryCatchNative) {
void TryCatchNativeResetHelper(
const v8::FunctionCallbackInfo<v8::Value>& args) {
ApiTestFuzzer::Fuzz();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
args.GetIsolate()->ThrowException(v8_str("boom"));
CHECK(try_catch.HasCaught());
try_catch.Reset();
@@ -5307,7 +5407,7 @@ TEST(TryCatchNativeReset) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::V8::Initialize();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
templ->Set(v8_str("TryCatchNativeResetHelper"),
v8::FunctionTemplate::New(isolate, TryCatchNativeResetHelper));
@@ -5433,7 +5533,7 @@ THREADED_TEST(DefinePropertyOnAPIAccessor) {
CHECK_EQ(result->BooleanValue(), false);
// Make sure that it is not possible to redefine again
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::Utf8Value exception_value(try_catch.Exception());
@@ -5482,7 +5582,7 @@ THREADED_TEST(DefinePropertyOnDefineGetterSetter) {
CHECK_EQ(result->BooleanValue(), false);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
result = script_define->Run();
CHECK(try_catch.HasCaught());
String::Utf8Value exception_value(try_catch.Exception());
@@ -5604,7 +5704,7 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut")));
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"Object.defineProperty(obj1, 'x',"
"{get: function() { return 'func'; }})");
@@ -5614,7 +5714,7 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) {
0, strcmp(*exception_value, "TypeError: Cannot redefine property: x"));
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"Object.defineProperty(obj2, 'x',"
"{get: function() { return 'func'; }})");
@@ -7384,10 +7484,10 @@ THREADED_TEST(ToArrayIndex) {
str = v8_str("-42");
index = str->ToArrayIndex();
CHECK(index.IsEmpty());
- str = v8_str("4294967295");
+ str = v8_str("4294967294");
index = str->ToArrayIndex();
CHECK(!index.IsEmpty());
- CHECK_EQ(4294967295.0, index->Uint32Value());
+ CHECK_EQ(4294967294.0, index->Uint32Value());
v8::Handle<v8::Number> num = v8::Number::New(isolate, 1);
index = num->ToArrayIndex();
CHECK(!index.IsEmpty());
@@ -7450,7 +7550,7 @@ THREADED_TEST(ExceptionCreateMessage) {
v8::Local<v8::Object> global = context->Global();
global->Set(v8_str("throwV8Exception"), fun->GetFunction());
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
CompileRun(
"function f1() {\n"
" throwV8Exception();\n"
@@ -7504,6 +7604,22 @@ THREADED_TEST(ExceptionCreateMessage) {
}
+THREADED_TEST(ExceptionCreateMessageLength) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+
+ // Test that the message is not truncated.
+ TryCatch try_catch(context->GetIsolate());
+ CompileRun(
+ "var message = 'm';"
+ "while (message.length < 1000) message += message;"
+ "throw message;");
+ CHECK(try_catch.HasCaught());
+
+ CHECK_LT(1000, try_catch.Message()->Get()->Length());
+}
+
+
static void YGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
@@ -7684,7 +7800,7 @@ TEST(ExceptionInNativeScript) {
TEST(CompilationErrorUsingTryCatchHandler) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
v8_compile("This doesn't &*&@#$&*^ compile.");
CHECK(*try_catch.Exception());
CHECK(try_catch.HasCaught());
@@ -7694,7 +7810,7 @@ TEST(CompilationErrorUsingTryCatchHandler) {
TEST(TryCatchFinallyUsingTryCatchHandler) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
CompileRun("try { throw ''; } catch (e) {}");
CHECK(!try_catch.HasCaught());
CompileRun("try { throw ''; } finally {}");
@@ -7726,7 +7842,7 @@ TEST(TryCatchFinallyStoresMessageUsingTryCatchHandler) {
templ->Set(v8_str("CEvaluate"),
v8::FunctionTemplate::New(isolate, CEvaluate));
LocalContext context(0, templ);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("try {"
" CEvaluate('throw 1;');"
"} finally {"
@@ -7853,7 +7969,7 @@ THREADED_TEST(SecurityChecks) {
Context::Scope scope_env2(env2);
// Call cross_domain_call, it should throw an exception
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env1->GetIsolate());
Function::Cast(*spy2)->Call(env2->Global(), 0, NULL);
CHECK(try_catch.HasCaught());
}
@@ -8105,7 +8221,7 @@ TEST(ContextDetachGlobal) {
{
Local<Value> get_prop = global1->Get(v8_str("getProp"));
CHECK(get_prop->IsFunction());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env1->GetIsolate());
Local<Value> r = Function::Cast(*get_prop)->Call(global1, 0, NULL);
CHECK(!try_catch.HasCaught());
CHECK_EQ(1, r->Int32Value());
@@ -8229,7 +8345,6 @@ TEST(DetachedAccesses) {
}
Local<Object> env2_global = env2->Global();
- env2_global->TurnOnAccessCheck();
env2->DetachGlobal();
Local<Value> result;
@@ -8639,8 +8754,6 @@ THREADED_TEST(AccessControlGetOwnPropertyNames) {
TEST(SuperAccessControl) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_harmony_classes = true;
- i::FLAG_harmony_object_literals = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::ObjectTemplate> obj_template =
@@ -8650,7 +8763,7 @@ TEST(SuperAccessControl) {
env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var f = { m() { return super.hasOwnProperty; } }.m;"
"var m = %ToMethod(f, prohibited);"
@@ -8659,7 +8772,7 @@ TEST(SuperAccessControl) {
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var f = {m() { return super[42]; } }.m;"
"var m = %ToMethod(f, prohibited);"
@@ -8668,7 +8781,7 @@ TEST(SuperAccessControl) {
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var f = {m() { super.hasOwnProperty = function () {}; } }.m;"
"var m = %ToMethod(f, prohibited);"
@@ -8677,7 +8790,7 @@ TEST(SuperAccessControl) {
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"Object.defineProperty(Object.prototype, 'x', { set : function(){}});"
"var f = {"
@@ -8694,8 +8807,6 @@ TEST(SuperAccessControl) {
TEST(Regress470113) {
- i::FLAG_harmony_classes = true;
- i::FLAG_harmony_object_literals = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
v8::Handle<v8::ObjectTemplate> obj_template =
@@ -8705,7 +8816,7 @@ TEST(Regress470113) {
env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"'use strict';\n"
"class C extends Object {\n"
@@ -9446,7 +9557,7 @@ THREADED_TEST(SetPrototypeThrows) {
CHECK(o0->SetPrototype(o1));
// If setting the prototype leads to the cycle, SetPrototype should
// return false and keep VM in sane state.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!o1->SetPrototype(o0));
CHECK(!try_catch.HasCaught());
DCHECK(!CcTest::i_isolate()->has_pending_exception());
@@ -9466,7 +9577,7 @@ THREADED_TEST(FunctionRemovePrototype) {
context->Global()->Set(v8_str("fun"), fun);
CHECK(!CompileRun("'prototype' in fun")->BooleanValue());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("new fun()");
CHECK(try_catch.HasCaught());
@@ -9488,7 +9599,7 @@ THREADED_TEST(GetterSetterExceptions) {
"x.__defineGetter__('get', Throw);");
Local<v8::Object> x =
Local<v8::Object>::Cast(context->Global()->Get(v8_str("x")));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
x->Get(v8_str("get"));
x->Set(v8_str("set"), v8::Integer::New(isolate, 8));
@@ -9554,7 +9665,7 @@ THREADED_TEST(ConstructorForObject) {
instance_template->SetCallAsFunctionHandler(ConstructorCallback);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9630,7 +9741,7 @@ THREADED_TEST(ConstructorForObject) {
Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj2"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9655,7 +9766,7 @@ THREADED_TEST(ConstructorForObject) {
instance_template->SetCallAsFunctionHandler(ThrowValue);
Local<Object> instance = instance_template->NewInstance();
context->Global()->Set(v8_str("obj3"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9680,7 +9791,7 @@ THREADED_TEST(ConstructorForObject) {
Local<Function> function = function_template->GetFunction();
Local<Object> instance1 = function;
context->Global()->Set(v8_str("obj4"), instance1);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9764,7 +9875,7 @@ THREADED_TEST(EvalAliasedDynamic) {
CHECK_EQ(0, current->Global()->Get(v8_str("result2"))->Int32Value());
CHECK_EQ(1, current->Global()->Get(v8_str("result3"))->Int32Value());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(current->GetIsolate());
script = v8_compile(
"function f(x) { "
" var bar = 2;"
@@ -9807,7 +9918,7 @@ THREADED_TEST(CrossEval) {
// Check that global variables in current context are not visible in other
// context.
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
script = v8_compile("var bar = 42; other.eval('bar');");
Local<Value> result = script->Run();
CHECK(try_catch.HasCaught());
@@ -9881,7 +9992,7 @@ THREADED_TEST(EvalInDetachedGlobal) {
v8::Handle<v8::Value> x_value = CompileRun("fun('x')");
CHECK_EQ(42, x_value->Int32Value());
context0->DetachGlobal();
- v8::TryCatch catcher;
+ v8::TryCatch catcher(isolate);
x_value = CompileRun("fun('x')");
CHECK_EQ(42, x_value->Int32Value());
context1->Exit();
@@ -9939,7 +10050,7 @@ THREADED_TEST(CallAsFunction) {
instance_template->SetCallAsFunctionHandler(call_as_function);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("obj"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -9994,7 +10105,7 @@ THREADED_TEST(CallAsFunction) {
USE(instance_template);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("obj2"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -10025,7 +10136,7 @@ THREADED_TEST(CallAsFunction) {
instance_template->SetCallAsFunctionHandler(ThrowValue);
Local<v8::Object> instance = t->GetFunction()->NewInstance();
context->Global()->Set(v8_str("obj3"), instance);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
Local<Value> value;
CHECK(!try_catch.HasCaught());
@@ -10123,7 +10234,7 @@ THREADED_TEST(CallableObject) {
Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
instance_template->SetCallAsFunctionHandler(call_as_function);
Local<Object> instance = instance_template->NewInstance();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10132,7 +10243,7 @@ THREADED_TEST(CallableObject) {
{
Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate);
Local<Object> instance = instance_template->NewInstance();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10143,7 +10254,7 @@ THREADED_TEST(CallableObject) {
FunctionTemplate::New(isolate, call_as_function);
Local<Function> function = function_template->GetFunction();
Local<Object> instance = function;
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10153,7 +10264,7 @@ THREADED_TEST(CallableObject) {
Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate);
Local<Function> function = function_template->GetFunction();
Local<Object> instance = function;
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(instance->IsCallable());
CHECK(!try_catch.HasCaught());
@@ -10544,7 +10655,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10587,7 +10698,7 @@ THREADED_PROFILED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10719,7 +10830,7 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_Miss2) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10758,7 +10869,7 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) {
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
context->Global()->Set(v8_str("o"), fun->NewInstance());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"o.foo = 17;"
"var receiver = {};"
@@ -10806,7 +10917,7 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
"o\n").As<Object>();
CHECK(!with_js_getter.IsEmpty());
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
Local<Value> result = instance->GetRealNamedProperty(v8_str("f"));
CHECK(try_catch.HasCaught());
@@ -10859,7 +10970,7 @@ THREADED_TEST(VariousGetPropertiesAndThrowingCallbacks) {
static void ThrowingCallbackWithTryCatch(
const v8::FunctionCallbackInfo<v8::Value>& args) {
- TryCatch try_catch;
+ TryCatch try_catch(args.GetIsolate());
// Verboseness is important: it triggers message delivery which can call into
// external code.
try_catch.SetVerbose(true);
@@ -10874,7 +10985,7 @@ static int call_depth;
static void WithTryCatch(Handle<Message> message, Handle<Value> data) {
- TryCatch try_catch;
+ TryCatch try_catch(CcTest::isolate());
}
@@ -11163,7 +11274,7 @@ TEST(ObjectProtoToStringES6) {
Local<Value> obj = v8::Object::New(isolate);
obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter);
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -11174,7 +11285,7 @@ TEST(ObjectProtoToStringES6) {
obj.As<v8::Object>()->SetAccessor(
toStringTag, SymbolAccessorGetterReturnsDefault, 0, v8_str("Test"));
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
CHECK(!try_catch.HasCaught());
@@ -11183,7 +11294,7 @@ TEST(ObjectProtoToStringES6) {
// JS @@toStringTag value
obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj");
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
CHECK(!try_catch.HasCaught());
@@ -11195,7 +11306,7 @@ TEST(ObjectProtoToStringES6) {
" get: function() { throw 'Test'; }"
"}); obj");
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -11207,7 +11318,7 @@ TEST(ObjectProtoToStringES6) {
" get: function() { return 'Test'; }"
"}); obj");
{
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
value = obj.As<v8::Object>()->ObjectProtoToString();
CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
CHECK(!try_catch.HasCaught());
@@ -11421,7 +11532,8 @@ static void ThrowInJS(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Locker nested_locker(isolate);
v8::HandleScope scope(isolate);
v8::Handle<Value> exception;
- { v8::TryCatch try_catch;
+ {
+ v8::TryCatch try_catch(isolate);
v8::Handle<Value> value = CompileRun(code);
CHECK(value.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -12447,7 +12559,7 @@ THREADED_TEST(Regress54) {
TEST(CatchStackOverflow) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
v8::Handle<v8::Value> result = CompileRun(
"function f() {"
" return f();"
@@ -12462,7 +12574,7 @@ static void CheckTryCatchSourceInfo(v8::Handle<v8::Script> script,
const char* resource_name,
int line_offset) {
v8::HandleScope scope(CcTest::isolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
v8::Handle<v8::Value> result = script->Run();
CHECK(result.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -12522,7 +12634,7 @@ THREADED_TEST(TryCatchSourceInfo) {
THREADED_TEST(TryCatchSourceInfoForEOSError) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
v8::Script::Compile(v8_str("!\n"));
CHECK(try_catch.HasCaught());
v8::Handle<v8::Message> message = try_catch.Message();
@@ -12714,71 +12826,6 @@ THREADED_TEST(AccessChecksReenabledCorrectly) {
}
-THREADED_TEST(TurnOnAccessCheck) {
- v8::Isolate* isolate = CcTest::isolate();
- v8::HandleScope handle_scope(isolate);
-
- // Create an environment with access check to the global object disabled by
- // default.
- v8::Handle<v8::ObjectTemplate> global_template =
- v8::ObjectTemplate::New(isolate);
- global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL,
- v8::Handle<v8::Value>(), false);
- v8::Local<Context> context = Context::New(isolate, NULL, global_template);
- Context::Scope context_scope(context);
-
- // Set up a property and a number of functions.
- context->Global()->Set(v8_str("a"), v8_num(1));
- CompileRun("function f1() {return a;}"
- "function f2() {return a;}"
- "function g1() {return h();}"
- "function g2() {return h();}"
- "function h() {return 1;}");
- Local<Function> f1 =
- Local<Function>::Cast(context->Global()->Get(v8_str("f1")));
- Local<Function> f2 =
- Local<Function>::Cast(context->Global()->Get(v8_str("f2")));
- Local<Function> g1 =
- Local<Function>::Cast(context->Global()->Get(v8_str("g1")));
- Local<Function> g2 =
- Local<Function>::Cast(context->Global()->Get(v8_str("g2")));
- Local<Function> h =
- Local<Function>::Cast(context->Global()->Get(v8_str("h")));
-
- // Get the global object.
- v8::Handle<v8::Object> global = context->Global();
-
- // Call f1 one time and f2 a number of times. This will ensure that f1 still
- // uses the runtime system to retreive property a whereas f2 uses global load
- // inline cache.
- CHECK(f1->Call(global, 0, NULL)->Equals(v8_num(1)));
- for (int i = 0; i < 4; i++) {
- CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1)));
- }
-
- // Same for g1 and g2.
- CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1)));
- for (int i = 0; i < 4; i++) {
- CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1)));
- }
-
- // Detach the global and turn on access check.
- Local<Object> hidden_global = Local<Object>::Cast(
- context->Global()->GetPrototype());
- context->DetachGlobal();
- hidden_global->TurnOnAccessCheck();
-
- // Failing access check results in exception.
- CHECK(f1->Call(global, 0, NULL).IsEmpty());
- CHECK(f2->Call(global, 0, NULL).IsEmpty());
- CHECK(g1->Call(global, 0, NULL).IsEmpty());
- CHECK(g2->Call(global, 0, NULL).IsEmpty());
-
- // No failing access check when just returning a constant.
- CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1)));
-}
-
-
// Tests that ScriptData can be serialized and deserialized.
TEST(PreCompileSerialization) {
v8::V8::Initialize();
@@ -13106,7 +13153,7 @@ TEST(RegExpInterruption) {
regexp_interruption_data.string_resource = new UC16VectorResource(
i::Vector<const i::uc16>(uc16_content, i::StrLength(one_byte_content)));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
timeout_thread.Start();
CompileRun("/((a*)*)*b/.exec(a)");
@@ -13216,8 +13263,9 @@ TEST(ForceSet) {
CHECK_EQ(3, global->Get(access_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
CHECK_EQ(2, force_set_get_count);
- // Forcing the property to be set should override the accessor without
- // calling it
+ // ForceSet doesn't call the accessors for now.
+ // TODO(verwaest): Update once blink doesn't rely on ForceSet to delete api
+ // accessors.
global->ForceSet(access_property, v8::Int32::New(isolate, 8));
CHECK_EQ(8, global->Get(access_property)->Int32Value());
CHECK_EQ(1, force_set_set_count);
@@ -13226,18 +13274,19 @@ TEST(ForceSet) {
TEST(ForceSetWithInterceptor) {
- force_set_get_count = 0;
- force_set_set_count = 0;
- pass_on_get = false;
-
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
ForceSetInterceptGetter, ForceSetInterceptSetter));
+ pass_on_get = true;
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
+ force_set_get_count = 0;
+ force_set_set_count = 0;
+ pass_on_get = false;
+
v8::Handle<v8::String> some_property =
v8::String::NewFromUtf8(isolate, "a");
CHECK_EQ(0, force_set_set_count);
@@ -13276,6 +13325,228 @@ TEST(ForceSetWithInterceptor) {
}
+TEST(CreateDataProperty) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ CompileRun(
+ "var a = {};"
+ "var b = [];"
+ "Object.defineProperty(a, 'foo', {value: 23});"
+ "Object.defineProperty(a, 'bar', {value: 23, configurable: true});");
+
+ v8::Local<v8::Object> obj =
+ v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
+ v8::Local<v8::Array> arr =
+ v8::Local<v8::Array>::Cast(env->Global()->Get(v8_str("b")));
+ {
+ // Can't change a non-configurable properties.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->CreateDataProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK(obj->CreateDataProperty(env.local(), v8_str("bar"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("bar")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set a regular property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->CreateDataProperty(env.local(), v8_str("blub"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("blub")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set an indexed property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->CreateDataProperty(env.local(), v8_str("1"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Special cases for arrays.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!arr->CreateDataProperty(env.local(), v8_str("length"),
+ v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+ {
+ // Special cases for arrays: index exceeds the array's length
+ v8::TryCatch try_catch(isolate);
+ CHECK(arr->CreateDataProperty(env.local(), 1, v8::Integer::New(isolate, 23))
+ .FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(2U, arr->Length());
+ v8::Local<v8::Value> val = arr->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(23.0, val->NumberValue(env.local()).FromJust());
+
+ // Set an existing entry.
+ CHECK(arr->CreateDataProperty(env.local(), 0, v8::Integer::New(isolate, 42))
+ .FromJust());
+ CHECK(!try_catch.HasCaught());
+ val = arr->Get(env.local(), 0).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ CompileRun("Object.freeze(a);");
+ {
+ // Can't change non-extensible objects.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->CreateDataProperty(env.local(), v8_str("baz"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL);
+ v8::Local<v8::Object> access_checked =
+ templ->NewInstance(env.local()).ToLocalChecked();
+ {
+ v8::TryCatch try_catch(isolate);
+ CHECK(access_checked->CreateDataProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42))
+ .IsNothing());
+ CHECK(try_catch.HasCaught());
+ }
+}
+
+
+TEST(DefineOwnProperty) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ CompileRun(
+ "var a = {};"
+ "var b = [];"
+ "Object.defineProperty(a, 'foo', {value: 23});"
+ "Object.defineProperty(a, 'bar', {value: 23, configurable: true});");
+
+ v8::Local<v8::Object> obj =
+ v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a")));
+ v8::Local<v8::Array> arr =
+ v8::Local<v8::Array>::Cast(env->Global()->Get(v8_str("b")));
+ {
+ // Can't change a non-configurable properties.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->DefineOwnProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("bar"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("bar")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set a regular property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("blub"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("blub")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set an indexed property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("1"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val = obj->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Special cases for arrays.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!arr->DefineOwnProperty(env.local(), v8_str("length"),
+ v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+ {
+ // Special cases for arrays: index exceeds the array's length
+ v8::TryCatch try_catch(isolate);
+ CHECK(arr->DefineOwnProperty(env.local(), v8_str("1"),
+ v8::Integer::New(isolate, 23)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(2U, arr->Length());
+ v8::Local<v8::Value> val = arr->Get(env.local(), 1).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(23.0, val->NumberValue(env.local()).FromJust());
+
+ // Set an existing entry.
+ CHECK(arr->DefineOwnProperty(env.local(), v8_str("0"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ val = arr->Get(env.local(), 0).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ }
+
+ {
+ // Set a non-writable property.
+ v8::TryCatch try_catch(isolate);
+ CHECK(obj->DefineOwnProperty(env.local(), v8_str("lala"),
+ v8::Integer::New(isolate, 42),
+ v8::ReadOnly).FromJust());
+ CHECK(!try_catch.HasCaught());
+ v8::Local<v8::Value> val =
+ obj->Get(env.local(), v8_str("lala")).ToLocalChecked();
+ CHECK(val->IsNumber());
+ CHECK_EQ(42.0, val->NumberValue(env.local()).FromJust());
+ CHECK_EQ(v8::ReadOnly, obj->GetPropertyAttributes(
+ env.local(), v8_str("lala")).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ CompileRun("Object.freeze(a);");
+ {
+ // Can't change non-extensible objects.
+ v8::TryCatch try_catch(isolate);
+ CHECK(!obj->DefineOwnProperty(env.local(), v8_str("baz"),
+ v8::Integer::New(isolate, 42)).FromJust());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
+ templ->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL);
+ v8::Local<v8::Object> access_checked =
+ templ->NewInstance(env.local()).ToLocalChecked();
+ {
+ v8::TryCatch try_catch(isolate);
+ CHECK(access_checked->DefineOwnProperty(env.local(), v8_str("foo"),
+ v8::Integer::New(isolate, 42))
+ .IsNothing());
+ CHECK(try_catch.HasCaught());
+ }
+}
+
+
static v8::Local<Context> calling_context0;
static v8::Local<Context> calling_context1;
static v8::Local<Context> calling_context2;
@@ -13789,7 +14060,8 @@ THREADED_TEST(FixedFloat64Array) {
}
-template <typename ElementType, typename TypedArray, class ExternalArrayClass>
+template <typename ElementType, typename TypedArray, class ExternalArrayClass,
+ class ArrayBufferType>
void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
int64_t high) {
const int kElementCount = 50;
@@ -13800,8 +14072,8 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
- Local<v8::ArrayBuffer> ab =
- v8::ArrayBuffer::New(isolate, backing_store.start(),
+ Local<ArrayBufferType> ab =
+ ArrayBufferType::New(isolate, backing_store.start(),
(kElementCount + 2) * sizeof(ElementType));
Local<TypedArray> ta =
TypedArray::New(ab, 2*sizeof(ElementType), kElementCount);
@@ -13822,56 +14094,58 @@ void TypedArrayTestHelper(i::ExternalArrayType array_type, int64_t low,
THREADED_TEST(Uint8Array) {
- TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array>(
- i::kExternalUint8Array, 0, 0xFF);
+ TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array,
+ v8::ArrayBuffer>(i::kExternalUint8Array, 0, 0xFF);
}
THREADED_TEST(Int8Array) {
- TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array>(
- i::kExternalInt8Array, -0x80, 0x7F);
+ TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array,
+ v8::ArrayBuffer>(i::kExternalInt8Array, -0x80, 0x7F);
}
THREADED_TEST(Uint16Array) {
- TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array>(
- i::kExternalUint16Array, 0, 0xFFFF);
+ TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array,
+ v8::ArrayBuffer>(i::kExternalUint16Array, 0, 0xFFFF);
}
THREADED_TEST(Int16Array) {
- TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array>(
- i::kExternalInt16Array, -0x8000, 0x7FFF);
+ TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array,
+ v8::ArrayBuffer>(i::kExternalInt16Array, -0x8000,
+ 0x7FFF);
}
THREADED_TEST(Uint32Array) {
- TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array>(
- i::kExternalUint32Array, 0, UINT_MAX);
+ TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array,
+ v8::ArrayBuffer>(i::kExternalUint32Array, 0, UINT_MAX);
}
THREADED_TEST(Int32Array) {
- TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array>(
- i::kExternalInt32Array, INT_MIN, INT_MAX);
+ TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array,
+ v8::ArrayBuffer>(i::kExternalInt32Array, INT_MIN,
+ INT_MAX);
}
THREADED_TEST(Float32Array) {
- TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array>(
- i::kExternalFloat32Array, -500, 500);
+ TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array,
+ v8::ArrayBuffer>(i::kExternalFloat32Array, -500, 500);
}
THREADED_TEST(Float64Array) {
- TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array>(
- i::kExternalFloat64Array, -500, 500);
+ TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array,
+ v8::ArrayBuffer>(i::kExternalFloat64Array, -500, 500);
}
THREADED_TEST(Uint8ClampedArray) {
TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray,
- i::ExternalUint8ClampedArray>(
+ i::ExternalUint8ClampedArray, v8::ArrayBuffer>(
i::kExternalUint8ClampedArray, 0, 0xFF);
}
@@ -13887,6 +14161,97 @@ THREADED_TEST(DataView) {
Local<v8::ArrayBuffer> ab =
v8::ArrayBuffer::New(isolate, backing_store.start(), 2 + kSize);
+ Local<v8::DataView> dv = v8::DataView::New(ab, 2, kSize);
+ CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv);
+ CHECK_EQ(2u, dv->ByteOffset());
+ CHECK_EQ(kSize, static_cast<int>(dv->ByteLength()));
+ CHECK(ab->Equals(dv->Buffer()));
+}
+
+
+THREADED_TEST(SharedUint8Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::ExternalUint8Array,
+ v8::SharedArrayBuffer>(i::kExternalUint8Array, 0, 0xFF);
+}
+
+
+THREADED_TEST(SharedInt8Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<int8_t, v8::Int8Array, i::ExternalInt8Array,
+ v8::SharedArrayBuffer>(i::kExternalInt8Array, -0x80,
+ 0x7F);
+}
+
+
+THREADED_TEST(SharedUint16Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint16_t, v8::Uint16Array, i::ExternalUint16Array,
+ v8::SharedArrayBuffer>(i::kExternalUint16Array, 0,
+ 0xFFFF);
+}
+
+
+THREADED_TEST(SharedInt16Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<int16_t, v8::Int16Array, i::ExternalInt16Array,
+ v8::SharedArrayBuffer>(i::kExternalInt16Array, -0x8000,
+ 0x7FFF);
+}
+
+
+THREADED_TEST(SharedUint32Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint32_t, v8::Uint32Array, i::ExternalUint32Array,
+ v8::SharedArrayBuffer>(i::kExternalUint32Array, 0,
+ UINT_MAX);
+}
+
+
+THREADED_TEST(SharedInt32Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<int32_t, v8::Int32Array, i::ExternalInt32Array,
+ v8::SharedArrayBuffer>(i::kExternalInt32Array, INT_MIN,
+ INT_MAX);
+}
+
+
+THREADED_TEST(SharedFloat32Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<float, v8::Float32Array, i::ExternalFloat32Array,
+ v8::SharedArrayBuffer>(i::kExternalFloat32Array, -500,
+ 500);
+}
+
+
+THREADED_TEST(SharedFloat64Array) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<double, v8::Float64Array, i::ExternalFloat64Array,
+ v8::SharedArrayBuffer>(i::kExternalFloat64Array, -500,
+ 500);
+}
+
+
+THREADED_TEST(SharedUint8ClampedArray) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ TypedArrayTestHelper<uint8_t, v8::Uint8ClampedArray,
+ i::ExternalUint8ClampedArray, v8::SharedArrayBuffer>(
+ i::kExternalUint8ClampedArray, 0, 0xFF);
+}
+
+
+THREADED_TEST(SharedDataView) {
+ i::FLAG_harmony_sharedarraybuffer = true;
+ const int kSize = 50;
+
+ i::ScopedVector<uint8_t> backing_store(kSize + 2);
+
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ Local<v8::SharedArrayBuffer> ab =
+ v8::SharedArrayBuffer::New(isolate, backing_store.start(), 2 + kSize);
Local<v8::DataView> dv =
v8::DataView::New(ab, 2, kSize);
CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv);
@@ -13949,7 +14314,7 @@ THREADED_TEST(ScriptContextDependence) {
THREADED_TEST(StackTrace) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
const char *source = "function foo() { FAIL.FAIL; }; foo();";
v8::Handle<v8::String> src =
v8::String::NewFromUtf8(context->GetIsolate(), source);
@@ -14928,7 +15293,7 @@ TEST(DynamicWithSourceURLInStackTraceString) {
i::ScopedVector<char> code(1024);
i::SNPrintF(code, source, "//# sourceURL=source_url");
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRunWithOrigin(code.start(), "", 0, 0);
CHECK(try_catch.HasCaught());
v8::String::Utf8Value stack(try_catch.StackTrace());
@@ -14949,7 +15314,7 @@ TEST(EvalWithSourceURLInMessageScriptResourceNameOrSourceURL) {
"outer();\n"
"//# sourceURL=outer_url";
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRun(source);
CHECK(try_catch.HasCaught());
@@ -14973,7 +15338,7 @@ TEST(RecursionWithSourceURLInMessageScriptResourceNameOrSourceURL) {
"outer();\n"
"//# sourceURL=outer_url";
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
CompileRun(source);
CHECK(try_catch.HasCaught());
@@ -14996,6 +15361,7 @@ static void CreateGarbageInOldSpace() {
// Test that idle notification can be handled and eventually collects garbage.
TEST(TestIdleNotification) {
+ if (!i::FLAG_incremental_marking) return;
const intptr_t MB = 1024 * 1024;
const double IdlePauseInSeconds = 1.0;
LocalContext env;
@@ -15006,6 +15372,9 @@ TEST(TestIdleNotification) {
CHECK_GT(size_with_garbage, initial_size + MB);
bool finished = false;
for (int i = 0; i < 200 && !finished; i++) {
+ if (i < 10 && CcTest::heap()->incremental_marking()->IsStopped()) {
+ CcTest::heap()->StartIdleIncrementalMarking();
+ }
finished = env->GetIsolate()->IdleNotificationDeadline(
(v8::base::TimeTicks::HighResolutionNow().ToInternalValue() /
static_cast<double>(v8::base::Time::kMicrosecondsPerSecond)) +
@@ -15284,9 +15653,6 @@ TEST(ExternalInternalizedStringCollectedAtTearDown) {
TEST(ExternalInternalizedStringCollectedAtGC) {
- // TODO(mvstanton): vector ics need weak support.
- if (i::FLAG_vector_ics) return;
-
int destroyed = 0;
{ LocalContext env;
v8::HandleScope handle_scope(env->GetIsolate());
@@ -15345,7 +15711,7 @@ THREADED_TEST(QuietSignalingNaNs) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
// Special double values.
double snan = DoubleFromBits(0x7ff00000, 0x00000001);
@@ -15432,7 +15798,7 @@ THREADED_TEST(QuietSignalingNaNs) {
static void SpaghettiIncident(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
- v8::TryCatch tc;
+ v8::TryCatch tc(args.GetIsolate());
v8::Handle<v8::String> str(args[0]->ToString(args.GetIsolate()));
USE(str);
if (tc.HasCaught())
@@ -15449,7 +15815,7 @@ THREADED_TEST(SpaghettiStackReThrow) {
context->Global()->Set(
v8::String::NewFromUtf8(isolate, "s"),
v8::FunctionTemplate::New(isolate, SpaghettiIncident)->GetFunction());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"var i = 0;"
"var o = {"
@@ -15535,7 +15901,7 @@ TEST(Regress528) {
v8::Local<Context> context = Context::New(isolate);
context->Enter();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(source_exception);
CHECK(try_catch.HasCaught());
v8::Handle<v8::Message> message = try_catch.Message();
@@ -15566,7 +15932,8 @@ THREADED_TEST(ScriptOrigin) {
v8::Integer::New(env->GetIsolate(), 1),
v8::Integer::New(env->GetIsolate(), 1), v8::True(env->GetIsolate()),
v8::Handle<v8::Integer>(), v8::True(env->GetIsolate()),
- v8::String::NewFromUtf8(env->GetIsolate(), "http://sourceMapUrl"));
+ v8::String::NewFromUtf8(env->GetIsolate(), "http://sourceMapUrl"),
+ v8::True(env->GetIsolate()));
v8::Handle<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(), "function f() {}\n\nfunction g() {}");
v8::Script::Compile(script, &origin)->Run();
@@ -15579,8 +15946,9 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(0, strcmp("test",
*v8::String::Utf8Value(script_origin_f.ResourceName())));
CHECK_EQ(1, script_origin_f.ResourceLineOffset()->Int32Value());
- CHECK(script_origin_f.ResourceIsSharedCrossOrigin()->Value());
- CHECK(script_origin_f.ResourceIsEmbedderDebugScript()->Value());
+ CHECK(script_origin_f.Options().IsSharedCrossOrigin());
+ CHECK(script_origin_f.Options().IsEmbedderDebugScript());
+ CHECK(script_origin_f.Options().IsOpaque());
printf("is name = %d\n", script_origin_f.SourceMapUrl()->IsUndefined());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
@@ -15590,8 +15958,9 @@ THREADED_TEST(ScriptOrigin) {
CHECK_EQ(0, strcmp("test",
*v8::String::Utf8Value(script_origin_g.ResourceName())));
CHECK_EQ(1, script_origin_g.ResourceLineOffset()->Int32Value());
- CHECK(script_origin_g.ResourceIsSharedCrossOrigin()->Value());
- CHECK(script_origin_g.ResourceIsEmbedderDebugScript()->Value());
+ CHECK(script_origin_g.Options().IsSharedCrossOrigin());
+ CHECK(script_origin_g.Options().IsEmbedderDebugScript());
+ CHECK(script_origin_g.Options().IsOpaque());
CHECK_EQ(0, strcmp("http://sourceMapUrl",
*v8::String::Utf8Value(script_origin_g.SourceMapUrl())));
}
@@ -16419,6 +16788,8 @@ void FailedAccessCheckCallbackGC(Local<v8::Object> target,
v8::AccessType type,
Local<v8::Value> data) {
CcTest::heap()->CollectAllGarbage();
+ CcTest::isolate()->ThrowException(
+ v8::Exception::Error(v8_str("cross context")));
}
@@ -16437,7 +16808,7 @@ TEST(GCInFailedAccessCheckCallback) {
v8::Handle<v8::ObjectTemplate> global_template =
v8::ObjectTemplate::New(isolate);
global_template->SetAccessCheckCallbacks(AccessAlwaysBlocked, NULL,
- v8::Handle<v8::Value>(), false);
+ v8::Handle<v8::Value>());
// Create a context and set an x property on it's global object.
LocalContext context0(NULL, global_template);
@@ -16449,28 +16820,42 @@ TEST(GCInFailedAccessCheckCallback) {
LocalContext context1(NULL, global_template);
context1->Global()->Set(v8_str("other"), global0);
+ v8::TryCatch try_catch(isolate);
+
// Get property with failed access check.
- ExpectUndefined("other.x");
+ CHECK(CompileRun("other.x").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Get element with failed access check.
- ExpectUndefined("other[0]");
+ CHECK(CompileRun("other[0]").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Set property with failed access check.
- v8::Handle<v8::Value> result = CompileRun("other.x = new Object()");
- CHECK(result->IsObject());
+ CHECK(CompileRun("other.x = new Object()").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Set element with failed access check.
- result = CompileRun("other[0] = new Object()");
- CHECK(result->IsObject());
+ CHECK(CompileRun("other[0] = new Object()").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Get property attribute with failed access check.
- ExpectFalse("\'x\' in other");
+ CHECK(CompileRun("\'x\' in other").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Get property attribute for element with failed access check.
- ExpectFalse("0 in other");
+ CHECK(CompileRun("0 in other").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Delete property.
- ExpectFalse("delete other.x");
+ CHECK(CompileRun("delete other.x").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// Delete element.
CHECK_EQ(false, global0->Delete(0));
@@ -16480,15 +16865,25 @@ TEST(GCInFailedAccessCheckCallback) {
global0->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("x")));
// Define JavaScript accessor.
- ExpectUndefined("Object.prototype.__defineGetter__.call("
- " other, \'x\', function() { return 42; })");
+ CHECK(CompileRun(
+ "Object.prototype.__defineGetter__.call("
+ " other, \'x\', function() { return 42; })").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// LookupAccessor.
- ExpectUndefined("Object.prototype.__lookupGetter__.call("
- " other, \'x\')");
+ CHECK(CompileRun(
+ "Object.prototype.__lookupGetter__.call("
+ " other, \'x\')").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
// HasOwnElement.
- ExpectFalse("Object.prototype.hasOwnProperty.call(other, \'0\')");
+ CHECK(CompileRun(
+ "Object.prototype.hasOwnProperty.call("
+ "other, \'0\')").IsEmpty());
+ CHECK(try_catch.HasCaught());
+ try_catch.Reset();
CHECK_EQ(false, global0->HasRealIndexedProperty(0));
CHECK_EQ(false, global0->HasRealNamedProperty(v8_str("x")));
@@ -17145,7 +17540,7 @@ TEST(RegExp) {
v8::Handle<v8::Value> value(CompileRun("re.property"));
CHECK_EQ(32, value->Int32Value());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(context->GetIsolate());
re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone);
CHECK(re.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -17485,7 +17880,7 @@ void CheckCodeGenerationAllowed() {
void CheckCodeGenerationDisallowed() {
- TryCatch try_catch;
+ TryCatch try_catch(CcTest::isolate());
Handle<Value> result = CompileRun("eval('42')");
CHECK(result.IsEmpty());
@@ -17548,7 +17943,7 @@ THREADED_TEST(AllowCodeGenFromStrings) {
TEST(SetErrorMessageForCodeGenFromStrings) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
Handle<String> message = v8_str("Message") ;
Handle<String> expected_message = v8_str("Uncaught EvalError: Message");
@@ -17575,7 +17970,7 @@ THREADED_TEST(CallAPIFunctionOnNonObject) {
v8::FunctionTemplate::New(isolate, NonObjectThis);
Handle<Function> function = templ->GetFunction();
context->Global()->Set(v8_str("f"), function);
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
CompileRun("f.call(2)");
}
@@ -18024,7 +18419,7 @@ TEST(RunMicrotasksIgnoresThrownExceptions) {
Function::New(isolate, MicrotaskExceptionOne));
isolate->EnqueueMicrotask(
Function::New(isolate, MicrotaskExceptionTwo));
- TryCatch try_catch;
+ TryCatch try_catch(isolate);
CompileRun("1+1;");
CHECK(!try_catch.HasCaught());
CHECK_EQ(1, CompileRun("exception1Calls")->Int32Value());
@@ -18345,7 +18740,7 @@ static void CheckInstanceCheckedResult(int getters, int setters,
static void CheckInstanceCheckedAccessors(bool expects_callbacks) {
instance_checked_getter_count = 0;
instance_checked_setter_count = 0;
- TryCatch try_catch;
+ TryCatch try_catch(CcTest::isolate());
// Test path through generic runtime code.
CompileRun("obj.foo");
@@ -18493,7 +18888,7 @@ TEST(TryFinallyMessage) {
// Test that the original error message is not lost if there is a
// recursive call into Javascript is done in the finally block, e.g. to
// initialize an IC. (crbug.com/129171)
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
const char* trigger_ic =
"try { \n"
" throw new Error('test'); \n"
@@ -18511,7 +18906,7 @@ TEST(TryFinallyMessage) {
{
// Test that the original exception message is indeed overwritten if
// a new error is thrown in the finally block.
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
const char* throw_again =
"try { \n"
" throw new Error('test'); \n"
@@ -18681,7 +19076,7 @@ THREADED_TEST(Regress137496) {
// Compile a try-finally clause where the finally block causes a GC
// while there still is a message pending for external reporting.
- TryCatch try_catch;
+ TryCatch try_catch(context->GetIsolate());
try_catch.SetVerbose(true);
CompileRun("try { throw new Error(); } finally { gc(); }");
CHECK(try_catch.HasCaught());
@@ -18859,16 +19254,6 @@ TEST(JSONStringifyAccessCheck) {
CHECK(CompileRun("JSON.stringify(other)").IsEmpty());
CHECK(CompileRun("JSON.stringify({ 'a' : other, 'b' : ['c'] })").IsEmpty());
CHECK(CompileRun("JSON.stringify([other, 'b', 'c'])").IsEmpty());
-
- v8::Handle<v8::Array> array = v8::Array::New(isolate, 2);
- array->Set(0, v8_str("a"));
- array->Set(1, v8_str("b"));
- context1->Global()->Set(v8_str("array"), array);
- ExpectString("JSON.stringify(array)", "[\"a\",\"b\"]");
- array->TurnOnAccessCheck();
- CHECK(CompileRun("JSON.stringify(array)").IsEmpty());
- CHECK(CompileRun("JSON.stringify([array])").IsEmpty());
- CHECK(CompileRun("JSON.stringify({'a' : array})").IsEmpty());
}
}
@@ -18924,6 +19309,7 @@ void CheckCorrectThrow(const char* script) {
TEST(AccessCheckThrows) {
i::FLAG_allow_natives_syntax = true;
+ i::FLAG_turbo_try_catch = true;
v8::V8::Initialize();
v8::V8::SetFailedAccessCheckCallbackFunction(&FailedAccessCheckThrows);
v8::Isolate* isolate = CcTest::isolate();
@@ -18953,7 +19339,8 @@ TEST(AccessCheckThrows) {
context1->Global()->Set(v8_str("has_own_property"),
has_own_property_fun->GetFunction());
- { v8::TryCatch try_catch;
+ {
+ v8::TryCatch try_catch(isolate);
access_check_fail_thrown = false;
CompileRun("other.x;");
CHECK(access_check_fail_thrown);
@@ -19570,7 +19957,7 @@ class ApiCallOptimizationChecker {
"%%OptimizeFunctionOnNextCall(wrap_set_%d);\n"
"check(wrap_set());\n",
wrap_function.start(), key, key, key, key, key, key);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(source.start());
DCHECK(!try_catch.HasCaught());
CHECK_EQ(9, count);
@@ -19994,7 +20381,7 @@ TEST(ThrowOnJavascriptExecution) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Isolate::DisallowJavascriptExecutionScope throw_js(
isolate, v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
CompileRun("1+1");
@@ -20054,7 +20441,7 @@ TEST(CaptureStackTraceForStackOverflow) {
v8::HandleScope scope(isolate);
V8::SetCaptureStackTraceForUncaughtExceptions(
true, 10, v8::StackTrace::kDetailed);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("(function f(x) { f(x+1); })(0)");
CHECK(try_catch.HasCaught());
}
@@ -20295,7 +20682,7 @@ void RunStreamingTest(const char** chunks,
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::ScriptCompiler::StreamedSource source(new TestSourceStream(chunks),
encoding);
@@ -20568,6 +20955,7 @@ TEST(StreamingWithDebuggingDoesNotProduceParserCache) {
CompileRun("function break_here() { }");
i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(
v8::Utils::OpenHandle(*env->Global()->Get(v8_str("break_here"))));
+ EnableDebugger();
v8::internal::Debug* debug = CcTest::i_isolate()->debug();
int position = 0;
debug->SetBreakPoint(func, i::Handle<i::Object>(v8::internal::Smi::FromInt(1),
@@ -20588,6 +20976,7 @@ TEST(StreamingWithDebuggingDoesNotProduceParserCache) {
// Check that we got no cached data.
CHECK(source.GetCachedData() == NULL);
+ DisableDebugger();
}
@@ -20667,7 +21056,7 @@ TEST(StreamingWithHarmonyScopes) {
// variable again.
const char* chunks[] = {"\"use strict\"; let x = 2;", NULL};
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::ScriptCompiler::StreamedSource source(
new TestSourceStream(chunks),
v8::ScriptCompiler::StreamedSource::ONE_BYTE);
@@ -20695,6 +21084,58 @@ TEST(StreamingWithHarmonyScopes) {
}
+TEST(CodeCache) {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+
+ const char* source = "Math.sqrt(4)";
+ const char* origin = "code cache test";
+ v8::ScriptCompiler::CachedData* cache;
+
+ v8::Isolate* isolate1 = v8::Isolate::New(create_params);
+ {
+ v8::Isolate::Scope iscope(isolate1);
+ v8::HandleScope scope(isolate1);
+ v8::Local<v8::Context> context = v8::Context::New(isolate1);
+ v8::Context::Scope cscope(context);
+ v8::Local<v8::String> source_string = v8_str(source);
+ v8::ScriptOrigin script_origin(v8_str(origin));
+ v8::ScriptCompiler::Source source(source_string, script_origin);
+ v8::ScriptCompiler::CompileOptions option =
+ v8::ScriptCompiler::kProduceCodeCache;
+ v8::ScriptCompiler::Compile(context, &source, option).ToLocalChecked();
+ int length = source.GetCachedData()->length;
+ uint8_t* cache_data = new uint8_t[length];
+ memcpy(cache_data, source.GetCachedData()->data, length);
+ cache = new v8::ScriptCompiler::CachedData(
+ cache_data, length, v8::ScriptCompiler::CachedData::BufferOwned);
+ }
+ isolate1->Dispose();
+
+ v8::Isolate* isolate2 = v8::Isolate::New(create_params);
+ {
+ v8::Isolate::Scope iscope(isolate2);
+ v8::HandleScope scope(isolate2);
+ v8::Local<v8::Context> context = v8::Context::New(isolate2);
+ v8::Context::Scope cscope(context);
+ v8::Local<v8::String> source_string = v8_str(source);
+ v8::ScriptOrigin script_origin(v8_str(origin));
+ v8::ScriptCompiler::Source source(source_string, script_origin, cache);
+ v8::ScriptCompiler::CompileOptions option =
+ v8::ScriptCompiler::kConsumeCodeCache;
+ v8::Local<v8::Script> script;
+ {
+ i::DisallowCompilation no_compile(
+ reinterpret_cast<i::Isolate*>(isolate2));
+ script = v8::ScriptCompiler::Compile(context, &source, option)
+ .ToLocalChecked();
+ }
+ CHECK_EQ(2, script->Run()->ToInt32(isolate2)->Int32Value());
+ }
+ isolate2->Dispose();
+}
+
+
void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) {
const char* garbage = "garbage garbage garbage garbage garbage garbage";
const uint8_t* data = reinterpret_cast<const uint8_t*>(garbage);
@@ -20782,7 +21223,7 @@ TEST(StringConcatOverflow) {
new RandomLengthOneByteResource(i::String::kMaxLength);
v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), r);
CHECK(!str.IsEmpty());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
v8::Local<v8::String> result = v8::String::Concat(str, str);
CHECK(result.IsEmpty());
CHECK(!try_catch.HasCaught());
@@ -20843,7 +21284,7 @@ TEST(GetPrototypeAccessControl) {
env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun(
"function f() { %_GetPrototype(prohibited); }"
"%OptimizeFunctionOnNextCall(f);"
@@ -20883,7 +21324,6 @@ TEST(GetPrototypeHidden) {
TEST(ClassPrototypeCreationContext) {
- i::FLAG_harmony_classes = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
LocalContext env;
@@ -20927,21 +21367,21 @@ TEST(NewStringRangeError) {
if (buffer == NULL) return;
memset(buffer, 'A', buffer_size);
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
char* data = reinterpret_cast<char*>(buffer);
CHECK(v8::String::NewFromUtf8(isolate, data, v8::String::kNormalString,
length).IsEmpty());
CHECK(!try_catch.HasCaught());
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
uint8_t* data = reinterpret_cast<uint8_t*>(buffer);
CHECK(v8::String::NewFromOneByte(isolate, data, v8::String::kNormalString,
length).IsEmpty());
CHECK(!try_catch.HasCaught());
}
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
uint16_t* data = reinterpret_cast<uint16_t*>(buffer);
CHECK(v8::String::NewFromTwoByte(isolate, data, v8::String::kNormalString,
length).IsEmpty());
@@ -20983,6 +21423,404 @@ TEST(SealHandleScopeNested) {
}
+static bool access_was_called = false;
+
+
+static bool AccessAlwaysAllowedWithFlag(Local<v8::Object> global,
+ Local<Value> name, v8::AccessType type,
+ Local<Value> data) {
+ access_was_called = true;
+ return true;
+}
+
+
+static bool AccessAlwaysBlockedWithFlag(Local<v8::Object> global,
+ Local<Value> name, v8::AccessType type,
+ Local<Value> data) {
+ access_was_called = true;
+ return false;
+}
+
+
+TEST(StrongModeAccessCheckAllowed) {
+ i::FLAG_strong_mode = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<Value> value;
+ access_was_called = false;
+
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
+
+ obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
+ obj_template->SetAccessCheckCallbacks(AccessAlwaysAllowedWithFlag, NULL);
+
+ // Create an environment
+ v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
+ context0->Enter();
+ v8::Handle<v8::Object> global0 = context0->Global();
+ global0->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(!try_catch.HasCaught());
+ CHECK(!access_was_called);
+ CHECK_EQ(42, value->Int32Value());
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+
+ // Create an environment
+ v8::Local<Context> context1 = Context::New(isolate);
+ context1->Enter();
+ v8::Handle<v8::Object> global1 = context1->Global();
+ global1->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(!try_catch.HasCaught());
+ CHECK(access_was_called);
+ CHECK_EQ(42, value->Int32Value());
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+
+ context1->Exit();
+ context0->Exit();
+}
+
+
+TEST(StrongModeAccessCheckBlocked) {
+ i::FLAG_strong_mode = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Handle<Value> value;
+ access_was_called = false;
+
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
+
+ obj_template->Set(v8_str("x"), v8::Integer::New(isolate, 42));
+ obj_template->SetAccessCheckCallbacks(AccessAlwaysBlockedWithFlag, NULL);
+
+ // Create an environment
+ v8::Local<Context> context0 = Context::New(isolate, NULL, obj_template);
+ context0->Enter();
+ v8::Handle<v8::Object> global0 = context0->Global();
+ global0->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(!try_catch.HasCaught());
+ CHECK(!access_was_called);
+ CHECK_EQ(42, value->Int32Value());
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(!access_was_called);
+ }
+
+ // Create an environment
+ v8::Local<Context> context1 = Context::New(isolate);
+ context1->Enter();
+ v8::Handle<v8::Object> global1 = context1->Global();
+ global1->Set(v8_str("object"), obj_template->NewInstance());
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.x");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object.foo");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+ access_was_called = false;
+ {
+ v8::TryCatch try_catch(isolate);
+ value = CompileRun("'use strong'; object[10]");
+ CHECK(try_catch.HasCaught());
+ CHECK(access_was_called);
+ }
+
+ context1->Exit();
+ context0->Exit();
+}
+
+
+TEST(StrongModeArityCallFromApi) {
+ i::FLAG_strong_mode = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Function> fun;
+ {
+ v8::TryCatch try_catch(isolate);
+ fun = Local<Function>::Cast(CompileRun(
+ "function f(x) { 'use strong'; }"
+ "f"));
+
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ fun->Call(v8::Undefined(isolate), 0, nullptr);
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42), v8_num(555)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+}
+
+
+TEST(StrongModeArityCallFromApi2) {
+ i::FLAG_strong_mode = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Function> fun;
+ {
+ v8::TryCatch try_catch(isolate);
+ fun = Local<Function>::Cast(CompileRun(
+ "'use strong';"
+ "function f(x) {}"
+ "f"));
+
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ fun->Call(v8::Undefined(isolate), 0, nullptr);
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch(isolate);
+ v8::Handle<Value> args[] = {v8_num(42), v8_num(555)};
+ fun->Call(v8::Undefined(isolate), arraysize(args), args);
+ CHECK(!try_catch.HasCaught());
+ }
+}
+
+
+TEST(StrongObjectDelete) {
+ i::FLAG_strong_mode = true;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<Object> obj;
+ {
+ v8::TryCatch try_catch;
+ obj = Local<Object>::Cast(CompileRun(
+ "'use strong';"
+ "({});"));
+ CHECK(!try_catch.HasCaught());
+ }
+ obj->ForceSet(v8_str("foo"), v8_num(1), v8::None);
+ obj->ForceSet(v8_str("2"), v8_num(1), v8::None);
+ CHECK(obj->HasOwnProperty(v8_str("foo")));
+ CHECK(obj->HasOwnProperty(v8_str("2")));
+ CHECK(!obj->Delete(v8_str("foo")));
+ CHECK(!obj->Delete(2));
+}
+
+
+static void ExtrasExportsTestRuntimeFunction(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ CHECK_EQ(3, args[0]->Int32Value());
+ args.GetReturnValue().Set(v8_num(7));
+}
+
+
+TEST(ExtrasExportsObject) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ // standalone.gypi ensures we include the test-extra.js file, which should
+ // export the tested functions.
+ v8::Local<v8::Object> exports = env->GetExtrasExportsObject();
+
+ auto func =
+ exports->Get(v8_str("testExtraShouldReturnFive")).As<v8::Function>();
+ auto undefined = v8::Undefined(isolate);
+ auto result = func->Call(undefined, 0, {}).As<v8::Number>();
+ CHECK_EQ(5, result->Int32Value());
+
+ v8::Handle<v8::FunctionTemplate> runtimeFunction =
+ v8::FunctionTemplate::New(isolate, ExtrasExportsTestRuntimeFunction);
+ exports->Set(v8_str("runtime"), runtimeFunction->GetFunction());
+ func =
+ exports->Get(v8_str("testExtraShouldCallToRuntime")).As<v8::Function>();
+ result = func->Call(undefined, 0, {}).As<v8::Number>();
+ CHECK_EQ(7, result->Int32Value());
+}
+
+
+TEST(Map) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ v8::Local<v8::Map> map = v8::Map::New(isolate);
+ CHECK(map->IsObject());
+ CHECK(map->IsMap());
+ CHECK(map->GetPrototype()->StrictEquals(CompileRun("Map.prototype")));
+ CHECK_EQ(0U, map->Size());
+
+ v8::Local<v8::Value> val = CompileRun("new Map([[1, 2], [3, 4]])");
+ CHECK(val->IsMap());
+ map = v8::Local<v8::Map>::Cast(val);
+ CHECK_EQ(2U, map->Size());
+
+ v8::Local<v8::Array> contents = map->AsArray();
+ CHECK_EQ(4U, contents->Length());
+ CHECK_EQ(1, contents->Get(0).As<v8::Int32>()->Value());
+ CHECK_EQ(2, contents->Get(1).As<v8::Int32>()->Value());
+ CHECK_EQ(3, contents->Get(2).As<v8::Int32>()->Value());
+ CHECK_EQ(4, contents->Get(3).As<v8::Int32>()->Value());
+
+ map = v8::Map::FromArray(env.local(), contents).ToLocalChecked();
+ CHECK_EQ(2U, map->Size());
+
+ CHECK(map->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(map->Has(env.local(), v8::Integer::New(isolate, 3)).FromJust());
+
+ CHECK(!map->Has(env.local(), v8::Integer::New(isolate, 2)).FromJust());
+ CHECK(!map->Has(env.local(), map).FromJust());
+
+ CHECK_EQ(2, map->Get(env.local(), v8::Integer::New(isolate, 1))
+ .ToLocalChecked()
+ ->Int32Value());
+ CHECK_EQ(4, map->Get(env.local(), v8::Integer::New(isolate, 3))
+ .ToLocalChecked()
+ ->Int32Value());
+
+ CHECK(map->Get(env.local(), v8::Integer::New(isolate, 42))
+ .ToLocalChecked()
+ ->IsUndefined());
+
+ CHECK(!map->Set(env.local(), map, map).IsEmpty());
+ CHECK_EQ(3U, map->Size());
+ CHECK(map->Has(env.local(), map).FromJust());
+
+ CHECK(map->Delete(env.local(), map).FromJust());
+ CHECK_EQ(2U, map->Size());
+ CHECK(!map->Has(env.local(), map).FromJust());
+ CHECK(!map->Delete(env.local(), map).FromJust());
+
+ map->Clear();
+ CHECK_EQ(0U, map->Size());
+}
+
+
+TEST(MapFromArrayOddLength) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+ // Odd lengths result in a null MaybeLocal.
+ Local<v8::Array> contents = v8::Array::New(isolate, 41);
+ CHECK(v8::Map::FromArray(env.local(), contents).IsEmpty());
+}
+
+
+TEST(Set) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ v8::Local<v8::Set> set = v8::Set::New(isolate);
+ CHECK(set->IsObject());
+ CHECK(set->IsSet());
+ CHECK(set->GetPrototype()->StrictEquals(CompileRun("Set.prototype")));
+ CHECK_EQ(0U, set->Size());
+
+ v8::Local<v8::Value> val = CompileRun("new Set([1, 2])");
+ CHECK(val->IsSet());
+ set = v8::Local<v8::Set>::Cast(val);
+ CHECK_EQ(2U, set->Size());
+
+ v8::Local<v8::Array> keys = set->AsArray();
+ CHECK_EQ(2U, keys->Length());
+ CHECK_EQ(1, keys->Get(0).As<v8::Int32>()->Value());
+ CHECK_EQ(2, keys->Get(1).As<v8::Int32>()->Value());
+
+ set = v8::Set::FromArray(env.local(), keys).ToLocalChecked();
+ CHECK_EQ(2U, set->Size());
+
+ CHECK(set->Has(env.local(), v8::Integer::New(isolate, 1)).FromJust());
+ CHECK(set->Has(env.local(), v8::Integer::New(isolate, 2)).FromJust());
+
+ CHECK(!set->Has(env.local(), v8::Integer::New(isolate, 3)).FromJust());
+ CHECK(!set->Has(env.local(), set).FromJust());
+
+ CHECK(!set->Add(env.local(), set).IsEmpty());
+ CHECK_EQ(3U, set->Size());
+ CHECK(set->Has(env.local(), set).FromJust());
+
+ CHECK(set->Delete(env.local(), set).FromJust());
+ CHECK_EQ(2U, set->Size());
+ CHECK(!set->Has(env.local(), set).FromJust());
+ CHECK(!set->Delete(env.local(), set).FromJust());
+
+ set->Clear();
+ CHECK_EQ(0U, set->Size());
+}
+
+
TEST(CompatibleReceiverCheckOnCachedICHandler) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc
index 059c04ad40..8f93150fad 100644
--- a/deps/v8/test/cctest/test-assembler-arm.cc
+++ b/deps/v8/test/cctest/test-assembler-arm.cc
@@ -175,17 +175,17 @@ TEST(3) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
__ mov(r4, Operand(r0));
- __ ldr(r0, MemOperand(r4, OFFSET_OF(T, i)));
+ __ ldr(r0, MemOperand(r4, offsetof(T, i)));
__ mov(r2, Operand(r0, ASR, 1));
- __ str(r2, MemOperand(r4, OFFSET_OF(T, i)));
- __ ldrsb(r2, MemOperand(r4, OFFSET_OF(T, c)));
+ __ str(r2, MemOperand(r4, offsetof(T, i)));
+ __ ldrsb(r2, MemOperand(r4, offsetof(T, c)));
__ add(r0, r2, Operand(r0));
__ mov(r2, Operand(r2, LSL, 2));
- __ strb(r2, MemOperand(r4, OFFSET_OF(T, c)));
- __ ldrsh(r2, MemOperand(r4, OFFSET_OF(T, s)));
+ __ strb(r2, MemOperand(r4, offsetof(T, c)));
+ __ ldrsh(r2, MemOperand(r4, offsetof(T, s)));
__ add(r0, r2, Operand(r0));
__ mov(r2, Operand(r2, ASR, 3));
- __ strh(r2, MemOperand(r4, OFFSET_OF(T, s)));
+ __ strh(r2, MemOperand(r4, offsetof(T, s)));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
CodeDesc desc;
@@ -247,68 +247,68 @@ TEST(4) {
__ sub(fp, ip, Operand(4));
__ mov(r4, Operand(r0));
- __ vldr(d6, r4, OFFSET_OF(T, a));
- __ vldr(d7, r4, OFFSET_OF(T, b));
+ __ vldr(d6, r4, offsetof(T, a));
+ __ vldr(d7, r4, offsetof(T, b));
__ vadd(d5, d6, d7);
- __ vstr(d5, r4, OFFSET_OF(T, c));
+ __ vstr(d5, r4, offsetof(T, c));
__ vmla(d5, d6, d7);
__ vmls(d5, d5, d6);
__ vmov(r2, r3, d5);
__ vmov(d4, r2, r3);
- __ vstr(d4, r4, OFFSET_OF(T, b));
+ __ vstr(d4, r4, offsetof(T, b));
// Load t.x and t.y, switch values, and store back to the struct.
- __ vldr(s0, r4, OFFSET_OF(T, x));
- __ vldr(s31, r4, OFFSET_OF(T, y));
+ __ vldr(s0, r4, offsetof(T, x));
+ __ vldr(s31, r4, offsetof(T, y));
__ vmov(s16, s0);
__ vmov(s0, s31);
__ vmov(s31, s16);
- __ vstr(s0, r4, OFFSET_OF(T, x));
- __ vstr(s31, r4, OFFSET_OF(T, y));
+ __ vstr(s0, r4, offsetof(T, x));
+ __ vstr(s31, r4, offsetof(T, y));
// Move a literal into a register that can be encoded in the instruction.
__ vmov(d4, 1.0);
- __ vstr(d4, r4, OFFSET_OF(T, e));
+ __ vstr(d4, r4, offsetof(T, e));
// Move a literal into a register that requires 64 bits to encode.
// 0x3ff0000010000000 = 1.000000059604644775390625
__ vmov(d4, 1.000000059604644775390625);
- __ vstr(d4, r4, OFFSET_OF(T, d));
+ __ vstr(d4, r4, offsetof(T, d));
// Convert from floating point to integer.
__ vmov(d4, 2.0);
__ vcvt_s32_f64(s31, d4);
- __ vstr(s31, r4, OFFSET_OF(T, i));
+ __ vstr(s31, r4, offsetof(T, i));
// Convert from integer to floating point.
__ mov(lr, Operand(42));
__ vmov(s31, lr);
__ vcvt_f64_s32(d4, s31);
- __ vstr(d4, r4, OFFSET_OF(T, f));
+ __ vstr(d4, r4, offsetof(T, f));
// Convert from fixed point to floating point.
__ mov(lr, Operand(2468));
__ vmov(s8, lr);
__ vcvt_f64_s32(d4, 2);
- __ vstr(d4, r4, OFFSET_OF(T, j));
+ __ vstr(d4, r4, offsetof(T, j));
// Test vabs.
- __ vldr(d1, r4, OFFSET_OF(T, g));
+ __ vldr(d1, r4, offsetof(T, g));
__ vabs(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, g));
- __ vldr(d2, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, g));
+ __ vldr(d2, r4, offsetof(T, h));
__ vabs(d0, d2);
- __ vstr(d0, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, h));
// Test vneg.
- __ vldr(d1, r4, OFFSET_OF(T, m));
+ __ vldr(d1, r4, offsetof(T, m));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, m));
- __ vldr(d1, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, m));
+ __ vldr(d1, r4, offsetof(T, n));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, n));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
@@ -647,19 +647,19 @@ TEST(8) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vldm(ia_w, r4, d0, d3);
__ vldm(ia_w, r4, d4, d7);
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vstm(ia_w, r4, d6, d7);
__ vstm(ia_w, r4, d0, d5);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vldm(ia_w, r4, s0, s3);
__ vldm(ia_w, r4, s4, s7);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vstm(ia_w, r4, s6, s7);
__ vstm(ia_w, r4, s0, s5);
@@ -753,22 +753,22 @@ TEST(9) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vldm(ia, r4, d0, d3);
__ add(r4, r4, Operand(4 * 8));
__ vldm(ia, r4, d4, d7);
- __ add(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, a))));
__ vstm(ia, r4, d6, d7);
__ add(r4, r4, Operand(2 * 8));
__ vstm(ia, r4, d0, d5);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vldm(ia, r4, s0, s3);
__ add(r4, r4, Operand(4 * 4));
__ vldm(ia, r4, s4, s7);
- __ add(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, a))));
__ vstm(ia, r4, s6, s7);
__ add(r4, r4, Operand(2 * 4));
__ vstm(ia, r4, s0, s5);
@@ -863,19 +863,19 @@ TEST(10) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, h)) + 8));
__ vldm(db_w, r4, d4, d7);
__ vldm(db_w, r4, d0, d3);
- __ add(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(D, h)) + 8));
__ vstm(db_w, r4, d0, d5);
__ vstm(db_w, r4, d6, d7);
- __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, h)) + 4));
__ vldm(db_w, r4, s4, s7);
__ vldm(db_w, r4, s0, s3);
- __ add(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ add(r4, r1, Operand(static_cast<int32_t>(offsetof(F, h)) + 4));
__ vstm(db_w, r4, s0, s5);
__ vstm(db_w, r4, s6, s7);
@@ -951,28 +951,28 @@ TEST(11) {
Assembler assm(isolate, NULL, 0);
// Test HeapObject untagging.
- __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ ldr(r1, MemOperand(r0, offsetof(I, a)));
__ mov(r1, Operand(r1, ASR, 1), SetCC);
__ adc(r1, r1, Operand(r1), LeaveCC, cs);
- __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ str(r1, MemOperand(r0, offsetof(I, a)));
- __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ ldr(r2, MemOperand(r0, offsetof(I, b)));
__ mov(r2, Operand(r2, ASR, 1), SetCC);
__ adc(r2, r2, Operand(r2), LeaveCC, cs);
- __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ str(r2, MemOperand(r0, offsetof(I, b)));
// Test corner cases.
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r1, ASR, 1), SetCC); // Set the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
+ __ str(r3, MemOperand(r0, offsetof(I, c)));
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r2, ASR, 1), SetCC); // Unset the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
+ __ str(r3, MemOperand(r0, offsetof(I, d)));
__ mov(pc, Operand(lr));
@@ -1048,9 +1048,9 @@ TEST(13) {
// Load a, b, c into d16, d17, d18.
__ mov(r4, Operand(r0));
- __ vldr(d16, r4, OFFSET_OF(T, a));
- __ vldr(d17, r4, OFFSET_OF(T, b));
- __ vldr(d18, r4, OFFSET_OF(T, c));
+ __ vldr(d16, r4, offsetof(T, a));
+ __ vldr(d17, r4, offsetof(T, b));
+ __ vldr(d18, r4, offsetof(T, c));
__ vneg(d25, d16);
__ vadd(d25, d25, d17);
@@ -1066,12 +1066,12 @@ TEST(13) {
// Store d16, d17, d18 into a, b, c.
__ mov(r4, Operand(r0));
- __ vstr(d16, r4, OFFSET_OF(T, a));
- __ vstr(d17, r4, OFFSET_OF(T, b));
- __ vstr(d18, r4, OFFSET_OF(T, c));
+ __ vstr(d16, r4, offsetof(T, a));
+ __ vstr(d17, r4, offsetof(T, b));
+ __ vstr(d18, r4, offsetof(T, c));
// Load x, y, z into d29-d31.
- __ add(r4, r0, Operand(OFFSET_OF(T, x)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, x))));
__ vldm(ia_w, r4, d29, d31);
// Swap d29 and d30 via r registers.
@@ -1084,7 +1084,7 @@ TEST(13) {
__ vcvt_f64_u32(d31, s1);
// Store d29-d31 into x, y, z.
- __ add(r4, r0, Operand(OFFSET_OF(T, x)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, x))));
__ vstm(ia_w, r4, d29, d31);
// Move constants into d20, d21, d22 and store into i, j, k.
@@ -1094,13 +1094,13 @@ TEST(13) {
__ mov(r2, Operand(1079146608));
__ vmov(d22, VmovIndexLo, r1);
__ vmov(d22, VmovIndexHi, r2);
- __ add(r4, r0, Operand(OFFSET_OF(T, i)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, i))));
__ vstm(ia_w, r4, d20, d22);
// Move d22 into low and high.
__ vmov(r4, VmovIndexLo, d22);
- __ str(r4, MemOperand(r0, OFFSET_OF(T, low)));
+ __ str(r4, MemOperand(r0, offsetof(T, low)));
__ vmov(r4, VmovIndexHi, d22);
- __ str(r4, MemOperand(r0, OFFSET_OF(T, high)));
+ __ str(r4, MemOperand(r0, offsetof(T, high)));
__ ldm(ia_w, sp, r4.bit() | pc.bit());
@@ -1164,16 +1164,16 @@ TEST(14) {
__ vmsr(r1);
__ bind(&fpscr_done);
- __ vldr(d0, r0, OFFSET_OF(T, left));
- __ vldr(d1, r0, OFFSET_OF(T, right));
+ __ vldr(d0, r0, offsetof(T, left));
+ __ vldr(d1, r0, offsetof(T, right));
__ vadd(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, add_result));
+ __ vstr(d2, r0, offsetof(T, add_result));
__ vsub(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, sub_result));
+ __ vstr(d2, r0, offsetof(T, sub_result));
__ vmul(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, mul_result));
+ __ vstr(d2, r0, offsetof(T, mul_result));
__ vdiv(d2, d0, d1);
- __ vstr(d2, r0, OFFSET_OF(T, div_result));
+ __ vstr(d2, r0, offsetof(T, div_result));
__ mov(pc, Operand(lr));
@@ -1264,23 +1264,23 @@ TEST(15) {
__ stm(db_w, sp, r4.bit() | lr.bit());
// Move 32 bytes with neon.
- __ add(r4, r0, Operand(OFFSET_OF(T, src0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, src0))));
__ vld1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
- __ add(r4, r0, Operand(OFFSET_OF(T, dst0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, dst0))));
__ vst1(Neon8, NeonListOperand(d0, 4), NeonMemOperand(r4));
// Expand 8 bytes into 8 words(16 bits).
- __ add(r4, r0, Operand(OFFSET_OF(T, srcA0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, srcA0))));
__ vld1(Neon8, NeonListOperand(d0), NeonMemOperand(r4));
__ vmovl(NeonU8, q0, d0);
- __ add(r4, r0, Operand(OFFSET_OF(T, dstA0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, dstA0))));
__ vst1(Neon8, NeonListOperand(d0, 2), NeonMemOperand(r4));
// The same expansion, but with different source and destination registers.
- __ add(r4, r0, Operand(OFFSET_OF(T, srcA0)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, srcA0))));
__ vld1(Neon8, NeonListOperand(d1), NeonMemOperand(r4));
__ vmovl(NeonU8, q1, d1);
- __ add(r4, r0, Operand(OFFSET_OF(T, dstA4)));
+ __ add(r4, r0, Operand(static_cast<int32_t>(offsetof(T, dstA4))));
__ vst1(Neon8, NeonListOperand(d2, 2), NeonMemOperand(r4));
__ ldm(ia_w, sp, r4.bit() | pc.bit());
@@ -1367,24 +1367,24 @@ TEST(16) {
__ stm(db_w, sp, r4.bit() | lr.bit());
__ mov(r4, Operand(r0));
- __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src0)));
- __ ldr(r1, MemOperand(r4, OFFSET_OF(T, src1)));
+ __ ldr(r0, MemOperand(r4, offsetof(T, src0)));
+ __ ldr(r1, MemOperand(r4, offsetof(T, src1)));
__ pkhbt(r2, r0, Operand(r1, LSL, 8));
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst0)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst0)));
__ pkhtb(r2, r0, Operand(r1, ASR, 8));
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst1)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst1)));
__ uxtb16(r2, r0, 8);
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst2)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst2)));
__ uxtb(r2, r0, 8);
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst3)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst3)));
- __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src2)));
+ __ ldr(r0, MemOperand(r4, offsetof(T, src2)));
__ uxtab(r2, r0, r1, 8);
- __ str(r2, MemOperand(r4, OFFSET_OF(T, dst4)));
+ __ str(r2, MemOperand(r4, offsetof(T, dst4)));
__ ldm(ia_w, sp, r4.bit() | pc.bit());
@@ -1461,11 +1461,11 @@ TEST(sdiv) {
__ mov(r3, Operand(r0));
- __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend)));
- __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor)));
+ __ ldr(r0, MemOperand(r3, offsetof(T, dividend)));
+ __ ldr(r1, MemOperand(r3, offsetof(T, divisor)));
__ sdiv(r2, r0, r1);
- __ str(r2, MemOperand(r3, OFFSET_OF(T, result)));
+ __ str(r2, MemOperand(r3, offsetof(T, result)));
__ bx(lr);
@@ -1525,11 +1525,11 @@ TEST(udiv) {
__ mov(r3, Operand(r0));
- __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend)));
- __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor)));
+ __ ldr(r0, MemOperand(r3, offsetof(T, dividend)));
+ __ ldr(r1, MemOperand(r3, offsetof(T, divisor)));
__ sdiv(r2, r0, r1);
- __ str(r2, MemOperand(r3, OFFSET_OF(T, result)));
+ __ str(r2, MemOperand(r3, offsetof(T, result)));
__ bx(lr);
@@ -1917,29 +1917,29 @@ TEST(ARMv8_vrintX) {
__ mov(r4, Operand(r0));
// Test vrinta
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrinta(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, ar));
+ __ vstr(d5, r4, offsetof(T, ar));
// Test vrintn
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintn(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, nr));
+ __ vstr(d5, r4, offsetof(T, nr));
// Test vrintp
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintp(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, pr));
+ __ vstr(d5, r4, offsetof(T, pr));
// Test vrintm
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintm(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, mr));
+ __ vstr(d5, r4, offsetof(T, mr));
// Test vrintz
- __ vldr(d6, r4, OFFSET_OF(T, input));
+ __ vldr(d6, r4, offsetof(T, input));
__ vrintz(d5, d6);
- __ vstr(d5, r4, OFFSET_OF(T, zr));
+ __ vstr(d5, r4, offsetof(T, zr));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
diff --git a/deps/v8/test/cctest/test-assembler-mips.cc b/deps/v8/test/cctest/test-assembler-mips.cc
index 7a8beaa578..13abbbb447 100644
--- a/deps/v8/test/cctest/test-assembler-mips.cc
+++ b/deps/v8/test/cctest/test-assembler-mips.cc
@@ -278,61 +278,61 @@ TEST(MIPS3) {
Label L, C;
// Double precision floating point instructions.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
__ add_d(f8, f4, f6);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
+ __ sdc1(f8, MemOperand(a0, offsetof(T, c)) ); // c = a + b.
__ mov_d(f10, f8); // c
__ neg_d(f12, f6); // -b
__ sub_d(f10, f10, f12);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b).
+ __ sdc1(f10, MemOperand(a0, offsetof(T, d)) ); // d = c - (-b).
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
+ __ sdc1(f4, MemOperand(a0, offsetof(T, b)) ); // b = a.
__ li(t0, 120);
__ mtc1(t0, f14);
__ cvt_d_w(f14, f14); // f14 = 120.0.
__ mul_d(f10, f10, f14);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16.
+ __ sdc1(f10, MemOperand(a0, offsetof(T, e)) ); // e = d * 120 = 1.8066e16.
__ div_d(f12, f10, f4);
- __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44.
+ __ sdc1(f12, MemOperand(a0, offsetof(T, f)) ); // f = e / a = 120.44.
__ sqrt_d(f14, f12);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(T, g)) );
// g = sqrt(f) = 10.97451593465515908537
if (IsMipsArchVariant(kMips32r2)) {
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, h)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, i)) );
__ madd_d(f14, f6, f4, f6);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(T, h)) );
}
// Single precision floating point instructions.
- __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fa)) );
- __ lwc1(f6, MemOperand(a0, OFFSET_OF(T, fb)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fa)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(T, fb)) );
__ add_s(f8, f4, f6);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, fc)) ); // fc = fa + fb.
+ __ swc1(f8, MemOperand(a0, offsetof(T, fc)) ); // fc = fa + fb.
__ neg_s(f10, f6); // -fb
__ sub_s(f10, f8, f10);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fd)) ); // fd = fc - (-fb).
+ __ swc1(f10, MemOperand(a0, offsetof(T, fd)) ); // fd = fc - (-fb).
- __ swc1(f4, MemOperand(a0, OFFSET_OF(T, fb)) ); // fb = fa.
+ __ swc1(f4, MemOperand(a0, offsetof(T, fb)) ); // fb = fa.
__ li(t0, 120);
__ mtc1(t0, f14);
__ cvt_s_w(f14, f14); // f14 = 120.0.
__ mul_s(f10, f10, f14);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fe)) ); // fe = fd * 120
+ __ swc1(f10, MemOperand(a0, offsetof(T, fe)) ); // fe = fd * 120
__ div_s(f12, f10, f4);
- __ swc1(f12, MemOperand(a0, OFFSET_OF(T, ff)) ); // ff = fe / fa
+ __ swc1(f12, MemOperand(a0, offsetof(T, ff)) ); // ff = fe / fa
__ sqrt_s(f14, f12);
- __ swc1(f14, MemOperand(a0, OFFSET_OF(T, fg)) );
+ __ swc1(f14, MemOperand(a0, offsetof(T, fg)) );
__ jr(ra);
__ nop();
@@ -398,8 +398,8 @@ TEST(MIPS4) {
Assembler assm(isolate, NULL, 0);
Label L, C;
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
// Swap f4 and f6, by using four integer registers, t0-t3.
if (!IsFp64Mode()) {
@@ -425,8 +425,8 @@ TEST(MIPS4) {
__ mthc1(t3, f4);
}
// Store the swapped f4 and f5 back to memory.
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ sdc1(f6, MemOperand(a0, OFFSET_OF(T, c)) );
+ __ sdc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ sdc1(f6, MemOperand(a0, offsetof(T, c)) );
__ jr(ra);
__ nop();
@@ -466,30 +466,30 @@ TEST(MIPS5) {
Label L, C;
// Load all structure elements to registers.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, i)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, j)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, i)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, j)) );
// Convert double in f4 to int in element i.
__ cvt_w_d(f8, f4);
__ mfc1(t2, f8);
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, i)) );
// Convert double in f6 to int in element j.
__ cvt_w_d(f10, f6);
__ mfc1(t3, f10);
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, j)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, j)) );
// Convert int in original i (t0) to double in a.
__ mtc1(t0, f12);
__ cvt_d_w(f0, f12);
- __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ sdc1(f0, MemOperand(a0, offsetof(T, a)) );
// Convert int in original j (t1) to double in b.
__ mtc1(t1, f14);
__ cvt_d_w(f2, f14);
- __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ sdc1(f2, MemOperand(a0, offsetof(T, b)) );
__ jr(ra);
__ nop();
@@ -535,31 +535,31 @@ TEST(MIPS6) {
Label L, C;
// Basic word load/store.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, r1)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, r1)) );
// lh with positive data.
- __ lh(t1, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, r2)) );
+ __ lh(t1, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, r2)) );
// lh with negative data.
- __ lh(t2, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, r3)) );
+ __ lh(t2, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, r3)) );
// lhu with negative data.
- __ lhu(t3, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, r4)) );
+ __ lhu(t3, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, r4)) );
// lb with negative data.
- __ lb(t4, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, r5)) );
+ __ lb(t4, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t4, MemOperand(a0, offsetof(T, r5)) );
// sh writes only 1/2 of word.
__ lui(t5, 0x3333);
__ ori(t5, t5, 0x3333);
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
- __ lhu(t5, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sh(t5, MemOperand(a0, OFFSET_OF(T, r6)) );
+ __ sw(t5, MemOperand(a0, offsetof(T, r6)) );
+ __ lhu(t5, MemOperand(a0, offsetof(T, si)) );
+ __ sh(t5, MemOperand(a0, offsetof(T, r6)) );
__ jr(ra);
__ nop();
@@ -615,8 +615,8 @@ TEST(MIPS7) {
MacroAssembler assm(isolate, NULL, 0);
Label neither_is_nan, less_than, outa_here;
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
if (!IsMipsArchVariant(kMips32r6)) {
__ c(UN, D, f4, f6);
__ bc1f(&neither_is_nan);
@@ -625,7 +625,7 @@ TEST(MIPS7) {
__ bc1eqz(&neither_is_nan, f2);
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&neither_is_nan);
@@ -642,12 +642,12 @@ TEST(MIPS7) {
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&less_than);
__ Addu(t0, zero_reg, Operand(1));
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
+ __ sw(t0, MemOperand(a0, offsetof(T, result)) ); // Set true.
// This test-case should have additional tests.
@@ -706,7 +706,7 @@ TEST(MIPS8) {
MacroAssembler assm(isolate, NULL, 0);
// Basic word load.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, input)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, input)) );
// ROTR instruction (called through the Ror macro).
__ Ror(t1, t0, 0x0004);
@@ -718,13 +718,13 @@ TEST(MIPS8) {
__ Ror(t7, t0, 0x001c);
// Basic word store.
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
- __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
- __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotr_4)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotr_8)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotr_12)) );
+ __ sw(t4, MemOperand(a0, offsetof(T, result_rotr_16)) );
+ __ sw(t5, MemOperand(a0, offsetof(T, result_rotr_20)) );
+ __ sw(t6, MemOperand(a0, offsetof(T, result_rotr_24)) );
+ __ sw(t7, MemOperand(a0, offsetof(T, result_rotr_28)) );
// ROTRV instruction (called through the Ror macro).
__ li(t7, 0x0004);
@@ -743,13 +743,13 @@ TEST(MIPS8) {
__ Ror(t7, t0, t7);
// Basic word store.
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
- __ sw(t4, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
- __ sw(t5, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
- __ sw(t6, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
- __ sw(t7, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotrv_4)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotrv_8)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotrv_12)) );
+ __ sw(t4, MemOperand(a0, offsetof(T, result_rotrv_16)) );
+ __ sw(t5, MemOperand(a0, offsetof(T, result_rotrv_20)) );
+ __ sw(t6, MemOperand(a0, offsetof(T, result_rotrv_24)) );
+ __ sw(t7, MemOperand(a0, offsetof(T, result_rotrv_28)) );
__ jr(ra);
__ nop();
@@ -808,8 +808,9 @@ TEST(MIPS9) {
TEST(MIPS10) {
- // Test conversions between doubles and long integers.
- // Test hos the long ints map to FP regs pairs.
+ // Test conversions between doubles and words.
+ // Test maps double to FP reg pairs in fp32 mode
+ // and into FP reg in fp64 mode.
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
@@ -830,24 +831,32 @@ TEST(MIPS10) {
if (!IsMipsArchVariant(kMips32r2)) return;
// Load all structure elements to registers.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
-
- // Save the raw bits of the double.
- __ mfc1(t0, f0);
- __ mfc1(t1, f1);
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
+ // (f0, f1) = a (fp32), f0 = a (fp64)
+ __ ldc1(f0, MemOperand(a0, offsetof(T, a)));
+
+ if (IsFp64Mode()) {
+ __ mfc1(t0, f0); // t0 = f0(31..0)
+ __ mfhc1(t1, f0); // t1 = sign_extend(f0(63..32))
+ __ sw(t0, MemOperand(a0, offsetof(T, dbl_mant))); // dbl_mant = t0
+ __ sw(t1, MemOperand(a0, offsetof(T, dbl_exp))); // dbl_exp = t1
+ } else {
+ // Save the raw bits of the double.
+ __ mfc1(t0, f0); // t0 = a1
+ __ mfc1(t1, f1); // t1 = a2
+ __ sw(t0, MemOperand(a0, offsetof(T, dbl_mant))); // dbl_mant = t0
+ __ sw(t1, MemOperand(a0, offsetof(T, dbl_exp))); // dbl_exp = t1
+ }
- // Convert double in f0 to long, save hi/lo parts.
- __ cvt_w_d(f0, f0);
- __ mfc1(t0, f0); // f0 has a 32-bits word.
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, word)));
+ // Convert double in f0 to word, save hi/lo parts.
+ __ cvt_w_d(f0, f0); // a_word = (word)a
+ __ mfc1(t0, f0); // f0 has a 32-bits word. t0 = a_word
+ __ sw(t0, MemOperand(a0, offsetof(T, word))); // word = a_word
- // Convert the b long integers to double b.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, b_word)));
+ // Convert the b word to double b.
+ __ lw(t0, MemOperand(a0, offsetof(T, b_word)));
__ mtc1(t0, f8); // f8 has a 32-bits word.
__ cvt_d_w(f10, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, b)));
__ jr(ra);
__ nop();
@@ -861,7 +870,6 @@ TEST(MIPS10) {
t.b_word = 0x0ff00ff0; // 0x0FF00FF0 -> 0x as double.
Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
USE(dummy);
-
CHECK_EQ(static_cast<int32_t>(0x41DFFFFF), t.dbl_exp);
CHECK_EQ(static_cast<int32_t>(0xFF800000), t.dbl_mant);
CHECK_EQ(static_cast<int32_t>(0x7FFFFFFE), t.word);
@@ -903,80 +911,80 @@ TEST(MIPS11) {
Assembler assm(isolate, NULL, 0);
// Test all combinations of LWL and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwl_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, lwl_0)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwl_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t1, MemOperand(a0, offsetof(T, mem_init) + 1) );
+ __ sw(t1, MemOperand(a0, offsetof(T, lwl_1)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwl_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t2, MemOperand(a0, offsetof(T, mem_init) + 2) );
+ __ sw(t2, MemOperand(a0, offsetof(T, lwl_2)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwl(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwl_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwl(t3, MemOperand(a0, offsetof(T, mem_init) + 3) );
+ __ sw(t3, MemOperand(a0, offsetof(T, lwl_3)) );
// Test all combinations of LWR and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, lwr_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, lwr_0)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t1, MemOperand(a0, OFFSET_OF(T, mem_init) + 1) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, lwr_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t1, MemOperand(a0, offsetof(T, mem_init) + 1) );
+ __ sw(t1, MemOperand(a0, offsetof(T, lwr_1)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t2, MemOperand(a0, OFFSET_OF(T, mem_init) + 2) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t2, MemOperand(a0, offsetof(T, mem_init) + 2) );
+ __ sw(t2, MemOperand(a0, offsetof(T, lwr_2)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ lwr(t3, MemOperand(a0, OFFSET_OF(T, mem_init) + 3) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ lwr(t3, MemOperand(a0, offsetof(T, mem_init) + 3) );
+ __ sw(t3, MemOperand(a0, offsetof(T, lwr_3)) );
// Test all combinations of SWL and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t0, MemOperand(a0, OFFSET_OF(T, swl_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, swl_1)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t1, MemOperand(a0, OFFSET_OF(T, swl_1) + 1) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, swl_2)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t2, MemOperand(a0, OFFSET_OF(T, swl_2) + 2) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, swl_3)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swl(t3, MemOperand(a0, OFFSET_OF(T, swl_3) + 3) );
+ __ lw(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, swl_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t0, MemOperand(a0, offsetof(T, swl_0)) );
+
+ __ lw(t1, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, swl_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t1, MemOperand(a0, offsetof(T, swl_1) + 1) );
+
+ __ lw(t2, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, swl_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t2, MemOperand(a0, offsetof(T, swl_2) + 2) );
+
+ __ lw(t3, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, swl_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swl(t3, MemOperand(a0, offsetof(T, swl_3) + 3) );
// Test all combinations of SWR and vAddr.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t0, MemOperand(a0, OFFSET_OF(T, swr_0)) );
-
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, swr_1)) );
- __ lw(t1, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t1, MemOperand(a0, OFFSET_OF(T, swr_1) + 1) );
-
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, swr_2)) );
- __ lw(t2, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t2, MemOperand(a0, OFFSET_OF(T, swr_2) + 2) );
-
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, mem_init)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, swr_3)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, reg_init)) );
- __ swr(t3, MemOperand(a0, OFFSET_OF(T, swr_3) + 3) );
+ __ lw(t0, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, swr_0)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t0, MemOperand(a0, offsetof(T, swr_0)) );
+
+ __ lw(t1, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, swr_1)) );
+ __ lw(t1, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t1, MemOperand(a0, offsetof(T, swr_1) + 1) );
+
+ __ lw(t2, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, swr_2)) );
+ __ lw(t2, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t2, MemOperand(a0, offsetof(T, swr_2) + 2) );
+
+ __ lw(t3, MemOperand(a0, offsetof(T, mem_init)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, swr_3)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, reg_init)) );
+ __ swr(t3, MemOperand(a0, offsetof(T, swr_3) + 3) );
__ jr(ra);
__ nop();
@@ -1013,7 +1021,7 @@ TEST(MIPS11) {
CHECK_EQ(static_cast<int32_t>(0xccdd3344), t.swr_2);
CHECK_EQ(static_cast<int32_t>(0xdd223344), t.swr_3);
#elif __BYTE_ORDER == __BIG_ENDIAN
- 11223344, t.lwl_0);
+ CHECK_EQ(static_cast<int32_t>(0x11223344), t.lwl_0);
CHECK_EQ(static_cast<int32_t>(0x223344dd), t.lwl_1);
CHECK_EQ(static_cast<int32_t>(0x3344ccdd), t.lwl_2);
CHECK_EQ(static_cast<int32_t>(0x44bbccdd), t.lwl_3);
@@ -1057,8 +1065,8 @@ TEST(MIPS12) {
__ mov(t6, fp); // Save frame pointer.
__ mov(fp, a0); // Access struct T by fp.
- __ lw(t0, MemOperand(a0, OFFSET_OF(T, y)) );
- __ lw(t3, MemOperand(a0, OFFSET_OF(T, y4)) );
+ __ lw(t0, MemOperand(a0, offsetof(T, y)) );
+ __ lw(t3, MemOperand(a0, offsetof(T, y4)) );
__ addu(t1, t0, t3);
__ subu(t4, t0, t3);
@@ -1076,30 +1084,30 @@ TEST(MIPS12) {
__ push(t3);
__ pop(t4);
__ nop();
- __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
- __ lw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ sw(t0, MemOperand(fp, offsetof(T, y)) );
+ __ lw(t0, MemOperand(fp, offsetof(T, y)) );
__ nop();
- __ sw(t0, MemOperand(fp, OFFSET_OF(T, y)) );
- __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ sw(t0, MemOperand(fp, offsetof(T, y)) );
+ __ lw(t1, MemOperand(fp, offsetof(T, y)) );
__ nop();
__ push(t1);
- __ lw(t1, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t1, MemOperand(fp, offsetof(T, y)) );
__ pop(t1);
__ nop();
__ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t1);
__ nop();
__ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t2);
__ nop();
__ push(t2);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t1);
__ nop();
__ push(t1);
- __ lw(t2, MemOperand(fp, OFFSET_OF(T, y)) );
+ __ lw(t2, MemOperand(fp, offsetof(T, y)) );
__ pop(t3);
__ nop();
@@ -1144,19 +1152,19 @@ TEST(MIPS13) {
MacroAssembler assm(isolate, NULL, 0);
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
+ __ sw(t0, MemOperand(a0, offsetof(T, cvt_small_in)));
__ Cvt_d_uw(f10, t0, f22);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, cvt_small_out)));
__ Trunc_uw_d(f10, f10, f22);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
+ __ swc1(f10, MemOperand(a0, offsetof(T, trunc_small_out)));
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
+ __ sw(t0, MemOperand(a0, offsetof(T, cvt_big_in)));
__ Cvt_d_uw(f8, t0, f22);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
+ __ sdc1(f8, MemOperand(a0, offsetof(T, cvt_big_out)));
__ Trunc_uw_d(f8, f8, f22);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
+ __ swc1(f8, MemOperand(a0, offsetof(T, trunc_big_out)));
__ jr(ra);
__ nop();
@@ -1226,46 +1234,46 @@ TEST(MIPS14) {
// Disable FPU exceptions.
__ ctc1(zero_reg, FCSR);
#define RUN_ROUND_TEST(x) \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err1_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err1_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err2_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err2_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err3_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err3_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err4_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err4_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_invalid_result)));
RUN_ROUND_TEST(round)
RUN_ROUND_TEST(floor)
@@ -1329,7 +1337,8 @@ TEST(MIPS15) {
}
-TEST(MIPS16) {
+// ----------------------mips32r6 specific tests----------------------
+TEST(seleqz_selnez) {
if (IsMipsArchVariant(kMips32r6)) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1345,26 +1354,36 @@ TEST(MIPS16) {
double f;
double g;
double h;
+ float i;
+ float j;
+ float k;
+ float l;
} Test;
Test test;
// Integer part of test.
__ addiu(t1, zero_reg, 1); // t1 = 1
__ seleqz(t3, t1, zero_reg); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, a))); // a = 1
__ seleqz(t2, t1, t1); // t2 = 0
- __ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b = 0
+ __ sw(t2, MemOperand(a0, offsetof(Test, b))); // b = 0
__ selnez(t3, t1, zero_reg); // t3 = 1;
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c = 0
+ __ sw(t3, MemOperand(a0, offsetof(Test, c))); // c = 0
__ selnez(t3, t1, t1); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, d))); // d = 1
// Floating point part of test.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(Test, e)) ); // src
- __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, f)) ); // test
- __ seleqz(D, f4, f0, f2);
- __ selnez(D, f6, f0, f2);
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(Test, g)) ); // src
- __ sdc1(f6, MemOperand(a0, OFFSET_OF(Test, h)) ); // src
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, e)) ); // src
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, f)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, i)) ); // src
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, j)) ); // test
+ __ seleqz_d(f4, f0, f2);
+ __ selnez_d(f6, f0, f2);
+ __ seleqz_s(f12, f8, f10);
+ __ selnez_s(f14, f8, f10);
+ __ sdc1(f4, MemOperand(a0, offsetof(Test, g)) ); // src
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, h)) ); // src
+ __ swc1(f12, MemOperand(a0, offsetof(Test, k)) ); // src
+ __ swc1(f14, MemOperand(a0, offsetof(Test, l)) ); // src
__ jr(ra);
__ nop();
CodeDesc desc;
@@ -1383,31 +1402,44 @@ TEST(MIPS16) {
const int test_size = 3;
const int input_size = 5;
- double inputs[input_size] = {0.0, 65.2, -70.32,
+ double inputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double outputs[input_size] = {0.0, 65.2, -70.32,
+ double outputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double tests[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
18446744073709551616.0, 18446744073709555712.0};
+ float inputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float outputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
for (int j=0; j < test_size; j+=2) {
for (int i=0; i < input_size; i++) {
- test.e = inputs[i];
- test.f = tests[j];
+ test.e = inputs_D[i];
+ test.f = tests_D[j];
+ test.i = inputs_S[i];
+ test.j = tests_S[j];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.g, outputs[i]);
+ CHECK_EQ(test.g, outputs_D[i]);
CHECK_EQ(test.h, 0);
+ CHECK_EQ(test.k, outputs_S[i]);
+ CHECK_EQ(test.l, 0);
- test.f = tests[j+1];
+ test.f = tests_D[j+1];
+ test.j = tests_S[j+1];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.g, 0);
- CHECK_EQ(test.h, outputs[i]);
+ CHECK_EQ(test.h, outputs_D[i]);
+ CHECK_EQ(test.k, 0);
+ CHECK_EQ(test.l, outputs_S[i]);
}
}
}
}
-TEST(MIPS17) {
+TEST(min_max) {
if (IsMipsArchVariant(kMips32r6)) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1419,16 +1451,38 @@ TEST(MIPS17) {
double b;
double c;
double d;
+ float e;
+ float f;
+ float g;
+ float h;
} TestFloat;
TestFloat test;
-
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)));
- __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)));
+ const double dblNaN = std::numeric_limits<double>::quiet_NaN();
+ const float fltNaN = std::numeric_limits<float>::quiet_NaN();
+ const int tableLength = 5;
+ double inputsa[tableLength] = {2.0, 3.0, dblNaN, 3.0, dblNaN};
+ double inputsb[tableLength] = {3.0, 2.0, 3.0, dblNaN, dblNaN};
+ double outputsdmin[tableLength] = {2.0, 2.0, 3.0, 3.0, dblNaN};
+ double outputsdmax[tableLength] = {3.0, 3.0, 3.0, 3.0, dblNaN};
+
+ float inputse[tableLength] = {2.0, 3.0, fltNaN, 3.0, fltNaN};
+ float inputsf[tableLength] = {3.0, 2.0, 3.0, fltNaN, fltNaN};
+ float outputsfmin[tableLength] = {2.0, 2.0, 3.0, 3.0, fltNaN};
+ float outputsfmax[tableLength] = {3.0, 3.0, 3.0, 3.0, fltNaN};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
__ min_d(f10, f4, f8);
__ max_d(f12, f4, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, c)));
- __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, d)));
+ __ min_s(f14, f2, f6);
+ __ max_s(f16, f2, f6);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g)));
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h)));
__ jr(ra);
__ nop();
@@ -1437,40 +1491,31 @@ TEST(MIPS17) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- test.a = 2.0; // a goes to fs
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
-
- test.a = 3.0; // a goes to fs
- test.b = 2.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
-
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.e = inputse[i];
+ test.f = inputsf[i];
- test.b = std::numeric_limits<double>::quiet_NaN();
- test.a = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = std::numeric_limits<double>::quiet_NaN();
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- DCHECK(std::isnan(test.c));
- DCHECK(std::isnan(test.d));
+ if (i < tableLength - 1) {
+ CHECK_EQ(test.c, outputsdmin[i]);
+ CHECK_EQ(test.d, outputsdmax[i]);
+ CHECK_EQ(test.g, outputsfmin[i]);
+ CHECK_EQ(test.h, outputsfmax[i]);
+ } else {
+ DCHECK(std::isnan(test.c));
+ DCHECK(std::isnan(test.d));
+ DCHECK(std::isnan(test.g));
+ DCHECK(std::isnan(test.h));
+ }
+ }
}
}
-TEST(MIPS18) {
+TEST(rint_d) {
if (IsMipsArchVariant(kMips32r6)) {
const int tableLength = 30;
CcTest::InitializeVM();
@@ -1548,12 +1593,191 @@ TEST(MIPS18) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
__ cfc1(t1, FCSR);
__ ctc1(t0, FCSR);
__ rint_d(f8, f4);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)) );
+ __ sdc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ctc1(t1, FCSR);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ for (int j = 0; j < 4; j++) {
+ test.fcsr = fcsr_inputs[j];
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs[j][i]);
+ }
+ }
+ }
+}
+
+
+TEST(sel) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dd;
+ double ds;
+ double dt;
+ float fd;
+ float fs;
+ float ft;
+ } Test;
+
+ Test test;
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, dd)) ); // test
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, ds)) ); // src1
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dt)) ); // src2
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, fd)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, fs)) ); // src1
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, ft)) ); // src2
+ __ sel_d(f0, f2, f4);
+ __ sel_s(f6, f8, f10);
+ __ sdc1(f0, MemOperand(a0, offsetof(Test, dd)) );
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fd)) );
+ __ jr(ra);
+ __ nop();
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ const int test_size = 3;
+ const int input_size = 5;
+
+ double inputs_dt[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ double inputs_ds[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ float inputs_ft[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float inputs_fs[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ 18446744073709551616.0, 18446744073709555712.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
+ for (int j=0; j < test_size; j+=2) {
+ for (int i=0; i < input_size; i++) {
+ test.dt = inputs_dt[i];
+ test.dd = tests_D[j];
+ test.ds = inputs_ds[i];
+ test.ft = inputs_ft[i];
+ test.fd = tests_S[j];
+ test.fs = inputs_fs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_ds[i]);
+ CHECK_EQ(test.fd, inputs_fs[i]);
+
+ test.dd = tests_D[j+1];
+ test.fd = tests_S[j+1];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_dt[i]);
+ CHECK_EQ(test.fd, inputs_ft[i]);
+ }
+ }
+ }
+}
+
+
+TEST(rint_s) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ const int tableLength = 30;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ int fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ float inputs[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E+38, 6.27463370218383111104242366943E-37,
+ 309485009821345068724781056.89,
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RN[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RZ[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RP[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 1,
+ 309485009821345068724781057.0,
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RM[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ int fcsr_inputs[4] =
+ {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
+ float* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t1, FCSR);
+ __ ctc1(t0, FCSR);
+ __ rint_s(f8, f4);
+ __ swc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
__ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1568,7 +1792,6 @@ TEST(MIPS18) {
test.fcsr = fcsr_inputs[j];
for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
- std::cout << j << " " << i << "\n";
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
}
@@ -1577,7 +1800,356 @@ TEST(MIPS18) {
}
-TEST(MIPS19) {
+TEST(mina_maxa) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double resd;
+ double resd1;
+ float c;
+ float d;
+ float resf;
+ float resf1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputsa[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ double inputsb[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ double resd[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ double resd1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+ float inputsc[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ float inputsd[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ float resf[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ float resf1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lwc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mina_d(f6, f2, f4);
+ __ mina_s(f12, f8, f10);
+ __ maxa_d(f14, f2, f4);
+ __ maxa_s(f16, f8, f10);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, resf)) );
+ __ sdc1(f6, MemOperand(a0, offsetof(TestFloat, resd)) );
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resf1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resd1)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.c = inputsc[i];
+ test.d = inputsd[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resd, resd[i]);
+ CHECK_EQ(test.resf, resf[i]);
+ CHECK_EQ(test.resd1, resd1[i]);
+ CHECK_EQ(test.resf1, resf1[i]);
+ }
+ }
+}
+
+
+// ----------------------mips32r2 specific tests----------------------
+TEST(trunc_l) {
+ if (IsMipsArchVariant(kMips32r2) && IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c; // a trunc result
+ int64_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_l_d(f8, f4);
+ __ trunc_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(movz_movn) {
+ if (IsMipsArchVariant(kMips32r2)) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t rt;
+ double a;
+ double b;
+ double bold;
+ double b1;
+ double bold1;
+ float c;
+ float d;
+ float dold;
+ float d1;
+ float dold1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, rt)) );
+ __ li(t1, 0x0);
+ __ mtc1(t1, f12);
+ __ mtc1(t1, f10);
+ __ mtc1(t1, f16);
+ __ mtc1(t1, f14);
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, bold)) );
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, dold)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, bold1)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, dold1)) );
+ __ movz_s(f10, f6, t0);
+ __ movz_d(f12, f2, t0);
+ __ movn_s(f14, f6, t0);
+ __ movn_d(f16, f2, t0);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, d1)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, b1)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ test.rt = 1;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, test.bold);
+ CHECK_EQ(test.d, test.dold);
+ CHECK_EQ(test.b1, outputs_D[i]);
+ CHECK_EQ(test.d1, outputs_S[i]);
+
+ test.rt = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ CHECK_EQ(test.b1, test.bold1);
+ CHECK_EQ(test.d1, test.dold1);
+ }
+ }
+}
+
+
+TEST(movt_movd) {
+ if (IsMipsArchVariant(kMips32r2)) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+
+ typedef struct test_float {
+ double srcd;
+ double dstd;
+ double dstdold;
+ double dstd1;
+ double dstdold1;
+ float srcf;
+ float dstf;
+ float dstfold;
+ float dstf1;
+ float dstfold1;
+ int32_t cc;
+ int32_t fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+ for (int i = 0; i < tableLength; i++) {
+ test.srcd = inputs_D[i];
+ test.srcf = inputs_S[i];
+
+ for (int j = 0; j< 8; j++) {
+ test.cc = condition_flags[j];
+ if (test.cc == 0) {
+ test.fcsr = 1 << 23;
+ } else {
+ test.fcsr = 1 << (24+condition_flags[j]);
+ }
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) );
+ __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t0, FCSR);
+ __ ctc1(t1, FCSR);
+ __ li(t2, 0x0);
+ __ mtc1(t2, f12);
+ __ mtc1(t2, f10);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold)) );
+ __ movt_s(f12, f4, test.cc);
+ __ movt_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold1)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold1)) );
+ __ movf_s(f12, f4, test.cc);
+ __ movf_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf1)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd1)) );
+ __ ctc1(t0, FCSR);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, outputs_S[i]);
+ CHECK_EQ(test.dstd, outputs_D[i]);
+ CHECK_EQ(test.dstf1, test.dstfold1);
+ CHECK_EQ(test.dstd1, test.dstdold1);
+ test.fcsr = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, test.dstfold);
+ CHECK_EQ(test.dstd, test.dstdold);
+ CHECK_EQ(test.dstf1, outputs_S[i]);
+ CHECK_EQ(test.dstd1, outputs_D[i]);
+ }
+ }
+ }
+}
+
+
+// ----------------------tests for all archs--------------------------
+TEST(cvt_w_d) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
@@ -1628,12 +2200,12 @@ TEST(MIPS19) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(Test, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(Test, fcsr)) );
__ cfc1(t1, FCSR);
__ ctc1(t0, FCSR);
__ cvt_w_d(f8, f4);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, b)) );
+ __ swc1(f8, MemOperand(a0, offsetof(Test, b)) );
__ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1647,7 +2219,6 @@ TEST(MIPS19) {
test.fcsr = fcsr_inputs[j];
for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
- std::cout << i << " " << j << "\n";
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
}
@@ -1655,6 +2226,750 @@ TEST(MIPS19) {
}
+TEST(trunc_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_w_d(f8, f4);
+ __ trunc_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_w_d(f8, f4);
+ __ round_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_l) {
+ if (IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_l_d(f8, f4);
+ __ round_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(sub) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ double outputs_D[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ float inputfs_S[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ float outputs_S[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sub_s(f6, f2, f4);
+ __ sub_d(f12, f8, f10);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+TEST(sqrt_rsqrt_recip) {
+ const int tableLength = 4;
+ const double deltaDouble = 2E-15;
+ const float deltaFloat = 2E-7;
+ const float sqrt2_s = sqrt(2);
+ const double sqrt2_d = sqrt(2);
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ float resultS1;
+ float resultS2;
+ double c;
+ double resultD;
+ double resultD1;
+ double resultD2;
+ }TestFloat;
+ TestFloat test;
+
+ double inputs_D[tableLength] = {
+ 0.0L, 4.0L, 2.0L, 4e-28L
+ };
+
+ double outputs_D[tableLength] = {
+ 0.0L, 2.0L, sqrt2_d, 2e-14L
+ };
+ float inputs_S[tableLength] = {
+ 0.0, 4.0, 2.0, 4e-28
+ };
+
+ float outputs_S[tableLength] = {
+ 0.0, 2.0, sqrt2_s, 2e-14
+ };
+
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ sqrt_s(f6, f2);
+ __ sqrt_d(f12, f8);
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ __ rsqrt_d(f14, f8);
+ __ rsqrt_s(f16, f2);
+ __ recip_d(f18, f8);
+ __ recip_s(f20, f2);
+ }
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resultS1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resultD1)) );
+ __ swc1(f20, MemOperand(a0, offsetof(TestFloat, resultS2)) );
+ __ sdc1(f18, MemOperand(a0, offsetof(TestFloat, resultD2)) );
+ }
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ for (int i = 0; i < tableLength; i++) {
+ float f1;
+ double d1;
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ if (i != 0) {
+ f1 = test.resultS1 - 1.0F/outputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD1 - 1.0L/outputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ f1 = test.resultS2 - 1.0F/inputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD2 - 1.0L/inputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ } else {
+ CHECK_EQ(test.resultS1, 1.0F/outputs_S[i]);
+ CHECK_EQ(test.resultD1, 1.0L/outputs_D[i]);
+ CHECK_EQ(test.resultS2, 1.0F/inputs_S[i]);
+ CHECK_EQ(test.resultD2, 1.0L/inputs_D[i]);
+ }
+ }
+ }
+}
+
+
+TEST(neg) {
+ const int tableLength = 3;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ double c;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 0.0, 4.0, -2.0
+ };
+
+ double outputs_D[tableLength] = {
+ 0.0, -4.0, 2.0
+ };
+ float inputs_S[tableLength] = {
+ 0.0, 4.0, -2.0
+ };
+
+ float outputs_S[tableLength] = {
+ 0.0, -4.0, 2.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ neg_s(f6, f2);
+ __ neg_d(f12, f8);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+TEST(mul) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float inputfs_S[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mul_s(f10, f2, f4);
+ __ mul_d(f12, f6, f8);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]);
+ CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]);
+ }
+}
+
+
+TEST(mov) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ float c;
+ float d;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ mov_s(f18, f6);
+ __ mov_d(f20, f2);
+ __ swc1(f18, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f20, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ }
+}
+
+
+TEST(floor_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_w_d(f8, f4);
+ __ floor_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(floor_l) {
+ if (IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_l_d(f8, f4);
+ __ floor_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(ceil_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_w_d(f8, f4);
+ __ ceil_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(ceil_l) {
+ if (IsFp64Mode()) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_l_d(f8, f4);
+ __ ceil_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
TEST(jump_tables1) {
// Test jump tables with forward jumps.
CcTest::InitializeVM();
@@ -1869,4 +3184,1879 @@ TEST(jump_tables3) {
}
+TEST(BITSWAP) {
+ // Test BITSWAP
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ int32_t r1;
+ int32_t r2;
+ int32_t r3;
+ int32_t r4;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+
+ __ lw(a2, MemOperand(a0, offsetof(T, r1)));
+ __ nop();
+ __ bitswap(a1, a2);
+ __ sw(a1, MemOperand(a0, offsetof(T, r1)));
+
+ __ lw(a2, MemOperand(a0, offsetof(T, r2)));
+ __ nop();
+ __ bitswap(a1, a2);
+ __ sw(a1, MemOperand(a0, offsetof(T, r2)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.r1 = 0x781A15C3;
+ t.r2 = 0x8B71FCDE;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(static_cast<int32_t>(0x1E58A8C3), t.r1);
+ CHECK_EQ(static_cast<int32_t>(0xD18E3F7B), t.r2);
+ }
+}
+
+
+TEST(class_fmt) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ // Test CLASS.fmt instruction.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double dSignalingNan;
+ double dQuietNan;
+ double dNegInf;
+ double dNegNorm;
+ double dNegSubnorm;
+ double dNegZero;
+ double dPosInf;
+ double dPosNorm;
+ double dPosSubnorm;
+ double dPosZero;
+ float fSignalingNan;
+ float fQuietNan;
+ float fNegInf;
+ float fNegNorm;
+ float fNegSubnorm;
+ float fNegZero;
+ float fPosInf;
+ float fPosNorm;
+ float fPosSubnorm;
+ float fPosZero; } T;
+ T t;
+
+ // Create a function that accepts &t, and loads, manipulates, and stores
+ // the doubles t.a ... t.f.
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dSignalingNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dQuietNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dQuietNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegZero)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosZero)));
+
+ // Testing instruction CLASS.S
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fSignalingNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fSignalingNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fQuietNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fQuietNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegZero)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosZero)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ t.dSignalingNan = std::numeric_limits<double>::signaling_NaN();
+ t.dQuietNan = std::numeric_limits<double>::quiet_NaN();
+ t.dNegInf = -1.0 / 0.0;
+ t.dNegNorm = -5.0;
+ t.dNegSubnorm = -DBL_MIN / 2.0;
+ t.dNegZero = -0.0;
+ t.dPosInf = 2.0 / 0.0;
+ t.dPosNorm = 275.35;
+ t.dPosSubnorm = DBL_MIN / 2.0;
+ t.dPosZero = +0.0;
+ // Float test values
+
+ t.fSignalingNan = std::numeric_limits<float>::signaling_NaN();
+ t.fQuietNan = std::numeric_limits<float>::quiet_NaN();
+ t.fNegInf = -0.5/0.0;
+ t.fNegNorm = -FLT_MIN;
+ t.fNegSubnorm = -FLT_MIN / 1.5;
+ t.fNegZero = -0.0;
+ t.fPosInf = 100000.0 / 0.0;
+ t.fPosNorm = FLT_MAX;
+ t.fPosSubnorm = FLT_MIN / 20.0;
+ t.fPosZero = +0.0;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ // Expected double results.
+ CHECK_EQ(bit_cast<int64_t>(t.dSignalingNan), 0x001);
+ CHECK_EQ(bit_cast<int64_t>(t.dQuietNan), 0x002);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegInf), 0x004);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegZero), 0x020);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosInf), 0x040);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosZero), 0x200);
+
+ // Expected float results.
+ CHECK_EQ(bit_cast<int32_t>(t.fSignalingNan), 0x001);
+ CHECK_EQ(bit_cast<int32_t>(t.fQuietNan), 0x002);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegInf), 0x004);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegZero), 0x020);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosInf), 0x040);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosZero), 0x200);
+ }
+}
+
+
+TEST(ABS) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t fir;
+ double a;
+ float b;
+ double fcsr;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FIR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ abs_d(f10, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, a)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)));
+ __ abs_s(f10, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, b)));
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ test.a = -2.0;
+ test.b = -2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ test.a = 2.0;
+ test.b = 2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ // Testing biggest positive number
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest negative number
+ test.a = -std::numeric_limits<double>::max(); // lowest()
+ test.b = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest positive number
+ test.a = -std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::min());
+
+ // Testing infinity
+ test.a = -std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min());
+
+ test.a = std::numeric_limits<double>::quiet_NaN();
+ test.b = std::numeric_limits<float>::quiet_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+
+ test.a = std::numeric_limits<double>::signaling_NaN();
+ test.b = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+}
+
+
+TEST(ADD_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double c;
+ float fa;
+ float fb;
+ float fc;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ add_d(f10, f8, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, fa)));
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, fb)));
+ __ add_s(f10, f8, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, fc)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ test.a = 2.0;
+ test.b = 3.0;
+ test.fa = 2.0;
+ test.fb = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 5.0);
+ CHECK_EQ(test.fc, 5.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = -std::numeric_limits<double>::max(); // lowest()
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 0.0);
+ CHECK_EQ(test.fc, 0.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<double>::max();
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isfinite(test.c), false);
+ CHECK_EQ(std::isfinite(test.fc), false);
+
+ test.a = 5.0;
+ test.b = std::numeric_limits<double>::signaling_NaN();
+ test.fa = 5.0;
+ test.fb = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.c), true);
+ CHECK_EQ(std::isnan(test.fc), true);
+}
+
+
+TEST(C_COND_FMT) {
+ if ((IsMipsArchVariant(kMips32r1)) || (IsMipsArchVariant(kMips32r2))) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ uint32_t dF;
+ uint32_t dUn;
+ uint32_t dEq;
+ uint32_t dUeq;
+ uint32_t dOlt;
+ uint32_t dUlt;
+ uint32_t dOle;
+ uint32_t dUle;
+ float fOp1;
+ float fOp2;
+ uint32_t fF;
+ uint32_t fUn;
+ uint32_t fEq;
+ uint32_t fUeq;
+ uint32_t fOlt;
+ uint32_t fUlt;
+ uint32_t fOle;
+ uint32_t fUle;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(F, f4, f6, 0);
+ __ c_s(F, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UN, f4, f6, 2);
+ __ c_s(UN, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(EQ, f4, f6, 4);
+ __ c_s(EQ, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UEQ, f4, f6, 6);
+ __ c_s(UEQ, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLT, f4, f6, 0);
+ __ c_s(OLT, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULT, f4, f6, 2);
+ __ c_s(ULT, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLE, f4, f6, 4);
+ __ c_s(OLE, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULE, f4, f6, 6);
+ __ c_s(ULE, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 1U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 1U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 0U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 0U);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 1U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 1U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 1U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 1U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 1U);
+ }
+}
+
+
+TEST(CMP_COND_FMT) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ double dF;
+ double dUn;
+ double dEq;
+ double dUeq;
+ double dOlt;
+ double dUlt;
+ double dOle;
+ double dUle;
+ double dOr;
+ double dUne;
+ double dNe;
+ float fOp1;
+ float fOp2;
+ float fF;
+ float fUn;
+ float fEq;
+ float fUeq;
+ float fOlt;
+ float fUlt;
+ float fOle;
+ float fUle;
+ float fOr;
+ float fUne;
+ float fNe;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ cmp_d(F, f2, f4, f6);
+ __ cmp_s(F, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ cmp_d(UN, f2, f4, f6);
+ __ cmp_s(UN, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ cmp_d(EQ, f2, f4, f6);
+ __ cmp_s(EQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ cmp_d(UEQ, f2, f4, f6);
+ __ cmp_s(UEQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ cmp_d(LT, f2, f4, f6);
+ __ cmp_s(LT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ cmp_d(ULT, f2, f4, f6);
+ __ cmp_s(ULT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ cmp_d(LE, f2, f4, f6);
+ __ cmp_s(LE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ cmp_d(ULE, f2, f4, f6);
+ __ cmp_s(ULE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ cmp_d(ORD, f2, f4, f6);
+ __ cmp_s(ORD, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOr)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOr)) );
+
+ __ cmp_d(UNE, f2, f4, f6);
+ __ cmp_s(UNE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUne)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUne)) );
+
+ __ cmp_d(NE, f2, f4, f6);
+ __ cmp_s(NE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dNe)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fNe)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ uint64_t dTrue = 0xFFFFFFFFFFFFFFFF;
+ uint64_t dFalse = 0x0000000000000000;
+ uint32_t fTrue = 0xFFFFFFFF;
+ uint32_t fFalse = 0x00000000;
+
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fFalse);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+ }
+}
+
+
+TEST(CVT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float cvt_d_s_in;
+ double cvt_d_s_out;
+ int32_t cvt_d_w_in;
+ double cvt_d_w_out;
+ int64_t cvt_d_l_in;
+ double cvt_d_l_out;
+
+ float cvt_l_s_in;
+ int64_t cvt_l_s_out;
+ double cvt_l_d_in;
+ int64_t cvt_l_d_out;
+
+ double cvt_s_d_in;
+ float cvt_s_d_out;
+ int32_t cvt_s_w_in;
+ float cvt_s_w_out;
+ int64_t cvt_s_l_in;
+ float cvt_s_l_out;
+
+ float cvt_w_s_in;
+ int32_t cvt_w_s_out;
+ double cvt_w_d_in;
+ int32_t cvt_w_d_out;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+#define GENERATE_CVT_TEST(x, y, z) \
+ __ y##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_in))); \
+ __ x(f0, f0); \
+ __ nop(); \
+ __ z##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_out)));
+
+ GENERATE_CVT_TEST(cvt_d_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_d_w, lw, sd)
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ GENERATE_CVT_TEST(cvt_d_l, ld, sd)
+ }
+
+ if (IsFp64Mode()) {
+ GENERATE_CVT_TEST(cvt_l_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_l_d, ld, sd)
+ }
+
+ GENERATE_CVT_TEST(cvt_s_d, ld, sw)
+ GENERATE_CVT_TEST(cvt_s_w, lw, sw)
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ GENERATE_CVT_TEST(cvt_s_l, ld, sw)
+ }
+
+ GENERATE_CVT_TEST(cvt_w_s, lw, sw)
+ GENERATE_CVT_TEST(cvt_w_d, ld, sw)
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ test.cvt_d_s_in = -0.51;
+ test.cvt_d_w_in = -1;
+ test.cvt_d_l_in = -1;
+ test.cvt_l_s_in = -0.51;
+ test.cvt_l_d_in = -0.51;
+ test.cvt_s_d_in = -0.51;
+ test.cvt_s_w_in = -1;
+ test.cvt_s_l_in = -1;
+ test.cvt_w_s_in = -0.51;
+ test.cvt_w_d_in = -0.51;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, -1);
+ CHECK_EQ(test.cvt_l_d_out, -1);
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, -1);
+ CHECK_EQ(test.cvt_w_d_out, -1);
+
+
+ test.cvt_d_s_in = 0.49;
+ test.cvt_d_w_in = 1;
+ test.cvt_d_l_in = 1;
+ test.cvt_l_s_in = 0.49;
+ test.cvt_l_d_in = 0.49;
+ test.cvt_s_d_in = 0.49;
+ test.cvt_s_w_in = 1;
+ test.cvt_s_l_in = 1;
+ test.cvt_w_s_in = 0.49;
+ test.cvt_w_d_in = 0.49;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+
+ test.cvt_d_s_in = std::numeric_limits<float>::max();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_l_s_in = std::numeric_limits<float>::max();
+ test.cvt_l_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_w_s_in = std::numeric_limits<float>::max();
+ test.cvt_w_d_in = std::numeric_limits<double>::max();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_l_d_out, std::numeric_limits<int64_t>::max());
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max());
+ CHECK_EQ(test.cvt_w_d_out, std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_l_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_l_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_w_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_w_d_in = -std::numeric_limits<double>::max(); // lowest()
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ // The returned value when converting from fixed-point to float-point
+ // is not consistent between board, simulator and specification
+ // in this test case, therefore modifying the test
+ if (IsFp64Mode()) {
+ CHECK(test.cvt_l_s_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_s_out == std::numeric_limits<int64_t>::max());
+ CHECK(test.cvt_l_d_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_d_out == std::numeric_limits<int64_t>::max());
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_s_out == std::numeric_limits<int32_t>::max());
+ CHECK(test.cvt_w_d_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_d_out == std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = std::numeric_limits<float>::min();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_l_s_in = std::numeric_limits<float>::min();
+ test.cvt_l_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_w_s_in = std::numeric_limits<float>::min();
+ test.cvt_w_d_in = std::numeric_limits<double>::min();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ }
+ if (IsFp64Mode()) {
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ }
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ }
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+}
+
+
+TEST(DIV_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dOp1;
+ double dOp2;
+ double dRes;
+ float fOp1;
+ float fOp2;
+ float fRes;
+ } Test;
+
+ Test test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dOp1)) );
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, dOp2)) );
+ __ nop();
+ __ div_d(f6, f4, f2);
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, dRes)) );
+
+ __ lwc1(f4, MemOperand(a0, offsetof(Test, fOp1)) );
+ __ lwc1(f2, MemOperand(a0, offsetof(Test, fOp2)) );
+ __ nop();
+ __ div_s(f6, f4, f2);
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fRes)) );
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ const int test_size = 3;
+
+ double dOp1[test_size] = {
+ 5.0,
+ DBL_MAX,
+ DBL_MAX,
+ };
+ double dOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -DBL_MAX,
+ };
+ double dRes[test_size] = {
+ 2.5,
+ DBL_MAX / 2.0,
+ -1.0,
+ };
+ float fOp1[test_size] = {
+ 5.0,
+ FLT_MAX,
+ FLT_MAX,
+ };
+ float fOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -FLT_MAX,
+ };
+ float fRes[test_size] = {
+ 2.5,
+ FLT_MAX / 2.0,
+ -1.0,
+ };
+
+ for (int i = 0; i < test_size; i++) {
+ test.dOp1 = dOp1[i];
+ test.dOp2 = dOp2[i];
+ test.fOp1 = fOp1[i];
+ test.fOp2 = fOp2[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dRes, dRes[i]);
+ CHECK_EQ(test.fRes, fRes[i]);
+ }
+
+ test.dOp1 = DBL_MAX;
+ test.dOp2 = -0.0;
+ test.fOp1 = FLT_MAX;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(false, std::isfinite(test.dRes));
+ CHECK_EQ(false, std::isfinite(test.fRes));
+
+ test.dOp1 = 0.0;
+ test.dOp2 = -0.0;
+ test.fOp1 = 0.0;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = -5.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = -5.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+}
+
+
+uint32_t run_align(uint32_t rs_value, uint32_t rt_value, uint8_t bp) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ align(v0, a0, a1, bp);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, rs_value,
+ rt_value,
+ 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_align) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAlign {
+ uint32_t rs_value;
+ uint32_t rt_value;
+ uint8_t bp;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseAlign tc[] = {
+ // rs_value, rt_value, bp, expected_res
+ { 0x11223344, 0xaabbccdd, 0, 0xaabbccdd },
+ { 0x11223344, 0xaabbccdd, 1, 0xbbccdd11 },
+ { 0x11223344, 0xaabbccdd, 2, 0xccdd1122 },
+ { 0x11223344, 0xaabbccdd, 3, 0xdd112233 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_align(tc[i].rs_value,
+ tc[i].rt_value, tc[i].bp));
+ }
+ }
+}
+
+uint32_t PC; // The program counter.
+
+uint32_t run_aluipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ aluipc(v0, offset);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ PC = (uint32_t) f; // Set the program counter.
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_aluipc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAluipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAluipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint32_t res = run_aluipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint32_t expected_res = ~0x0FFFF & (PC + (tc[i].offset << 16));
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_auipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ auipc(v0, offset);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ PC = (uint32_t) f; // Set the program counter.
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_auipc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAuipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAuipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint32_t res = run_auipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint32_t expected_res = PC + (tc[i].offset << 16);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_lwpc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2^8k
+ // addiu t7, t0, 0xffff; (0x250fffff)
+ // ...
+ // addiu t4, t0, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ lwpc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2^8k
+ // addiu t0, t0, 0x0000; (0x25080000)
+ // ...
+ // addiu t3, t0, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_lwpc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLwpc {
+ int offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseLwpc tc[] = {
+ // offset, expected_res
+ { -262144, 0x250fffff }, // offset 0x40000
+ { -4, 0x250c0003 },
+ { -1, 0x250c0000 },
+ { 0, 0xef080000 },
+ { 1, 0x03001025 }, // mov(v0, t8)
+ { 2, 0x25080000 },
+ { 4, 0x25080002 },
+ { 262143, 0x250bfffd }, // offset 0x3ffff
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_lwpc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_jic(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label get_program_counter, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -32
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jic(t0, offset);
+
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 16
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jic) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJic {
+ // As rt will be used t0 register which will have value of
+ // the program counter for the jic instruction.
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJic tc[] = {
+ // offset, expected_result
+ { 16, 0x2033 },
+ { 4, 0x3333 },
+ { -32, 0x66 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_jic(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_beqzc(int32_t value, int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label stop_execution;
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+ __ push(ra);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -32
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ beqzc(a0, offset); // BEQZC rs, offset
+
+ __ addiu(v0, v0, 0x1);
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 16
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, value, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_beqzc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBeqzc {
+ uint32_t value;
+ int32_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseBeqzc tc[] = {
+ // value, offset, expected_res
+ { 0x0, -8, 0x66 },
+ { 0x0, 0, 0x3334 },
+ { 0x0, 1, 0x3333 },
+ { 0xabc, 1, 0x3334 },
+ { 0x0, 4, 0x2033 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_beqzc(tc[i].value, tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint32_t run_jialc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label main_block, get_program_counter;
+ __ push(ra);
+ __ li(v0, 0);
+ __ beq(v0, v0, &main_block);
+ __ nop();
+
+ // Block 1
+ __ addiu(v0, v0, 0x1); // <-- offset = -40
+ __ addiu(v0, v0, 0x2);
+ __ jr(ra);
+ __ nop();
+
+ // Block 2
+ __ addiu(v0, v0, 0x10); // <-- offset = -24
+ __ addiu(v0, v0, 0x20);
+ __ jr(ra);
+ __ nop();
+
+ // Block 3 (Main)
+ __ bind(&main_block);
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jialc(t0, offset);
+ __ addiu(v0, v0, 0x4);
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ // Block 4
+ __ addiu(v0, v0, 0x100); // <-- offset = 20
+ __ addiu(v0, v0, 0x200);
+ __ jr(ra);
+ __ nop();
+
+ // Block 5
+ __ addiu(v0, v0, 0x1000); // <--- offset = 36
+ __ addiu(v0, v0, 0x2000);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ jr(ra);
+ __ nop();
+
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint32_t res =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jialc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJialc {
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJialc tc[] = {
+ // offset, expected_res
+ { -40, 0x7 },
+ { -24, 0x34 },
+ { 20, 0x304 },
+ { 36, 0x3004 }
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_jialc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_addiupc(int32_t imm19) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ addiupc(v0, imm19);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ PC = (uint32_t) f; // Set the program counter.
+
+ uint32_t rs =
+ reinterpret_cast<uint32_t>(CALL_GENERATED_CODE(f, imm19, 0, 0, 0, 0));
+
+ return rs;
+}
+
+
+TEST(r6_addiupc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAddiupc {
+ int32_t imm19;
+ };
+
+ struct TestCaseAddiupc tc[] = {
+ // imm19
+ { -262144 }, // 0x40000
+ { -1 }, // 0x7FFFF
+ { 0 },
+ { 1 }, // 0x00001
+ { 262143 } // 0x3FFFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint32_t res = run_addiupc(tc[i].imm19);
+ // Now, the program_counter (PC) is set.
+ uint32_t expected_res = PC + (tc[i].imm19 << 2);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+int32_t run_bc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // A condition for stopping execution.
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -100; i <= -11; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ addiu(t8, t8, 1); // -10
+
+ __ beq(t8, t9, &stop_execution); // -9
+ __ nop(); // -8
+ __ beq(t8, t8, &continue_1); // -7
+ __ nop(); // -6
+
+ __ bind(&stop_execution);
+ __ pop(ra); // -5, -4
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ bc(offset); // -1
+
+ for (int32_t i = 0; i <= 99; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ int32_t res =
+ reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_bc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBc {
+ int32_t offset;
+ int32_t expected_res;
+ };
+
+ struct TestCaseBc tc[] = {
+ // offset, expected_result
+ { -100, (abs(-100) - 10) * 2 },
+ { -11, (abs(-100) - 10 + 1) },
+ { 0, (abs(-100) - 10 + 1 + 99) },
+ { 1, (abs(-100) - 10 + 99) },
+ { 99, (abs(-100) - 10 + 1) },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int32_t res = run_bc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+int32_t run_balc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // A condition for stopping execution.
+
+ __ beq(t8, t8, &continue_1);
+ __ nop();
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -117; i <= -57; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -56
+ __ nop(); // -55
+
+ for (int32_t i = -54; i <= -4; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ balc(offset); // -1
+
+ __ pop(ra); // 0, 1
+ __ jr(ra); // 2
+ __ nop(); // 3
+
+ for (int32_t i = 4; i <= 44; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ int32_t res =
+ reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_balc) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBalc {
+ int32_t offset;
+ int32_t expected_res;
+ };
+
+ struct TestCaseBalc tc[] = {
+ // offset, expected_result
+ { -117, 61 },
+ { -54, 51 },
+ { 0, 0 },
+ { 4, 41 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int32_t res = run_balc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc
index 3b422a2716..bb7b05ca76 100644
--- a/deps/v8/test/cctest/test-assembler-mips64.cc
+++ b/deps/v8/test/cctest/test-assembler-mips64.cc
@@ -45,6 +45,7 @@ using namespace v8::internal;
typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
+typedef Object* (*F4)(int64_t x, int64_t y, int64_t p2, int64_t p3, int64_t p4);
// clang-format off
@@ -289,61 +290,61 @@ TEST(MIPS3) {
Label L, C;
// Double precision floating point instructions.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
__ add_d(f8, f4, f6);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, c)) ); // c = a + b.
+ __ sdc1(f8, MemOperand(a0, offsetof(T, c)) ); // c = a + b.
__ mov_d(f10, f8); // c
__ neg_d(f12, f6); // -b
__ sub_d(f10, f10, f12);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, d)) ); // d = c - (-b).
+ __ sdc1(f10, MemOperand(a0, offsetof(T, d)) ); // d = c - (-b).
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, b)) ); // b = a.
+ __ sdc1(f4, MemOperand(a0, offsetof(T, b)) ); // b = a.
__ li(a4, 120);
__ mtc1(a4, f14);
__ cvt_d_w(f14, f14); // f14 = 120.0.
__ mul_d(f10, f10, f14);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, e)) ); // e = d * 120 = 1.8066e16.
+ __ sdc1(f10, MemOperand(a0, offsetof(T, e)) ); // e = d * 120 = 1.8066e16.
__ div_d(f12, f10, f4);
- __ sdc1(f12, MemOperand(a0, OFFSET_OF(T, f)) ); // f = e / a = 120.44.
+ __ sdc1(f12, MemOperand(a0, offsetof(T, f)) ); // f = e / a = 120.44.
__ sqrt_d(f14, f12);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, g)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(T, g)) );
// g = sqrt(f) = 10.97451593465515908537
if (kArchVariant == kMips64r2) {
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, h)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, h)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, i)) );
__ madd_d(f14, f6, f4, f6);
- __ sdc1(f14, MemOperand(a0, OFFSET_OF(T, h)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(T, h)) );
}
// Single precision floating point instructions.
- __ lwc1(f4, MemOperand(a0, OFFSET_OF(T, fa)) );
- __ lwc1(f6, MemOperand(a0, OFFSET_OF(T, fb)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fa)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(T, fb)) );
__ add_s(f8, f4, f6);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, fc)) ); // fc = fa + fb.
+ __ swc1(f8, MemOperand(a0, offsetof(T, fc)) ); // fc = fa + fb.
__ neg_s(f10, f6); // -fb
__ sub_s(f10, f8, f10);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fd)) ); // fd = fc - (-fb).
+ __ swc1(f10, MemOperand(a0, offsetof(T, fd)) ); // fd = fc - (-fb).
- __ swc1(f4, MemOperand(a0, OFFSET_OF(T, fb)) ); // fb = fa.
+ __ swc1(f4, MemOperand(a0, offsetof(T, fb)) ); // fb = fa.
__ li(t0, 120);
__ mtc1(t0, f14);
__ cvt_s_w(f14, f14); // f14 = 120.0.
__ mul_s(f10, f10, f14);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, fe)) ); // fe = fd * 120
+ __ swc1(f10, MemOperand(a0, offsetof(T, fe)) ); // fe = fd * 120
__ div_s(f12, f10, f4);
- __ swc1(f12, MemOperand(a0, OFFSET_OF(T, ff)) ); // ff = fe / fa
+ __ swc1(f12, MemOperand(a0, offsetof(T, ff)) ); // ff = fe / fa
__ sqrt_s(f14, f12);
- __ swc1(f14, MemOperand(a0, OFFSET_OF(T, fg)) );
+ __ swc1(f14, MemOperand(a0, offsetof(T, fg)) );
__ jr(ra);
__ nop();
@@ -412,8 +413,8 @@ TEST(MIPS4) {
Assembler assm(isolate, NULL, 0);
Label L, C;
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)));
- __ ldc1(f5, MemOperand(a0, OFFSET_OF(T, b)));
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)));
+ __ ldc1(f5, MemOperand(a0, offsetof(T, b)));
// Swap f4 and f5, by using 3 integer registers, a4-a6,
// both two 32-bit chunks, and one 64-bit chunk.
@@ -428,16 +429,16 @@ TEST(MIPS4) {
__ dmtc1(a6, f4);
// Store the swapped f4 and f5 back to memory.
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(T, a)));
- __ sdc1(f5, MemOperand(a0, OFFSET_OF(T, c)));
+ __ sdc1(f4, MemOperand(a0, offsetof(T, a)));
+ __ sdc1(f5, MemOperand(a0, offsetof(T, c)));
// Test sign extension of move operations from coprocessor.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, d)));
+ __ ldc1(f4, MemOperand(a0, offsetof(T, d)));
__ mfhc1(a4, f4);
__ mfc1(a5, f4);
- __ sd(a4, MemOperand(a0, OFFSET_OF(T, high)));
- __ sd(a5, MemOperand(a0, OFFSET_OF(T, low)));
+ __ sd(a4, MemOperand(a0, offsetof(T, high)));
+ __ sd(a5, MemOperand(a0, offsetof(T, low)));
__ jr(ra);
__ nop();
@@ -480,30 +481,30 @@ TEST(MIPS5) {
Label L, C;
// Load all structure elements to registers.
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, i)) );
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, j)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
+ __ lw(a4, MemOperand(a0, offsetof(T, i)) );
+ __ lw(a5, MemOperand(a0, offsetof(T, j)) );
// Convert double in f4 to int in element i.
__ cvt_w_d(f8, f4);
__ mfc1(a6, f8);
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, i)) );
+ __ sw(a6, MemOperand(a0, offsetof(T, i)) );
// Convert double in f6 to int in element j.
__ cvt_w_d(f10, f6);
__ mfc1(a7, f10);
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, j)) );
+ __ sw(a7, MemOperand(a0, offsetof(T, j)) );
// Convert int in original i (a4) to double in a.
__ mtc1(a4, f12);
__ cvt_d_w(f0, f12);
- __ sdc1(f0, MemOperand(a0, OFFSET_OF(T, a)) );
+ __ sdc1(f0, MemOperand(a0, offsetof(T, a)) );
// Convert int in original j (a5) to double in b.
__ mtc1(a5, f14);
__ cvt_d_w(f2, f14);
- __ sdc1(f2, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ sdc1(f2, MemOperand(a0, offsetof(T, b)) );
__ jr(ra);
__ nop();
@@ -549,31 +550,31 @@ TEST(MIPS6) {
Label L, C;
// Basic word load/store.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)) );
+ __ lw(a4, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(a4, MemOperand(a0, offsetof(T, r1)) );
// lh with positive data.
- __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)) );
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)) );
+ __ lh(a5, MemOperand(a0, offsetof(T, ui)) );
+ __ sw(a5, MemOperand(a0, offsetof(T, r2)) );
// lh with negative data.
- __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)) );
+ __ lh(a6, MemOperand(a0, offsetof(T, si)) );
+ __ sw(a6, MemOperand(a0, offsetof(T, r3)) );
// lhu with negative data.
- __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)) );
+ __ lhu(a7, MemOperand(a0, offsetof(T, si)) );
+ __ sw(a7, MemOperand(a0, offsetof(T, r4)) );
// lb with negative data.
- __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)) );
+ __ lb(t0, MemOperand(a0, offsetof(T, si)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, r5)) );
// sh writes only 1/2 of word.
__ lui(t1, 0x3333);
__ ori(t1, t1, 0x3333);
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
- __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)) );
- __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, r6)) );
+ __ lhu(t1, MemOperand(a0, offsetof(T, si)) );
+ __ sh(t1, MemOperand(a0, offsetof(T, r6)) );
__ jr(ra);
__ nop();
@@ -619,8 +620,8 @@ TEST(MIPS7) {
MacroAssembler assm(isolate, NULL, 0);
Label neither_is_nan, less_than, outa_here;
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(T, a)) );
- __ ldc1(f6, MemOperand(a0, OFFSET_OF(T, b)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(T, a)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(T, b)) );
if (kArchVariant != kMips64r6) {
__ c(UN, D, f4, f6);
__ bc1f(&neither_is_nan);
@@ -629,7 +630,7 @@ TEST(MIPS7) {
__ bc1eqz(&neither_is_nan, f2);
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&neither_is_nan);
@@ -643,12 +644,12 @@ TEST(MIPS7) {
}
__ nop();
- __ sw(zero_reg, MemOperand(a0, OFFSET_OF(T, result)) );
+ __ sw(zero_reg, MemOperand(a0, offsetof(T, result)) );
__ Branch(&outa_here);
__ bind(&less_than);
__ Addu(a4, zero_reg, Operand(1));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, result)) ); // Set true.
+ __ sw(a4, MemOperand(a0, offsetof(T, result)) ); // Set true.
// This test-case should have additional tests.
@@ -707,7 +708,7 @@ TEST(MIPS8) {
MacroAssembler assm(isolate, NULL, 0);
// Basic word load.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, input)) );
+ __ lw(a4, MemOperand(a0, offsetof(T, input)) );
// ROTR instruction (called through the Ror macro).
__ Ror(a5, a4, 0x0004);
@@ -719,13 +720,13 @@ TEST(MIPS8) {
__ Ror(t3, a4, 0x001c);
// Basic word store.
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotr_4)) );
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotr_8)) );
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotr_12)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotr_16)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotr_20)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotr_24)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotr_28)) );
+ __ sw(a5, MemOperand(a0, offsetof(T, result_rotr_4)) );
+ __ sw(a6, MemOperand(a0, offsetof(T, result_rotr_8)) );
+ __ sw(a7, MemOperand(a0, offsetof(T, result_rotr_12)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, result_rotr_16)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotr_20)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotr_24)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotr_28)) );
// ROTRV instruction (called through the Ror macro).
__ li(t3, 0x0004);
@@ -744,13 +745,13 @@ TEST(MIPS8) {
__ Ror(t3, a4, t3);
// Basic word store.
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, result_rotrv_4)) );
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, result_rotrv_8)) );
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, result_rotrv_12)) );
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, result_rotrv_16)) );
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, result_rotrv_20)) );
- __ sw(t2, MemOperand(a0, OFFSET_OF(T, result_rotrv_24)) );
- __ sw(t3, MemOperand(a0, OFFSET_OF(T, result_rotrv_28)) );
+ __ sw(a5, MemOperand(a0, offsetof(T, result_rotrv_4)) );
+ __ sw(a6, MemOperand(a0, offsetof(T, result_rotrv_8)) );
+ __ sw(a7, MemOperand(a0, offsetof(T, result_rotrv_12)) );
+ __ sw(t0, MemOperand(a0, offsetof(T, result_rotrv_16)) );
+ __ sw(t1, MemOperand(a0, offsetof(T, result_rotrv_20)) );
+ __ sw(t2, MemOperand(a0, offsetof(T, result_rotrv_24)) );
+ __ sw(t3, MemOperand(a0, offsetof(T, result_rotrv_28)) );
__ jr(ra);
__ nop();
@@ -838,42 +839,42 @@ TEST(MIPS10) {
// - 32 FP regs of 64-bits each, no odd/even pairs.
// - Note that cvt_l_d/cvt_d_l ARE legal in FR=1 mode.
// Load all structure elements to registers.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, a)));
+ __ ldc1(f0, MemOperand(a0, offsetof(T, a)));
// Save the raw bits of the double.
__ mfc1(a4, f0);
__ mfhc1(a5, f0);
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, dbl_mant)));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, dbl_exp)));
+ __ sw(a4, MemOperand(a0, offsetof(T, dbl_mant)));
+ __ sw(a5, MemOperand(a0, offsetof(T, dbl_exp)));
// Convert double in f0 to long, save hi/lo parts.
__ cvt_l_d(f0, f0);
__ mfc1(a4, f0); // f0 LS 32 bits of long.
__ mfhc1(a5, f0); // f0 MS 32 bits of long.
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, long_lo)));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, long_hi)));
+ __ sw(a4, MemOperand(a0, offsetof(T, long_lo)));
+ __ sw(a5, MemOperand(a0, offsetof(T, long_hi)));
// Combine the high/low ints, convert back to double.
__ dsll32(a6, a5, 0); // Move a5 to high bits of a6.
__ or_(a6, a6, a4);
__ dmtc1(a6, f1);
__ cvt_d_l(f1, f1);
- __ sdc1(f1, MemOperand(a0, OFFSET_OF(T, a_converted)));
+ __ sdc1(f1, MemOperand(a0, offsetof(T, a_converted)));
// Convert the b long integers to double b.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, b_long_lo)));
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, b_long_hi)));
+ __ lw(a4, MemOperand(a0, offsetof(T, b_long_lo)));
+ __ lw(a5, MemOperand(a0, offsetof(T, b_long_hi)));
__ mtc1(a4, f8); // f8 LS 32-bits.
__ mthc1(a5, f8); // f8 MS 32-bits.
__ cvt_d_l(f10, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, b)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, b)));
// Convert double b back to long-int.
- __ ldc1(f31, MemOperand(a0, OFFSET_OF(T, b)));
+ __ ldc1(f31, MemOperand(a0, offsetof(T, b)));
__ cvt_l_d(f31, f31);
__ dmfc1(a7, f31);
- __ sd(a7, MemOperand(a0, OFFSET_OF(T, b_long_as_int64)));
+ __ sd(a7, MemOperand(a0, offsetof(T, b_long_as_int64)));
__ jr(ra);
@@ -936,80 +937,80 @@ TEST(MIPS11) {
Assembler assm(isolate, NULL, 0);
// Test all combinations of LWL and vAddr.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwl(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwl_0)));
+ __ lw(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(T, lwl_0)));
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwl(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwl_1)));
+ __ lw(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a5, MemOperand(a0, offsetof(T, mem_init) + 1));
+ __ sw(a5, MemOperand(a0, offsetof(T, lwl_1)));
- __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwl(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2));
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwl_2)));
+ __ lw(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a6, MemOperand(a0, offsetof(T, mem_init) + 2));
+ __ sw(a6, MemOperand(a0, offsetof(T, lwl_2)));
- __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwl(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3));
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwl_3)));
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwl(a7, MemOperand(a0, offsetof(T, mem_init) + 3));
+ __ sw(a7, MemOperand(a0, offsetof(T, lwl_3)));
// Test all combinations of LWR and vAddr.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwr(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, lwr_0)));
+ __ lw(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(T, lwr_0)));
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwr(a5, MemOperand(a0, OFFSET_OF(T, mem_init) + 1));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, lwr_1)));
+ __ lw(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a5, MemOperand(a0, offsetof(T, mem_init) + 1));
+ __ sw(a5, MemOperand(a0, offsetof(T, lwr_1)));
- __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwr(a6, MemOperand(a0, OFFSET_OF(T, mem_init) + 2));
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, lwr_2)) );
+ __ lw(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a6, MemOperand(a0, offsetof(T, mem_init) + 2));
+ __ sw(a6, MemOperand(a0, offsetof(T, lwr_2)) );
- __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ lwr(a7, MemOperand(a0, OFFSET_OF(T, mem_init) + 3));
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, lwr_3)) );
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ lwr(a7, MemOperand(a0, offsetof(T, mem_init) + 3));
+ __ sw(a7, MemOperand(a0, offsetof(T, lwr_3)) );
// Test all combinations of SWL and vAddr.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, swl_0)));
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swl(a4, MemOperand(a0, OFFSET_OF(T, swl_0)));
-
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, swl_1)));
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swl(a5, MemOperand(a0, OFFSET_OF(T, swl_1) + 1));
-
- __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, swl_2)));
- __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swl(a6, MemOperand(a0, OFFSET_OF(T, swl_2) + 2));
-
- __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, swl_3)));
- __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swl(a7, MemOperand(a0, OFFSET_OF(T, swl_3) + 3));
+ __ lw(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(T, swl_0)));
+ __ lw(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a4, MemOperand(a0, offsetof(T, swl_0)));
+
+ __ lw(a5, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a5, MemOperand(a0, offsetof(T, swl_1)));
+ __ lw(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a5, MemOperand(a0, offsetof(T, swl_1) + 1));
+
+ __ lw(a6, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a6, MemOperand(a0, offsetof(T, swl_2)));
+ __ lw(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a6, MemOperand(a0, offsetof(T, swl_2) + 2));
+
+ __ lw(a7, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a7, MemOperand(a0, offsetof(T, swl_3)));
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ swl(a7, MemOperand(a0, offsetof(T, swl_3) + 3));
// Test all combinations of SWR and vAddr.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, swr_0)));
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swr(a4, MemOperand(a0, OFFSET_OF(T, swr_0)));
-
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, swr_1)));
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swr(a5, MemOperand(a0, OFFSET_OF(T, swr_1) + 1));
-
- __ lw(a6, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, swr_2)));
- __ lw(a6, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swr(a6, MemOperand(a0, OFFSET_OF(T, swr_2) + 2));
-
- __ lw(a7, MemOperand(a0, OFFSET_OF(T, mem_init)));
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, swr_3)));
- __ lw(a7, MemOperand(a0, OFFSET_OF(T, reg_init)));
- __ swr(a7, MemOperand(a0, OFFSET_OF(T, swr_3) + 3));
+ __ lw(a4, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a4, MemOperand(a0, offsetof(T, swr_0)));
+ __ lw(a4, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a4, MemOperand(a0, offsetof(T, swr_0)));
+
+ __ lw(a5, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a5, MemOperand(a0, offsetof(T, swr_1)));
+ __ lw(a5, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a5, MemOperand(a0, offsetof(T, swr_1) + 1));
+
+ __ lw(a6, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a6, MemOperand(a0, offsetof(T, swr_2)));
+ __ lw(a6, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a6, MemOperand(a0, offsetof(T, swr_2) + 2));
+
+ __ lw(a7, MemOperand(a0, offsetof(T, mem_init)));
+ __ sw(a7, MemOperand(a0, offsetof(T, swr_3)));
+ __ lw(a7, MemOperand(a0, offsetof(T, reg_init)));
+ __ swr(a7, MemOperand(a0, offsetof(T, swr_3) + 3));
__ jr(ra);
__ nop();
@@ -1067,8 +1068,8 @@ TEST(MIPS12) {
__ mov(t2, fp); // Save frame pointer.
__ mov(fp, a0); // Access struct T by fp.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, y)));
- __ lw(a7, MemOperand(a0, OFFSET_OF(T, y4)));
+ __ lw(a4, MemOperand(a0, offsetof(T, y)));
+ __ lw(a7, MemOperand(a0, offsetof(T, y4)));
__ addu(a5, a4, a7);
__ subu(t0, a4, a7);
@@ -1086,30 +1087,30 @@ TEST(MIPS12) {
__ push(a7);
__ pop(t0);
__ nop();
- __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)));
- __ lw(a4, MemOperand(fp, OFFSET_OF(T, y)));
+ __ sw(a4, MemOperand(fp, offsetof(T, y)));
+ __ lw(a4, MemOperand(fp, offsetof(T, y)));
__ nop();
- __ sw(a4, MemOperand(fp, OFFSET_OF(T, y)));
- __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)));
+ __ sw(a4, MemOperand(fp, offsetof(T, y)));
+ __ lw(a5, MemOperand(fp, offsetof(T, y)));
__ nop();
__ push(a5);
- __ lw(a5, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a5, MemOperand(fp, offsetof(T, y)));
__ pop(a5);
__ nop();
__ push(a5);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a5);
__ nop();
__ push(a5);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a6);
__ nop();
__ push(a6);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a5);
__ nop();
__ push(a5);
- __ lw(a6, MemOperand(fp, OFFSET_OF(T, y)));
+ __ lw(a6, MemOperand(fp, offsetof(T, y)));
__ pop(a7);
__ nop();
@@ -1154,19 +1155,19 @@ TEST(MIPS13) {
MacroAssembler assm(isolate, NULL, 0);
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_small_in)));
+ __ sw(a4, MemOperand(a0, offsetof(T, cvt_small_in)));
__ Cvt_d_uw(f10, a4, f22);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(T, cvt_small_out)));
+ __ sdc1(f10, MemOperand(a0, offsetof(T, cvt_small_out)));
__ Trunc_uw_d(f10, f10, f22);
- __ swc1(f10, MemOperand(a0, OFFSET_OF(T, trunc_small_out)));
+ __ swc1(f10, MemOperand(a0, offsetof(T, trunc_small_out)));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, cvt_big_in)));
+ __ sw(a4, MemOperand(a0, offsetof(T, cvt_big_in)));
__ Cvt_d_uw(f8, a4, f22);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(T, cvt_big_out)));
+ __ sdc1(f8, MemOperand(a0, offsetof(T, cvt_big_out)));
__ Trunc_uw_d(f8, f8, f22);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(T, trunc_big_out)));
+ __ swc1(f8, MemOperand(a0, offsetof(T, trunc_big_out)));
__ jr(ra);
__ nop();
@@ -1236,46 +1237,46 @@ TEST(MIPS14) {
// Disable FPU exceptions.
__ ctc1(zero_reg, FCSR);
#define RUN_ROUND_TEST(x) \
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_up_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_up_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_up_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_up_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, neg_round_down_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, neg_round_down_in))); \
__ x##_w_d(f0, f0); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, neg_##x##_down_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, neg_##x##_down_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err1_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err1_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err1_out))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err1_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err2_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err2_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err2_out))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err2_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err3_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err3_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err3_out))); \
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err3_out))); \
\
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(T, err4_in))); \
+ __ ldc1(f0, MemOperand(a0, offsetof(T, err4_in))); \
__ ctc1(zero_reg, FCSR); \
__ x##_w_d(f0, f0); \
__ cfc1(a2, FCSR); \
- __ sw(a2, MemOperand(a0, OFFSET_OF(T, x##_err4_out))); \
- __ swc1(f0, MemOperand(a0, OFFSET_OF(T, x##_invalid_result)));
+ __ sw(a2, MemOperand(a0, offsetof(T, x##_err4_out))); \
+ __ swc1(f0, MemOperand(a0, offsetof(T, x##_invalid_result)));
RUN_ROUND_TEST(round)
RUN_ROUND_TEST(floor)
@@ -1363,48 +1364,48 @@ TEST(MIPS16) {
Label L, C;
// Basic 32-bit word load/store, with un-signed data.
- __ lw(a4, MemOperand(a0, OFFSET_OF(T, ui)));
- __ sw(a4, MemOperand(a0, OFFSET_OF(T, r1)));
+ __ lw(a4, MemOperand(a0, offsetof(T, ui)));
+ __ sw(a4, MemOperand(a0, offsetof(T, r1)));
// Check that the data got zero-extended into 64-bit a4.
- __ sd(a4, MemOperand(a0, OFFSET_OF(T, r2)));
+ __ sd(a4, MemOperand(a0, offsetof(T, r2)));
// Basic 32-bit word load/store, with SIGNED data.
- __ lw(a5, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, r3)));
+ __ lw(a5, MemOperand(a0, offsetof(T, si)));
+ __ sw(a5, MemOperand(a0, offsetof(T, r3)));
// Check that the data got sign-extended into 64-bit a4.
- __ sd(a5, MemOperand(a0, OFFSET_OF(T, r4)));
+ __ sd(a5, MemOperand(a0, offsetof(T, r4)));
// 32-bit UNSIGNED word load/store, with SIGNED data.
- __ lwu(a6, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, r5)));
+ __ lwu(a6, MemOperand(a0, offsetof(T, si)));
+ __ sw(a6, MemOperand(a0, offsetof(T, r5)));
// Check that the data got zero-extended into 64-bit a4.
- __ sd(a6, MemOperand(a0, OFFSET_OF(T, r6)));
+ __ sd(a6, MemOperand(a0, offsetof(T, r6)));
// lh with positive data.
- __ lh(a5, MemOperand(a0, OFFSET_OF(T, ui)));
- __ sw(a5, MemOperand(a0, OFFSET_OF(T, r2)));
+ __ lh(a5, MemOperand(a0, offsetof(T, ui)));
+ __ sw(a5, MemOperand(a0, offsetof(T, r2)));
// lh with negative data.
- __ lh(a6, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(a6, MemOperand(a0, OFFSET_OF(T, r3)));
+ __ lh(a6, MemOperand(a0, offsetof(T, si)));
+ __ sw(a6, MemOperand(a0, offsetof(T, r3)));
// lhu with negative data.
- __ lhu(a7, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(a7, MemOperand(a0, OFFSET_OF(T, r4)));
+ __ lhu(a7, MemOperand(a0, offsetof(T, si)));
+ __ sw(a7, MemOperand(a0, offsetof(T, r4)));
// lb with negative data.
- __ lb(t0, MemOperand(a0, OFFSET_OF(T, si)));
- __ sw(t0, MemOperand(a0, OFFSET_OF(T, r5)));
+ __ lb(t0, MemOperand(a0, offsetof(T, si)));
+ __ sw(t0, MemOperand(a0, offsetof(T, r5)));
// // sh writes only 1/2 of word.
__ lui(t1, 0x3333);
__ ori(t1, t1, 0x3333);
- __ sw(t1, MemOperand(a0, OFFSET_OF(T, r6)));
- __ lhu(t1, MemOperand(a0, OFFSET_OF(T, si)));
- __ sh(t1, MemOperand(a0, OFFSET_OF(T, r6)));
+ __ sw(t1, MemOperand(a0, offsetof(T, r6)));
+ __ lhu(t1, MemOperand(a0, offsetof(T, si)));
+ __ sh(t1, MemOperand(a0, offsetof(T, r6)));
__ jr(ra);
__ nop();
@@ -1439,7 +1440,8 @@ TEST(MIPS16) {
}
-TEST(MIPS17) {
+// ----------------------mips32r6 specific tests----------------------
+TEST(seleqz_selnez) {
if (kArchVariant == kMips64r6) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1455,26 +1457,36 @@ TEST(MIPS17) {
double f;
double g;
double h;
+ float i;
+ float j;
+ float k;
+ float l;
} Test;
Test test;
// Integer part of test.
__ addiu(t1, zero_reg, 1); // t1 = 1
__ seleqz(t3, t1, zero_reg); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, a))); // a = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, a))); // a = 1
__ seleqz(t2, t1, t1); // t2 = 0
- __ sw(t2, MemOperand(a0, OFFSET_OF(Test, b))); // b = 0
+ __ sw(t2, MemOperand(a0, offsetof(Test, b))); // b = 0
__ selnez(t3, t1, zero_reg); // t3 = 1;
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, c))); // c = 0
+ __ sw(t3, MemOperand(a0, offsetof(Test, c))); // c = 0
__ selnez(t3, t1, t1); // t3 = 1
- __ sw(t3, MemOperand(a0, OFFSET_OF(Test, d))); // d = 1
+ __ sw(t3, MemOperand(a0, offsetof(Test, d))); // d = 1
// Floating point part of test.
- __ ldc1(f0, MemOperand(a0, OFFSET_OF(Test, e)) ); // src
- __ ldc1(f2, MemOperand(a0, OFFSET_OF(Test, f)) ); // test
- __ seleqz(D, f4, f0, f2);
- __ selnez(D, f6, f0, f2);
- __ sdc1(f4, MemOperand(a0, OFFSET_OF(Test, g)) ); // src
- __ sdc1(f6, MemOperand(a0, OFFSET_OF(Test, h)) ); // src
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, e)) ); // src
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, f)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, i)) ); // src
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, j)) ); // test
+ __ seleqz_d(f4, f0, f2);
+ __ selnez_d(f6, f0, f2);
+ __ seleqz_s(f12, f8, f10);
+ __ selnez_s(f14, f8, f10);
+ __ sdc1(f4, MemOperand(a0, offsetof(Test, g)) ); // src
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, h)) ); // src
+ __ swc1(f12, MemOperand(a0, offsetof(Test, k)) ); // src
+ __ swc1(f14, MemOperand(a0, offsetof(Test, l)) ); // src
__ jr(ra);
__ nop();
CodeDesc desc;
@@ -1493,31 +1505,45 @@ TEST(MIPS17) {
const int test_size = 3;
const int input_size = 5;
- double inputs[input_size] = {0.0, 65.2, -70.32,
+ double inputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double outputs[input_size] = {0.0, 65.2, -70.32,
+ double outputs_D[input_size] = {0.0, 65.2, -70.32,
18446744073709551621.0, -18446744073709551621.0};
- double tests[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
18446744073709551616.0, 18446744073709555712.0};
- for (int j=0;j < test_size;j+=2) {
- for (int i=0;i < input_size;i++) {
- test.e = inputs[i];
- test.f = tests[j];
+ float inputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float outputs_S[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
+ for (int j=0; j < test_size; j+=2) {
+ for (int i=0; i < input_size; i++) {
+ test.e = inputs_D[i];
+ test.f = tests_D[j];
+ test.i = inputs_S[i];
+ test.j = tests_S[j];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.g, outputs[i]);
+ CHECK_EQ(test.g, outputs_D[i]);
CHECK_EQ(test.h, 0);
+ CHECK_EQ(test.k, outputs_S[i]);
+ CHECK_EQ(test.l, 0);
- test.f = tests[j+1];
+ test.f = tests_D[j+1];
+ test.j = tests_S[j+1];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.g, 0);
- CHECK_EQ(test.h, outputs[i]);
+ CHECK_EQ(test.h, outputs_D[i]);
+ CHECK_EQ(test.k, 0);
+ CHECK_EQ(test.l, outputs_S[i]);
}
}
}
}
-TEST(MIPS18) {
+
+TEST(min_max) {
if (kArchVariant == kMips64r6) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -1529,16 +1555,38 @@ TEST(MIPS18) {
double b;
double c;
double d;
+ float e;
+ float f;
+ float g;
+ float h;
} TestFloat;
TestFloat test;
-
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)));
- __ ldc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)));
+ const double dblNaN = std::numeric_limits<double>::quiet_NaN();
+ const float fltNaN = std::numeric_limits<float>::quiet_NaN();
+ const int tableLength = 5;
+ double inputsa[tableLength] = {2.0, 3.0, dblNaN, 3.0, dblNaN};
+ double inputsb[tableLength] = {3.0, 2.0, 3.0, dblNaN, dblNaN};
+ double outputsdmin[tableLength] = {2.0, 2.0, 3.0, 3.0, dblNaN};
+ double outputsdmax[tableLength] = {3.0, 3.0, 3.0, 3.0, dblNaN};
+
+ float inputse[tableLength] = {2.0, 3.0, fltNaN, 3.0, fltNaN};
+ float inputsf[tableLength] = {3.0, 2.0, 3.0, fltNaN, fltNaN};
+ float outputsfmin[tableLength] = {2.0, 2.0, 3.0, 3.0, fltNaN};
+ float outputsfmax[tableLength] = {3.0, 3.0, 3.0, 3.0, fltNaN};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, e)));
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, f)));
__ min_d(f10, f4, f8);
__ max_d(f12, f4, f8);
- __ sdc1(f10, MemOperand(a0, OFFSET_OF(TestFloat, c)));
- __ sdc1(f12, MemOperand(a0, OFFSET_OF(TestFloat, d)));
+ __ min_s(f14, f2, f6);
+ __ max_s(f16, f2, f6);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, d)));
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, g)));
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, h)));
__ jr(ra);
__ nop();
@@ -1547,40 +1595,31 @@ TEST(MIPS18) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- test.a = 2.0; // a goes to fs
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.e = inputse[i];
+ test.f = inputsf[i];
- test.a = 3.0; // a goes to fs
- test.b = 2.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 2.0);
- CHECK_EQ(test.d, 3.0);
-
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
-
- test.b = std::numeric_limits<double>::quiet_NaN();
- test.a = 3.0; // b goes to ft
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.c, 3.0);
- CHECK_EQ(test.d, 3.0);
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- test.a = std::numeric_limits<double>::quiet_NaN();
- test.b = std::numeric_limits<double>::quiet_NaN();
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- DCHECK(std::isnan(test.c));
- DCHECK(std::isnan(test.d));
+ if (i < tableLength - 1) {
+ CHECK_EQ(test.c, outputsdmin[i]);
+ CHECK_EQ(test.d, outputsdmax[i]);
+ CHECK_EQ(test.g, outputsfmin[i]);
+ CHECK_EQ(test.h, outputsfmax[i]);
+ } else {
+ DCHECK(std::isnan(test.c));
+ DCHECK(std::isnan(test.d));
+ DCHECK(std::isnan(test.g));
+ DCHECK(std::isnan(test.h));
+ }
+ }
}
}
-TEST(MIPS19) {
+TEST(rint_d) {
if (kArchVariant == kMips64r6) {
const int tableLength = 30;
CcTest::InitializeVM();
@@ -1658,11 +1697,190 @@ TEST(MIPS19) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
__ ctc1(t0, FCSR);
__ rint_d(f8, f4);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)) );
+ __ sdc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ for (int j = 0; j < 4; j++) {
+ test.fcsr = fcsr_inputs[j];
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs[j][i]);
+ }
+ }
+ }
+}
+
+
+TEST(sel) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dd;
+ double ds;
+ double dt;
+ float fd;
+ float fs;
+ float ft;
+ } Test;
+
+ Test test;
+ __ ldc1(f0, MemOperand(a0, offsetof(Test, dd)) ); // test
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, ds)) ); // src1
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dt)) ); // src2
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, fd)) ); // test
+ __ lwc1(f8, MemOperand(a0, offsetof(Test, fs)) ); // src1
+ __ lwc1(f10, MemOperand(a0, offsetof(Test, ft)) ); // src2
+ __ sel_d(f0, f2, f4);
+ __ sel_s(f6, f8, f10);
+ __ sdc1(f0, MemOperand(a0, offsetof(Test, dd)) );
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fd)) );
+ __ jr(ra);
+ __ nop();
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ const int test_size = 3;
+ const int input_size = 5;
+
+ double inputs_dt[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ double inputs_ds[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ float inputs_ft[input_size] = {0.0, 65.2, -70.32,
+ 18446744073709551621.0, -18446744073709551621.0};
+ float inputs_fs[input_size] = {0.1, 69.88, -91.325,
+ 18446744073709551625.0, -18446744073709551625.0};
+ double tests_D[test_size*2] = {2.8, 2.9, -2.8, -2.9,
+ 18446744073709551616.0, 18446744073709555712.0};
+ float tests_S[test_size*2] = {2.9, 2.8, -2.9, -2.8,
+ 18446744073709551616.0, 18446746272732807168.0};
+ for (int j=0; j < test_size; j+=2) {
+ for (int i=0; i < input_size; i++) {
+ test.dt = inputs_dt[i];
+ test.dd = tests_D[j];
+ test.ds = inputs_ds[i];
+ test.ft = inputs_ft[i];
+ test.fd = tests_S[j];
+ test.fs = inputs_fs[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_ds[i]);
+ CHECK_EQ(test.fd, inputs_fs[i]);
+
+ test.dd = tests_D[j+1];
+ test.fd = tests_S[j+1];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dd, inputs_dt[i]);
+ CHECK_EQ(test.fd, inputs_ft[i]);
+ }
+ }
+ }
+}
+
+
+TEST(rint_s) {
+ if (kArchVariant == kMips64r6) {
+ const int tableLength = 30;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ int fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ float inputs[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E+38, 6.27463370218383111104242366943E-37,
+ 309485009821345068724781056.89,
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RN[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RZ[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RP[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 1,
+ 309485009821345068724781057.0,
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ float outputs_RM[tableLength] = {18446744073709551617.0,
+ 4503599627370496.0, -4503599627370496.0,
+ 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E37,
+ 1.7976931348623157E38, 0,
+ 309485009821345068724781057.0,
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 37778931862957161709568.0, 37778931862957161709569.0,
+ 37778931862957161709580.0, 37778931862957161709581.0,
+ 37778931862957161709582.0, 37778931862957161709583.0,
+ 37778931862957161709584.0, 37778931862957161709585.0,
+ 37778931862957161709586.0, 37778931862957161709587.0};
+ int fcsr_inputs[4] =
+ {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
+ float* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t1, FCSR);
+ __ ctc1(t0, FCSR);
+ __ rint_s(f8, f4);
+ __ swc1(f8, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1672,11 +1890,10 @@ TEST(MIPS19) {
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- for (int j = 0;j < 4;j++) {
+ for (int j = 0; j < 4; j++) {
test.fcsr = fcsr_inputs[j];
- for (int i = 0;i < tableLength;i++) {
+ for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
- std::cout << j << " " << i << "\n";
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
}
@@ -1685,7 +1902,358 @@ TEST(MIPS19) {
}
-TEST(MIPS20) {
+TEST(mina_maxa) {
+ if (kArchVariant == kMips64r6) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double resd;
+ double resd1;
+ float c;
+ float d;
+ float resf;
+ float resf1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputsa[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ double inputsb[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ double resd[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ double resd1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+ float inputsc[tableLength] = {
+ 5.3, 4.8, 6.1,
+ 9.8, 9.8, 9.8,
+ -10.0, -8.9, -9.8,
+ -10.0, -8.9, -9.8
+ };
+ float inputsd[tableLength] = {
+ 4.8, 5.3, 6.1,
+ -10.0, -8.9, -9.8,
+ 9.8, 9.8, 9.8,
+ -9.8, -11.2, -9.8
+ };
+ float resf[tableLength] = {
+ 4.8, 4.8, 6.1,
+ 9.8, -8.9, 9.8,
+ 9.8, -8.9, 9.8,
+ -9.8, -8.9, -9.8
+ };
+ float resf1[tableLength] = {
+ 5.3, 5.3, 6.1,
+ -10.0, 9.8, 9.8,
+ -10.0, 9.8, 9.8,
+ -10.0, -11.2, -9.8
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lwc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mina_d(f6, f2, f4);
+ __ mina_s(f12, f8, f10);
+ __ maxa_d(f14, f2, f4);
+ __ maxa_s(f16, f8, f10);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, resf)) );
+ __ sdc1(f6, MemOperand(a0, offsetof(TestFloat, resd)) );
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resf1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resd1)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputsa[i];
+ test.b = inputsb[i];
+ test.c = inputsc[i];
+ test.d = inputsd[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ CHECK_EQ(test.resd, resd[i]);
+ CHECK_EQ(test.resf, resf[i]);
+ CHECK_EQ(test.resd1, resd1[i]);
+ CHECK_EQ(test.resf1, resf1[i]);
+ }
+ }
+}
+
+
+
+// ----------------------mips32r2 specific tests----------------------
+TEST(trunc_l) {
+ if (kArchVariant == kMips64r2) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c; // a trunc result
+ int64_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_l_d(f8, f4);
+ __ trunc_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+ }
+}
+
+
+TEST(movz_movn) {
+ if (kArchVariant == kMips64r2) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t rt;
+ double a;
+ double b;
+ double bold;
+ double b1;
+ double bold1;
+ float c;
+ float d;
+ float dold;
+ float d1;
+ float dold1;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ lw(t0, MemOperand(a0, offsetof(TestFloat, rt)) );
+ __ li(t1, 0x0);
+ __ mtc1(t1, f12);
+ __ mtc1(t1, f10);
+ __ mtc1(t1, f16);
+ __ mtc1(t1, f14);
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, bold)) );
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, dold)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, bold1)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, dold1)) );
+ __ movz_s(f10, f6, t0);
+ __ movz_d(f12, f2, t0);
+ __ movn_s(f14, f6, t0);
+ __ movn_d(f16, f2, t0);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ swc1(f14, MemOperand(a0, offsetof(TestFloat, d1)) );
+ __ sdc1(f16, MemOperand(a0, offsetof(TestFloat, b1)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ test.rt = 1;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, test.bold);
+ CHECK_EQ(test.d, test.dold);
+ CHECK_EQ(test.b1, outputs_D[i]);
+ CHECK_EQ(test.d1, outputs_S[i]);
+
+ test.rt = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ CHECK_EQ(test.b1, test.bold1);
+ CHECK_EQ(test.d1, test.dold1);
+ }
+ }
+}
+
+
+TEST(movt_movd) {
+ if (kArchVariant == kMips64r2) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ typedef struct test_float {
+ double srcd;
+ double dstd;
+ double dstdold;
+ double dstd1;
+ double dstdold1;
+ float srcf;
+ float dstf;
+ float dstfold;
+ float dstf1;
+ float dstfold1;
+ int32_t cc;
+ int32_t fcsr;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.88, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 20.8, -2.9
+ };
+ int condition_flags[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+
+ for (int i = 0; i < tableLength; i++) {
+ test.srcd = inputs_D[i];
+ test.srcf = inputs_S[i];
+
+ for (int j = 0; j< 8; j++) {
+ test.cc = condition_flags[j];
+ if (test.cc == 0) {
+ test.fcsr = 1 << 23;
+ } else {
+ test.fcsr = 1 << (24+condition_flags[j]);
+ }
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, srcd)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, srcf)) );
+ __ lw(t1, MemOperand(a0, offsetof(TestFloat, fcsr)) );
+ __ cfc1(t0, FCSR);
+ __ ctc1(t1, FCSR);
+ __ li(t2, 0x0);
+ __ mtc1(t2, f12);
+ __ mtc1(t2, f10);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold)) );
+ __ movt_s(f12, f4, test.cc);
+ __ movt_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstdold1)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstfold1)) );
+ __ movf_s(f12, f4, test.cc);
+ __ movf_d(f10, f2, test.cc);
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, dstf1)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, dstd1)) );
+ __ ctc1(t0, FCSR);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, outputs_S[i]);
+ CHECK_EQ(test.dstd, outputs_D[i]);
+ CHECK_EQ(test.dstf1, test.dstfold1);
+ CHECK_EQ(test.dstd1, test.dstdold1);
+ test.fcsr = 0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dstf, test.dstfold);
+ CHECK_EQ(test.dstd, test.dstdold);
+ CHECK_EQ(test.dstf1, outputs_S[i]);
+ CHECK_EQ(test.dstd1, outputs_D[i]);
+ }
+ }
+ }
+}
+
+
+
+// ----------------------tests for all archs--------------------------
+TEST(cvt_w_d) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
@@ -1736,12 +2304,12 @@ TEST(MIPS20) {
int fcsr_inputs[4] =
{kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(Test, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(Test, fcsr)) );
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lw(t0, MemOperand(a0, offsetof(Test, fcsr)) );
__ cfc1(t1, FCSR);
__ ctc1(t0, FCSR);
__ cvt_w_d(f8, f4);
- __ swc1(f8, MemOperand(a0, OFFSET_OF(Test, b)) );
+ __ swc1(f8, MemOperand(a0, offsetof(Test, b)) );
__ ctc1(t1, FCSR);
__ jr(ra);
__ nop();
@@ -1751,9 +2319,9 @@ TEST(MIPS20) {
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- for (int j = 0;j < 4;j++) {
+ for (int j = 0; j < 4; j++) {
test.fcsr = fcsr_inputs[j];
- for (int i = 0;i < tableLength;i++) {
+ for (int i = 0; i < tableLength; i++) {
test.a = inputs[i];
(CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
CHECK_EQ(test.b, outputs[j][i]);
@@ -1762,111 +2330,736 @@ TEST(MIPS20) {
}
-TEST(MIPS21) {
- if (kArchVariant == kMips64r6) {
- const int tableLength = 30;
+TEST(trunc_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ trunc_w_d(f8, f4);
+ __ trunc_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a trunc result
+ int32_t d; // b trunc result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_w_d(f8, f4);
+ __ round_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(round_l) {
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0);
-
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
typedef struct test_float {
double a;
- double b;
- int fcsr;
- }TestFloat;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
+ -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ round_l_d(f8, f4);
+ __ round_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ std::cout<< i<< "\n";
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
- TestFloat test;
- double inputs[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 6.27463370218383111104242366943E-307,
- 309485009821345068724781056.89,
+
+TEST(sub) {
+ const int tableLength = 12;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ double outputs_D[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ float inputfs_S[tableLength] = {
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9,
+ 5.3, 4.8, 2.9, -5.3, -4.8, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 5.3, 2.9, 4.8, 5.3, 2.9,
+ -4.8, -5.3, -2.9, -4.8, -5.3, -2.9
+ };
+ float outputs_S[tableLength] = {
+ 0.5, -0.5, 0.0, -10.1, -10.1, -5.8,
+ 10.1, 10.1, 5.8, -0.5, 0.5, 0.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f10, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sub_s(f6, f2, f4);
+ __ sub_d(f12, f8, f10);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+TEST(sqrt_rsqrt_recip) {
+ const int tableLength = 4;
+ const double deltaDouble = 2E-15;
+ const float deltaFloat = 2E-7;
+ const float sqrt2_s = sqrt(2);
+ const double sqrt2_d = sqrt(2);
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ float resultS1;
+ float resultS2;
+ double c;
+ double resultD;
+ double resultD1;
+ double resultD2;
+ }TestFloat;
+ TestFloat test;
+
+ double inputs_D[tableLength] = {
+ 0.0L, 4.0L, 2.0L, 4e-28L
+ };
+
+ double outputs_D[tableLength] = {
+ 0.0L, 2.0L, sqrt2_d, 2e-14L
+ };
+ float inputs_S[tableLength] = {
+ 0.0, 4.0, 2.0, 4e-28
+ };
+
+ float outputs_S[tableLength] = {
+ 0.0, 2.0, sqrt2_s, 2e-14
+ };
+
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ sqrt_s(f6, f2);
+ __ sqrt_d(f12, f8);
+ __ rsqrt_d(f14, f8);
+ __ rsqrt_s(f16, f2);
+ __ recip_d(f18, f8);
+ __ recip_s(f20, f2);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ swc1(f16, MemOperand(a0, offsetof(TestFloat, resultS1)) );
+ __ sdc1(f14, MemOperand(a0, offsetof(TestFloat, resultD1)) );
+ __ swc1(f20, MemOperand(a0, offsetof(TestFloat, resultS2)) );
+ __ sdc1(f18, MemOperand(a0, offsetof(TestFloat, resultD2)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ for (int i = 0; i < tableLength; i++) {
+ float f1;
+ double d1;
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+
+ if (i != 0) {
+ f1 = test.resultS1 - 1.0F/outputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD1 - 1.0L/outputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ f1 = test.resultS2 - 1.0F/inputs_S[i];
+ f1 = (f1 < 0) ? f1 : -f1;
+ CHECK(f1 <= deltaFloat);
+ d1 = test.resultD2 - 1.0L/inputs_D[i];
+ d1 = (d1 < 0) ? d1 : -d1;
+ CHECK(d1 <= deltaDouble);
+ } else {
+ CHECK_EQ(test.resultS1, 1.0F/outputs_S[i]);
+ CHECK_EQ(test.resultD1, 1.0L/outputs_D[i]);
+ CHECK_EQ(test.resultS2, 1.0F/inputs_S[i]);
+ CHECK_EQ(test.resultD2, 1.0L/inputs_D[i]);
+ }
+ }
+}
+
+
+TEST(neg) {
+ const int tableLength = 2;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float resultS;
+ double c;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 4.0, -2.0
+ };
+
+ double outputs_D[tableLength] = {
+ -4.0, 2.0
+ };
+ float inputs_S[tableLength] = {
+ 4.0, -2.0
+ };
+
+ float outputs_S[tableLength] = {
+ -4.0, 2.0
+ };
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ neg_s(f6, f2);
+ __ neg_d(f12, f8);
+ __ swc1(f6, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_S[i];
+ test.c = inputs_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, outputs_S[i]);
+ CHECK_EQ(test.resultD, outputs_D[i]);
+ }
+}
+
+
+
+TEST(mul) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float a;
+ float b;
+ float resultS;
+ double c;
+ double d;
+ double resultD;
+ }TestFloat;
+
+ TestFloat test;
+ double inputfs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputft_D[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float inputfs_S[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ float inputft_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ __ lwc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ mul_s(f10, f2, f4);
+ __ mul_d(f12, f6, f8);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, resultS)) );
+ __ sdc1(f12, MemOperand(a0, offsetof(TestFloat, resultD)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputfs_S[i];
+ test.b = inputft_S[i];
+ test.c = inputfs_D[i];
+ test.d = inputft_D[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.resultS, inputfs_S[i]*inputft_S[i]);
+ CHECK_EQ(test.resultD, inputfs_D[i]*inputft_D[i]);
+ }
+}
+
+
+TEST(mov) {
+ const int tableLength = 4;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ float c;
+ float d;
+ }TestFloat;
+
+ TestFloat test;
+ double inputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+ double inputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+
+ float outputs_S[tableLength] = {
+ 4.8, 4.8, -4.8, -0.29
+ };
+ double outputs_D[tableLength] = {
+ 5.3, -5.3, 5.3, -2.9
+ };
+
+ __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(TestFloat, c)) );
+ __ mov_s(f18, f6);
+ __ mov_d(f20, f2);
+ __ swc1(f18, MemOperand(a0, offsetof(TestFloat, d)) );
+ __ sdc1(f20, MemOperand(a0, offsetof(TestFloat, b)) );
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.c = inputs_S[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.b, outputs_D[i]);
+ CHECK_EQ(test.d, outputs_S[i]);
+ }
+}
+
+
+TEST(floor_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
-2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RN[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 0,
- 309485009821345068724781057.0,
- 2.0, 3.0, 2.0, 3.0, 4.0, 4.0,
- -2.0, -3.0, -2.0, -3.0, -4.0, -4.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RZ[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 0,
- 309485009821345068724781057.0,
- 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
- -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RP[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 1,
- 309485009821345068724781057.0,
- 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
- -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- double outputs_RM[tableLength] = {18446744073709551617.0,
- 4503599627370496.0, -4503599627370496.0,
- 1.26782468584154733584017312973E30, 1.44860108245951772690707170478E147,
- 1.7976931348623157E308, 0,
- 309485009821345068724781057.0,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
-3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
- 37778931862957161709568.0, 37778931862957161709569.0,
- 37778931862957161709580.0, 37778931862957161709581.0,
- 37778931862957161709582.0, 37778931862957161709583.0,
- 37778931862957161709584.0, 37778931862957161709585.0,
- 37778931862957161709586.0, 37778931862957161709587.0};
- int fcsr_inputs[4] =
- {kRoundToNearest, kRoundToZero, kRoundToPlusInf, kRoundToMinusInf};
- double* outputs[4] = {outputs_RN, outputs_RZ, outputs_RP, outputs_RM};
- __ ldc1(f4, MemOperand(a0, OFFSET_OF(TestFloat, a)) );
- __ lw(t0, MemOperand(a0, OFFSET_OF(TestFloat, fcsr)) );
- __ cfc1(t1, FCSR);
- __ ctc1(t0, FCSR);
- __ rint_d(f8, f4);
- __ sdc1(f8, MemOperand(a0, OFFSET_OF(TestFloat, b)) );
- __ ctc1(t1, FCSR);
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_w_d(f8, f4);
+ __ floor_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
+
+
+TEST(floor_l) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 2.0, 2.0, 2.0, 3.0, 3.0, 3.0,
+ -3.0, -3.0, -3.0, -4.0, -4.0, -4.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ floor_l_d(f8, f4);
+ __ floor_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
__ jr(ra);
__ nop();
-
+ Test test;
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
- for (int j = 0;j < 4;j++) {
- test.fcsr = fcsr_inputs[j];
- for (int i = 0;i < tableLength;i++) {
- test.a = inputs[i];
- (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
- CHECK_EQ(test.b, outputs[j][i]);
- }
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
}
+}
+
+
+TEST(ceil_w) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ float b;
+ int32_t c; // a floor result
+ int32_t d; // b floor result
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ kFPUInvalidResult, kFPUInvalidResult,
+ kFPUInvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_w_d(f8, f4);
+ __ ceil_w_s(f10, f6);
+ __ swc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ swc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
}
}
+TEST(ceil_l) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+ const double dFPU64InvalidResult = static_cast<double>(kFPU64InvalidResult);
+ typedef struct test_float {
+ double a;
+ float b;
+ int64_t c;
+ int64_t d;
+ }Test;
+ const int tableLength = 15;
+ double inputs_D[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()
+ };
+ float inputs_S[tableLength] = {
+ 2.1, 2.6, 2.5, 3.1, 3.6, 3.5,
+ -2.1, -2.6, -2.5, -3.1, -3.6, -3.5,
+ 2147483648.0,
+ std::numeric_limits<float>::quiet_NaN(),
+ std::numeric_limits<float>::infinity()
+ };
+ double outputs[tableLength] = {
+ 3.0, 3.0, 3.0, 4.0, 4.0, 4.0,
+ -2.0, -2.0, -2.0, -3.0, -3.0, -3.0,
+ 2147483648.0, dFPU64InvalidResult,
+ dFPU64InvalidResult};
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, a)) );
+ __ lwc1(f6, MemOperand(a0, offsetof(Test, b)) );
+ __ ceil_l_d(f8, f4);
+ __ ceil_l_s(f10, f6);
+ __ sdc1(f8, MemOperand(a0, offsetof(Test, c)) );
+ __ sdc1(f10, MemOperand(a0, offsetof(Test, d)) );
+ __ jr(ra);
+ __ nop();
+ Test test;
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ for (int i = 0; i < tableLength; i++) {
+ test.a = inputs_D[i];
+ test.b = inputs_S[i];
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, outputs[i]);
+ CHECK_EQ(test.d, test.c);
+ }
+}
TEST(jump_tables1) {
@@ -1930,8 +3123,9 @@ TEST(jump_tables1) {
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
for (int i = 0; i < kNumCases; ++i) {
- int res = reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
- ::printf("f(%d) = %d\n", i, res);
+ int64_t res = reinterpret_cast<int64_t>(
+ CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %" PRId64 "\n", i, res);
CHECK_EQ(values[i], static_cast<int>(res));
}
}
@@ -2002,8 +3196,9 @@ TEST(jump_tables2) {
#endif
F1 f = FUNCTION_CAST<F1>(code->entry());
for (int i = 0; i < kNumCases; ++i) {
- int res = reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
- ::printf("f(%d) = %d\n", i, res);
+ int64_t res = reinterpret_cast<int64_t>(
+ CALL_GENERATED_CODE(f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %" PRId64 "\n", i, res);
CHECK_EQ(values[i], res);
}
}
@@ -2095,4 +3290,2080 @@ TEST(jump_tables3) {
}
+TEST(BITSWAP) {
+ // Test BITSWAP
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ int64_t r1;
+ int64_t r2;
+ int64_t r3;
+ int64_t r4;
+ int64_t r5;
+ int64_t r6;
+ } T;
+ T t;
+
+ Assembler assm(isolate, NULL, 0);
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r1)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r1)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r2)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r2)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r3)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r3)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r4)));
+ __ nop();
+ __ bitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r4)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r5)));
+ __ nop();
+ __ dbitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r5)));
+
+ __ ld(a4, MemOperand(a0, offsetof(T, r6)));
+ __ nop();
+ __ dbitswap(a6, a4);
+ __ sd(a6, MemOperand(a0, offsetof(T, r6)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ t.r1 = 0x00102100781A15C3;
+ t.r2 = 0x001021008B71FCDE;
+ t.r3 = 0xFF8017FF781A15C3;
+ t.r4 = 0xFF8017FF8B71FCDE;
+ t.r5 = 0x10C021098B71FCDE;
+ t.r6 = 0xFB8017FF781A15C3;
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(static_cast<int64_t>(0x000000001E58A8C3L), t.r1);
+ CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFD18E3F7BL), t.r2);
+ CHECK_EQ(static_cast<int64_t>(0x000000001E58A8C3L), t.r3);
+ CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFD18E3F7BL), t.r4);
+ CHECK_EQ(static_cast<int64_t>(0x08038490D18E3F7BL), t.r5);
+ CHECK_EQ(static_cast<int64_t>(0xDF01E8FF1E58A8C3L), t.r6);
+ }
+}
+
+
+TEST(class_fmt) {
+ if (kArchVariant == kMips64r6) {
+ // Test CLASS.fmt instruction.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ double dSignalingNan;
+ double dQuietNan;
+ double dNegInf;
+ double dNegNorm;
+ double dNegSubnorm;
+ double dNegZero;
+ double dPosInf;
+ double dPosNorm;
+ double dPosSubnorm;
+ double dPosZero;
+ float fSignalingNan;
+ float fQuietNan;
+ float fNegInf;
+ float fNegNorm;
+ float fNegSubnorm;
+ float fNegZero;
+ float fPosInf;
+ float fPosNorm;
+ float fPosSubnorm;
+ float fPosZero; } T;
+ T t;
+
+ // Create a function that accepts &t, and loads, manipulates, and stores
+ // the doubles t.a ... t.f.
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dSignalingNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dSignalingNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dQuietNan)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dQuietNan)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dNegZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dNegZero)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosInf)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosInf)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosNorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosNorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosSubnorm)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosSubnorm)));
+
+ __ ldc1(f4, MemOperand(a0, offsetof(T, dPosZero)));
+ __ class_d(f6, f4);
+ __ sdc1(f6, MemOperand(a0, offsetof(T, dPosZero)));
+
+ // Testing instruction CLASS.S
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fSignalingNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fSignalingNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fQuietNan)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fQuietNan)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fNegZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fNegZero)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosInf)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosInf)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosNorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosNorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosSubnorm)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosSubnorm)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(T, fPosZero)));
+ __ class_s(f6, f4);
+ __ swc1(f6, MemOperand(a0, offsetof(T, fPosZero)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ // Double test values.
+ t.dSignalingNan = std::numeric_limits<double>::signaling_NaN();
+ t.dQuietNan = std::numeric_limits<double>::quiet_NaN();
+ t.dNegInf = -1.0 / 0.0;
+ t.dNegNorm = -5.0;
+ t.dNegSubnorm = -DBL_MIN / 2.0;
+ t.dNegZero = -0.0;
+ t.dPosInf = 2.0 / 0.0;
+ t.dPosNorm = 275.35;
+ t.dPosSubnorm = DBL_MIN / 2.0;
+ t.dPosZero = +0.0;
+ // Float test values
+
+ t.fSignalingNan = std::numeric_limits<float>::signaling_NaN();
+ t.fQuietNan = std::numeric_limits<float>::quiet_NaN();
+ t.fNegInf = -0.5/0.0;
+ t.fNegNorm = -FLT_MIN;
+ t.fNegSubnorm = -FLT_MIN / 1.5;
+ t.fNegZero = -0.0;
+ t.fPosInf = 100000.0 / 0.0;
+ t.fPosNorm = FLT_MAX;
+ t.fPosSubnorm = FLT_MIN / 20.0;
+ t.fPosZero = +0.0;
+
+ Object* dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);
+ USE(dummy);
+ // Expected double results.
+ CHECK_EQ(bit_cast<int64_t>(t.dNegInf), 0x004);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int64_t>(t.dNegZero), 0x020);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosInf), 0x040);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int64_t>(t.dPosZero), 0x200);
+
+ // Expected float results.
+ CHECK_EQ(bit_cast<int32_t>(t.fNegInf), 0x004);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegNorm), 0x008);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegSubnorm), 0x010);
+ CHECK_EQ(bit_cast<int32_t>(t.fNegZero), 0x020);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosInf), 0x040);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosNorm), 0x080);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosSubnorm), 0x100);
+ CHECK_EQ(bit_cast<int32_t>(t.fPosZero), 0x200);
+ }
+}
+
+
+TEST(ABS) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ int64_t fir;
+ double a;
+ float b;
+ double fcsr;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FIR.
+ __ cfc1(a1, FCSR);
+ __ sd(a1, MemOperand(a0, offsetof(TestFloat, fcsr)));
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ abs_d(f10, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, a)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, b)));
+ __ abs_s(f10, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, b)));
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ test.a = -2.0;
+ test.b = -2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ test.a = 2.0;
+ test.b = 2.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, 2.0);
+ CHECK_EQ(test.b, 2.0);
+
+ // Testing biggest positive number
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest negative number
+ test.a = -std::numeric_limits<double>::max(); // lowest()
+ test.b = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max());
+
+ // Testing smallest positive number
+ test.a = -std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::min());
+
+ // Testing infinity
+ test.a = -std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min();
+ test.b = -std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.a, std::numeric_limits<double>::max()
+ / std::numeric_limits<double>::min());
+ CHECK_EQ(test.b, std::numeric_limits<float>::max()
+ / std::numeric_limits<float>::min());
+
+ test.a = std::numeric_limits<double>::quiet_NaN();
+ test.b = std::numeric_limits<float>::quiet_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+
+ test.a = std::numeric_limits<double>::signaling_NaN();
+ test.b = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.a), true);
+ CHECK_EQ(std::isnan(test.b), true);
+}
+
+
+TEST(ADD_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double a;
+ double b;
+ double c;
+ float fa;
+ float fb;
+ float fc;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
+ __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
+ __ add_d(f10, f8, f4);
+ __ sdc1(f10, MemOperand(a0, offsetof(TestFloat, c)));
+
+ __ lwc1(f4, MemOperand(a0, offsetof(TestFloat, fa)));
+ __ lwc1(f8, MemOperand(a0, offsetof(TestFloat, fb)));
+ __ add_s(f10, f8, f4);
+ __ swc1(f10, MemOperand(a0, offsetof(TestFloat, fc)));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ test.a = 2.0;
+ test.b = 3.0;
+ test.fa = 2.0;
+ test.fb = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 5.0);
+ CHECK_EQ(test.fc, 5.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = -std::numeric_limits<double>::max(); // lowest()
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.c, 0.0);
+ CHECK_EQ(test.fc, 0.0);
+
+ test.a = std::numeric_limits<double>::max();
+ test.b = std::numeric_limits<double>::max();
+ test.fa = std::numeric_limits<float>::max();
+ test.fb = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isfinite(test.c), false);
+ CHECK_EQ(std::isfinite(test.fc), false);
+
+ test.a = 5.0;
+ test.b = std::numeric_limits<double>::signaling_NaN();
+ test.fa = 5.0;
+ test.fb = std::numeric_limits<float>::signaling_NaN();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(std::isnan(test.c), true);
+ CHECK_EQ(std::isnan(test.fc), true);
+}
+
+
+TEST(C_COND_FMT) {
+ if (kArchVariant == kMips64r2) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ uint32_t dF;
+ uint32_t dUn;
+ uint32_t dEq;
+ uint32_t dUeq;
+ uint32_t dOlt;
+ uint32_t dUlt;
+ uint32_t dOle;
+ uint32_t dUle;
+ float fOp1;
+ float fOp2;
+ uint32_t fF;
+ uint32_t fUn;
+ uint32_t fEq;
+ uint32_t fUeq;
+ uint32_t fOlt;
+ uint32_t fUlt;
+ uint32_t fOle;
+ uint32_t fUle;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(F, f4, f6, 0);
+ __ c_s(F, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UN, f4, f6, 2);
+ __ c_s(UN, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(EQ, f4, f6, 4);
+ __ c_s(EQ, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(UEQ, f4, f6, 6);
+ __ c_s(UEQ, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLT, f4, f6, 0);
+ __ c_s(OLT, f14, f16, 2);
+ __ movt(t2, t1, 0);
+ __ movt(t3, t1, 2);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULT, f4, f6, 2);
+ __ c_s(ULT, f14, f16, 4);
+ __ movt(t2, t1, 2);
+ __ movt(t3, t1, 4);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(OLE, f4, f6, 4);
+ __ c_s(OLE, f14, f16, 6);
+ __ movt(t2, t1, 4);
+ __ movt(t3, t1, 6);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ mov(t2, zero_reg);
+ __ mov(t3, zero_reg);
+ __ c_d(ULE, f4, f6, 6);
+ __ c_s(ULE, f14, f16, 0);
+ __ movt(t2, t1, 6);
+ __ movt(t3, t1, 0);
+ __ sw(t2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ sw(t3, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 1U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 1U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 0U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 0U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 0U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 0U);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 0U);
+ CHECK_EQ(test.dEq, 1U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 0U);
+ CHECK_EQ(test.dOle, 1U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 0U);
+ CHECK_EQ(test.fEq, 1U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 0U);
+ CHECK_EQ(test.fOle, 1U);
+ CHECK_EQ(test.fUle, 1U);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dF, 0U);
+ CHECK_EQ(test.dUn, 1U);
+ CHECK_EQ(test.dEq, 0U);
+ CHECK_EQ(test.dUeq, 1U);
+ CHECK_EQ(test.dOlt, 0U);
+ CHECK_EQ(test.dUlt, 1U);
+ CHECK_EQ(test.dOle, 0U);
+ CHECK_EQ(test.dUle, 1U);
+ CHECK_EQ(test.fF, 0U);
+ CHECK_EQ(test.fUn, 1U);
+ CHECK_EQ(test.fEq, 0U);
+ CHECK_EQ(test.fUeq, 1U);
+ CHECK_EQ(test.fOlt, 0U);
+ CHECK_EQ(test.fUlt, 1U);
+ CHECK_EQ(test.fOle, 0U);
+ CHECK_EQ(test.fUle, 1U);
+ }
+}
+
+
+TEST(CMP_COND_FMT) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ double dOp1;
+ double dOp2;
+ double dF;
+ double dUn;
+ double dEq;
+ double dUeq;
+ double dOlt;
+ double dUlt;
+ double dOle;
+ double dUle;
+ double dOr;
+ double dUne;
+ double dNe;
+ float fOp1;
+ float fOp2;
+ float fF;
+ float fUn;
+ float fEq;
+ float fUeq;
+ float fOlt;
+ float fUlt;
+ float fOle;
+ float fUle;
+ float fOr;
+ float fUne;
+ float fNe;
+ } TestFloat;
+
+ TestFloat test;
+
+ __ li(t1, 1);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, dOp1)));
+ __ ldc1(f6, MemOperand(a0, offsetof(TestFloat, dOp2)));
+
+ __ lwc1(f14, MemOperand(a0, offsetof(TestFloat, fOp1)));
+ __ lwc1(f16, MemOperand(a0, offsetof(TestFloat, fOp2)));
+
+ __ cmp_d(F, f2, f4, f6);
+ __ cmp_s(F, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dF)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fF)) );
+
+ __ cmp_d(UN, f2, f4, f6);
+ __ cmp_s(UN, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUn)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUn)) );
+
+ __ cmp_d(EQ, f2, f4, f6);
+ __ cmp_s(EQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dEq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fEq)) );
+
+ __ cmp_d(UEQ, f2, f4, f6);
+ __ cmp_s(UEQ, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUeq)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUeq)) );
+
+ __ cmp_d(LT, f2, f4, f6);
+ __ cmp_s(LT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOlt)) );
+
+ __ cmp_d(ULT, f2, f4, f6);
+ __ cmp_s(ULT, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUlt)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUlt)) );
+
+ __ cmp_d(LE, f2, f4, f6);
+ __ cmp_s(LE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOle)) );
+
+ __ cmp_d(ULE, f2, f4, f6);
+ __ cmp_s(ULE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUle)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUle)) );
+
+ __ cmp_d(ORD, f2, f4, f6);
+ __ cmp_s(ORD, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dOr)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fOr)) );
+
+ __ cmp_d(UNE, f2, f4, f6);
+ __ cmp_s(UNE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dUne)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fUne)) );
+
+ __ cmp_d(NE, f2, f4, f6);
+ __ cmp_s(NE, f12, f14, f16);
+ __ sdc1(f2, MemOperand(a0, offsetof(TestFloat, dNe)) );
+ __ swc1(f12, MemOperand(a0, offsetof(TestFloat, fNe)) );
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+ uint64_t dTrue = 0xFFFFFFFFFFFFFFFF;
+ uint64_t dFalse = 0x0000000000000000;
+ uint32_t fTrue = 0xFFFFFFFF;
+ uint32_t fFalse = 0x00000000;
+
+ test.dOp1 = 2.0;
+ test.dOp2 = 3.0;
+ test.fOp1 = 2.0;
+ test.fOp2 = 3.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::max();
+ test.dOp2 = std::numeric_limits<double>::min();
+ test.fOp1 = std::numeric_limits<float>::min();
+ test.fOp2 = -std::numeric_limits<float>::max(); // lowest()
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fFalse);
+
+ test.dOp1 = -std::numeric_limits<double>::max(); // lowest()
+ test.dOp2 = -std::numeric_limits<double>::max(); // lowest()
+ test.fOp1 = std::numeric_limits<float>::max();
+ test.fOp2 = std::numeric_limits<float>::max();
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = 0.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = 0.0;
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(bit_cast<uint64_t>(test.dF), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUn), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dEq), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUeq), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOlt), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUlt), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOle), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUle), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dOr), dFalse);
+ CHECK_EQ(bit_cast<uint64_t>(test.dUne), dTrue);
+ CHECK_EQ(bit_cast<uint64_t>(test.dNe), dFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fF), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUn), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fEq), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUeq), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOlt), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUlt), fTrue);
+ CHECK_EQ(bit_cast<uint32_t>(test.fOle), fFalse);
+ CHECK_EQ(bit_cast<uint32_t>(test.fUle), fTrue);
+ }
+}
+
+
+TEST(CVT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test_float {
+ float cvt_d_s_in;
+ double cvt_d_s_out;
+ int32_t cvt_d_w_in;
+ double cvt_d_w_out;
+ int64_t cvt_d_l_in;
+ double cvt_d_l_out;
+
+ float cvt_l_s_in;
+ int64_t cvt_l_s_out;
+ double cvt_l_d_in;
+ int64_t cvt_l_d_out;
+
+ double cvt_s_d_in;
+ float cvt_s_d_out;
+ int32_t cvt_s_w_in;
+ float cvt_s_w_out;
+ int64_t cvt_s_l_in;
+ float cvt_s_l_out;
+
+ float cvt_w_s_in;
+ int32_t cvt_w_s_out;
+ double cvt_w_d_in;
+ int32_t cvt_w_d_out;
+ } TestFloat;
+
+ TestFloat test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+#define GENERATE_CVT_TEST(x, y, z) \
+ __ y##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_in))); \
+ __ x(f0, f0); \
+ __ nop(); \
+ __ z##c1(f0, MemOperand(a0, offsetof(TestFloat, x##_out)));
+
+ GENERATE_CVT_TEST(cvt_d_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_d_w, lw, sd)
+ GENERATE_CVT_TEST(cvt_d_l, ld, sd)
+
+ GENERATE_CVT_TEST(cvt_l_s, lw, sd)
+ GENERATE_CVT_TEST(cvt_l_d, ld, sd)
+
+ GENERATE_CVT_TEST(cvt_s_d, ld, sw)
+ GENERATE_CVT_TEST(cvt_s_w, lw, sw)
+ GENERATE_CVT_TEST(cvt_s_l, ld, sw)
+
+ GENERATE_CVT_TEST(cvt_w_s, lw, sw)
+ GENERATE_CVT_TEST(cvt_w_d, ld, sw)
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ test.cvt_d_s_in = -0.51;
+ test.cvt_d_w_in = -1;
+ test.cvt_d_l_in = -1;
+ test.cvt_l_s_in = -0.51;
+ test.cvt_l_d_in = -0.51;
+ test.cvt_s_d_in = -0.51;
+ test.cvt_s_w_in = -1;
+ test.cvt_s_l_in = -1;
+ test.cvt_w_s_in = -0.51;
+ test.cvt_w_d_in = -0.51;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, -1);
+ CHECK_EQ(test.cvt_l_d_out, -1);
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, -1);
+ CHECK_EQ(test.cvt_w_d_out, -1);
+
+
+ test.cvt_d_s_in = 0.49;
+ test.cvt_d_w_in = 1;
+ test.cvt_d_l_in = 1;
+ test.cvt_l_s_in = 0.49;
+ test.cvt_l_d_in = 0.49;
+ test.cvt_s_d_in = 0.49;
+ test.cvt_s_w_in = 1;
+ test.cvt_s_l_in = 1;
+ test.cvt_w_s_in = 0.49;
+ test.cvt_w_d_in = 0.49;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+
+ test.cvt_d_s_in = std::numeric_limits<float>::max();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_l_s_in = std::numeric_limits<float>::max();
+ test.cvt_l_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_d_in = std::numeric_limits<double>::max();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::max();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::max();
+ test.cvt_w_s_in = std::numeric_limits<float>::max();
+ test.cvt_w_d_in = std::numeric_limits<double>::max();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_l_d_out, std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, std::numeric_limits<int32_t>::max());
+ CHECK_EQ(test.cvt_w_d_out, std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_l_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_l_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_d_in = -std::numeric_limits<double>::max(); // lowest()
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min(); // lowest()
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min(); // lowest()
+ test.cvt_w_s_in = -std::numeric_limits<float>::max(); // lowest()
+ test.cvt_w_d_in = -std::numeric_limits<double>::max(); // lowest()
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ // The returned value when converting from fixed-point to float-point
+ // is not consistent between board, simulator and specification
+ // in this test case, therefore modifying the test
+ CHECK(test.cvt_l_s_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_s_out == std::numeric_limits<int64_t>::max());
+ CHECK(test.cvt_l_d_out == std::numeric_limits<int64_t>::min() ||
+ test.cvt_l_d_out == std::numeric_limits<int64_t>::max());
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK(test.cvt_w_s_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_s_out == std::numeric_limits<int32_t>::max());
+ CHECK(test.cvt_w_d_out == std::numeric_limits<int32_t>::min() ||
+ test.cvt_w_d_out == std::numeric_limits<int32_t>::max());
+
+
+ test.cvt_d_s_in = std::numeric_limits<float>::min();
+ test.cvt_d_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_d_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_l_s_in = std::numeric_limits<float>::min();
+ test.cvt_l_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_d_in = std::numeric_limits<double>::min();
+ test.cvt_s_w_in = std::numeric_limits<int32_t>::min();
+ test.cvt_s_l_in = std::numeric_limits<int64_t>::min();
+ test.cvt_w_s_in = std::numeric_limits<float>::min();
+ test.cvt_w_d_in = std::numeric_limits<double>::min();
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.cvt_d_s_out, static_cast<double>(test.cvt_d_s_in));
+ CHECK_EQ(test.cvt_d_w_out, static_cast<double>(test.cvt_d_w_in));
+ CHECK_EQ(test.cvt_d_l_out, static_cast<double>(test.cvt_d_l_in));
+ CHECK_EQ(test.cvt_l_s_out, 0);
+ CHECK_EQ(test.cvt_l_d_out, 0);
+ CHECK_EQ(test.cvt_s_d_out, static_cast<float>(test.cvt_s_d_in));
+ CHECK_EQ(test.cvt_s_w_out, static_cast<float>(test.cvt_s_w_in));
+ CHECK_EQ(test.cvt_s_l_out, static_cast<float>(test.cvt_s_l_in));
+ CHECK_EQ(test.cvt_w_s_out, 0);
+ CHECK_EQ(test.cvt_w_d_out, 0);
+}
+
+
+TEST(DIV_FMT) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assm(isolate, NULL, 0);
+
+ typedef struct test {
+ double dOp1;
+ double dOp2;
+ double dRes;
+ float fOp1;
+ float fOp2;
+ float fRes;
+ } Test;
+
+ Test test;
+
+ // Save FCSR.
+ __ cfc1(a1, FCSR);
+ // Disable FPU exceptions.
+ __ ctc1(zero_reg, FCSR);
+
+ __ ldc1(f4, MemOperand(a0, offsetof(Test, dOp1)) );
+ __ ldc1(f2, MemOperand(a0, offsetof(Test, dOp2)) );
+ __ nop();
+ __ div_d(f6, f4, f2);
+ __ sdc1(f6, MemOperand(a0, offsetof(Test, dRes)) );
+
+ __ lwc1(f4, MemOperand(a0, offsetof(Test, fOp1)) );
+ __ lwc1(f2, MemOperand(a0, offsetof(Test, fOp2)) );
+ __ nop();
+ __ div_s(f6, f4, f2);
+ __ swc1(f6, MemOperand(a0, offsetof(Test, fRes)) );
+
+ // Restore FCSR.
+ __ ctc1(a1, FCSR);
+
+ __ jr(ra);
+ __ nop();
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+
+ const int test_size = 3;
+
+ double dOp1[test_size] = {
+ 5.0,
+ DBL_MAX,
+ DBL_MAX,
+ };
+ double dOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -DBL_MAX,
+ };
+ double dRes[test_size] = {
+ 2.5,
+ DBL_MAX / 2.0,
+ -1.0,
+ };
+ float fOp1[test_size] = {
+ 5.0,
+ FLT_MAX,
+ FLT_MAX,
+ };
+ float fOp2[test_size] = {
+ 2.0,
+ 2.0,
+ -FLT_MAX,
+ };
+ float fRes[test_size] = {
+ 2.5,
+ FLT_MAX / 2.0,
+ -1.0,
+ };
+
+ for (int i = 0; i < test_size; i++) {
+ test.dOp1 = dOp1[i];
+ test.dOp2 = dOp2[i];
+ test.fOp1 = fOp1[i];
+ test.fOp2 = fOp2[i];
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(test.dRes, dRes[i]);
+ CHECK_EQ(test.fRes, fRes[i]);
+ }
+
+ test.dOp1 = DBL_MAX;
+ test.dOp2 = -0.0;
+ test.fOp1 = FLT_MAX;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(false, std::isfinite(test.dRes));
+ CHECK_EQ(false, std::isfinite(test.fRes));
+
+ test.dOp1 = 0.0;
+ test.dOp2 = -0.0;
+ test.fOp1 = 0.0;
+ test.fOp2 = -0.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+
+ test.dOp1 = std::numeric_limits<double>::quiet_NaN();
+ test.dOp2 = -5.0;
+ test.fOp1 = std::numeric_limits<float>::quiet_NaN();
+ test.fOp2 = -5.0;
+
+ (CALL_GENERATED_CODE(f, &test, 0, 0, 0, 0));
+ CHECK_EQ(true, std::isnan(test.dRes));
+ CHECK_EQ(true, std::isnan(test.fRes));
+}
+
+
+uint64_t run_align(uint64_t rs_value, uint64_t rt_value, uint8_t bp) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ align(v0, a0, a1, bp);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs_value,
+ rt_value,
+ 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_align) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAlign {
+ uint64_t rs_value;
+ uint64_t rt_value;
+ uint8_t bp;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseAlign tc[] = {
+ // rs_value, rt_value, bp, expected_res
+ { 0x11223344, 0xaabbccdd, 0, 0xffffffffaabbccdd },
+ { 0x11223344, 0xaabbccdd, 1, 0xffffffffbbccdd11 },
+ { 0x11223344, 0xaabbccdd, 2, 0xffffffffccdd1122 },
+ { 0x11223344, 0xaabbccdd, 3, 0xffffffffdd112233 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAlign);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_align(tc[i].rs_value,
+ tc[i].rt_value,
+ tc[i].bp));
+ }
+ }
+}
+
+
+uint64_t run_dalign(uint64_t rs_value, uint64_t rt_value, uint8_t bp) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ dalign(v0, a0, a1, bp);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F4 f = FUNCTION_CAST<F4>(code->entry());
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, rs_value,
+ rt_value,
+ 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_dalign) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseDalign {
+ uint64_t rs_value;
+ uint64_t rt_value;
+ uint8_t bp;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseDalign tc[] = {
+ // rs_value, rt_value, bp, expected_res
+ { 0x1122334455667700, 0xaabbccddeeff8899, 0, 0xaabbccddeeff8899 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 1, 0xbbccddeeff889911 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 2, 0xccddeeff88991122 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 3, 0xddeeff8899112233 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 4, 0xeeff889911223344 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 5, 0xff88991122334455 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 6, 0x8899112233445566 },
+ { 0x1122334455667700, 0xaabbccddeeff8899, 7, 0x9911223344556677 }
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDalign);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_dalign(tc[i].rs_value,
+ tc[i].rt_value,
+ tc[i].bp));
+ }
+ }
+}
+
+
+uint64_t PC; // The program counter.
+
+uint64_t run_aluipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ aluipc(v0, offset);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ PC = (uint64_t) f; // Set the program counter.
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_aluipc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAluipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAluipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAluipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint64_t res = run_aluipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint64_t expected_res = ~0x0FFFF & (PC + (tc[i].offset << 16));
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_auipc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ auipc(v0, offset);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ PC = (uint64_t) f; // Set the program counter.
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_auipc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAuipc {
+ int16_t offset;
+ };
+
+ struct TestCaseAuipc tc[] = {
+ // offset
+ { -32768 }, // 0x8000
+ { -1 }, // 0xFFFF
+ { 0 },
+ { 1 },
+ { 32767 }, // 0x7FFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAuipc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint64_t res = run_auipc(tc[i].offset);
+ // Now, the program_counter (PC) is set.
+ uint64_t expected_res = PC + (tc[i].offset << 16);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_lwpc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2^8k
+ // addiu t3, a4, 0xffff; (0x250fffff)
+ // ...
+ // addiu t0, a4, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ lwpc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2^8k
+ // addiu a4, a4, 0x0000; (0x25080000)
+ // ...
+ // addiu a7, a4, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_lwpc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLwpc {
+ int offset;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLwpc tc[] = {
+ // offset, expected_res
+ { -262144, 0x250fffff }, // offset 0x40000
+ { -4, 0x250c0003 },
+ { -1, 0x250c0000 },
+ { 0, 0xffffffffef080000 },
+ { 1, 0x03001025 }, // mov(v0, t8)
+ { 2, 0x25080000 },
+ { 4, 0x25080002 },
+ { 262143, 0x250bfffd }, // offset 0x3ffff
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwpc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_lwpc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_lwupc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2^8k
+ // addiu t3, a4, 0xffff; (0x250fffff)
+ // ...
+ // addiu t0, a4, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ lwupc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2^8k
+ // addiu a4, a4, 0x0000; (0x25080000)
+ // ...
+ // addiu a7, a4, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_lwupc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLwupc {
+ int offset;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLwupc tc[] = {
+ // offset, expected_res
+ { -262144, 0x250fffff }, // offset 0x40000
+ { -4, 0x250c0003 },
+ { -1, 0x250c0000 },
+ { 0, 0xef100000 },
+ { 1, 0x03001025 }, // mov(v0, t8)
+ { 2, 0x25080000 },
+ { 4, 0x25080002 },
+ { 262143, 0x250bfffd }, // offset 0x3ffff
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLwupc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_lwupc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_jic(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label get_program_counter, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -32
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jic(t0, offset);
+
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 16
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jic) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJic {
+ // As rt will be used t0 register which will have value of
+ // the program counter for the jic instruction.
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJic tc[] = {
+ // offset, expected_result
+ { 16, 0x2033 },
+ { 4, 0x3333 },
+ { -32, 0x66 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJic);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_jic(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_beqzc(int32_t value, int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label stop_execution;
+ __ li(v0, 0);
+ __ li(t1, 0x66);
+
+ __ addiu(v0, v0, 0x1); // <-- offset = -8
+ __ addiu(v0, v0, 0x2);
+ __ addiu(v0, v0, 0x10);
+ __ addiu(v0, v0, 0x20);
+ __ beq(v0, t1, &stop_execution);
+ __ nop();
+
+ __ beqzc(a0, offset);
+
+ __ addiu(v0, v0, 0x1);
+ __ addiu(v0, v0, 0x100);
+ __ addiu(v0, v0, 0x200);
+ __ addiu(v0, v0, 0x1000);
+ __ addiu(v0, v0, 0x2000); // <--- offset = 4
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&stop_execution);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, value, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_beqzc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBeqzc {
+ uint32_t value;
+ int32_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseBeqzc tc[] = {
+ // value, offset, expected_res
+ { 0x0, -8, 0x66 },
+ { 0x0, 0, 0x3334 },
+ { 0x0, 1, 0x3333 },
+ { 0xabc, 1, 0x3334 },
+ { 0x0, 4, 0x2033 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBeqzc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_beqzc(tc[i].value, tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_jialc(int16_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label main_block, get_program_counter;
+ __ push(ra);
+ __ li(v0, 0);
+ __ beq(v0, v0, &main_block);
+ __ nop();
+
+ // Block 1
+ __ addiu(v0, v0, 0x1); // <-- offset = -40
+ __ addiu(v0, v0, 0x2);
+ __ jr(ra);
+ __ nop();
+
+ // Block 2
+ __ addiu(v0, v0, 0x10); // <-- offset = -24
+ __ addiu(v0, v0, 0x20);
+ __ jr(ra);
+ __ nop();
+
+ // Block 3 (Main)
+ __ bind(&main_block);
+ __ bal(&get_program_counter); // t0 <- program counter
+ __ nop();
+ __ jialc(t0, offset);
+ __ addiu(v0, v0, 0x4);
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ // Block 4
+ __ addiu(v0, v0, 0x100); // <-- offset = 20
+ __ addiu(v0, v0, 0x200);
+ __ jr(ra);
+ __ nop();
+
+ // Block 5
+ __ addiu(v0, v0, 0x1000); // <--- offset = 36
+ __ addiu(v0, v0, 0x2000);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&get_program_counter);
+ __ mov(t0, ra);
+ __ jr(ra);
+ __ nop();
+
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_jialc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseJialc {
+ // As rt will be used t0 register which will have value of
+ // the program counter for the jialc instruction.
+ int16_t offset;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseJialc tc[] = {
+ // offset, expected_res
+ { -40, 0x7 },
+ { -24, 0x34 },
+ { 20, 0x304 },
+ { 36, 0x3004 }
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseJialc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_jialc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_addiupc(int32_t imm19) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ __ addiupc(v0, imm19);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+ PC = (uint64_t) f; // Set the program counter.
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_addiupc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseAddiupc {
+ int32_t imm19;
+ };
+
+ struct TestCaseAddiupc tc[] = {
+ // imm19
+ { -262144 }, // 0x40000
+ { -1 }, // 0x7FFFF
+ { 0 },
+ { 1 }, // 0x00001
+ { 262143 } // 0x3FFFF
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseAddiupc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ PC = 0;
+ uint64_t res = run_addiupc(tc[i].imm19);
+ // Now, the program_counter (PC) is set.
+ uint64_t expected_res = PC + (tc[i].imm19 << 2);
+ CHECK_EQ(expected_res, res);
+ }
+ }
+}
+
+
+uint64_t run_ldpc(int offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ // 256k instructions; 2 * 2^7k = 2^8k
+ // addiu t3, a4, 0xffff; (0x250fffff)
+ // ...
+ // addiu t0, a4, 0x0000; (0x250c0000)
+ uint32_t addiu_start_1 = 0x25000000;
+ for (int32_t i = 0xfffff; i >= 0xc0000; --i) {
+ uint32_t addiu_new = addiu_start_1 + i;
+ __ dd(addiu_new);
+ }
+
+ __ ldpc(t8, offset); // offset 0; 0xef080000 (t8 register)
+ __ mov(v0, t8);
+
+ // 256k instructions; 2 * 2^7k = 2^8k
+ // addiu a4, a4, 0x0000; (0x25080000)
+ // ...
+ // addiu a7, a4, 0xffff; (0x250bffff)
+ uint32_t addiu_start_2 = 0x25000000;
+ for (int32_t i = 0x80000; i <= 0xbffff; ++i) {
+ uint32_t addiu_new = addiu_start_2 + i;
+ __ dd(addiu_new);
+ }
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res =
+ reinterpret_cast<uint64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_ldpc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseLdpc {
+ int offset;
+ uint64_t expected_res;
+ };
+
+ struct TestCaseLdpc tc[] = {
+ // offset, expected_res
+ { -131072, 0x250ffffe250fffff },
+ { -4, 0x250c0006250c0007 },
+ { -1, 0x250c0000250c0001 },
+ { 0, 0x03001025ef180000 },
+ { 1, 0x2508000125080000 },
+ { 4, 0x2508000725080006 },
+ { 131071, 0x250bfffd250bfffc },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLdpc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint64_t res = run_ldpc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+int64_t run_bc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // Condition for the stopping execution.
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -100; i <= -11; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ addiu(t8, t8, 1); // -10
+
+ __ beq(t8, t9, &stop_execution); // -9
+ __ nop(); // -8
+ __ beq(t8, t8, &continue_1); // -7
+ __ nop(); // -6
+
+ __ bind(&stop_execution);
+ __ pop(ra); // -5, -4
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ bc(offset); // -1
+
+ for (int32_t i = 0; i <= 99; ++i) {
+ __ dd(instruction_addiu);
+ }
+
+ __ pop(ra);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ int64_t res =
+ reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_bc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBc {
+ int32_t offset;
+ int64_t expected_res;
+ };
+
+ struct TestCaseBc tc[] = {
+ // offset, expected_result
+ { -100, (abs(-100) - 10) * 2 },
+ { -11, (abs(-100) - 10 + 1) },
+ { 0, (abs(-100) - 10 + 1 + 99) },
+ { 1, (abs(-100) - 10 + 99) },
+ { 99, (abs(-100) - 10 + 1) },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int64_t res = run_bc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
+int64_t run_balc(int32_t offset) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0);
+
+ Label continue_1, stop_execution;
+ __ push(ra);
+ __ li(v0, 0);
+ __ li(t8, 0);
+ __ li(t9, 2); // Condition for stopping execution.
+
+ __ beq(t8, t8, &continue_1);
+ __ nop();
+
+ uint32_t instruction_addiu = 0x24420001; // addiu v0, v0, 1
+ for (int32_t i = -117; i <= -57; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -56
+ __ nop(); // -55
+
+ for (int32_t i = -54; i <= -4; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra); // -3
+ __ nop(); // -2
+
+ __ bind(&continue_1);
+ __ balc(offset); // -1
+
+ __ pop(ra); // 0, 1
+ __ jr(ra); // 2
+ __ nop(); // 3
+
+ for (int32_t i = 4; i <= 44; ++i) {
+ __ dd(instruction_addiu);
+ }
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ int64_t res =
+ reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(r6_balc) {
+ if (kArchVariant == kMips64r6) {
+ CcTest::InitializeVM();
+
+ struct TestCaseBalc {
+ int32_t offset;
+ int64_t expected_res;
+ };
+
+ struct TestCaseBalc tc[] = {
+ // offset, expected_result
+ { -117, 61 },
+ { -54, 51 },
+ { 0, 0 },
+ { 4, 41 },
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseBalc);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ int64_t res = run_balc(tc[i].offset);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+ }
+}
+
+
#undef __
diff --git a/deps/v8/test/cctest/test-assembler-ppc.cc b/deps/v8/test/cctest/test-assembler-ppc.cc
index 4a2e7d3983..b2dca6a9fc 100644
--- a/deps/v8/test/cctest/test-assembler-ppc.cc
+++ b/deps/v8/test/cctest/test-assembler-ppc.cc
@@ -194,21 +194,21 @@ TEST(3) {
__ mr(r4, r3);
// modify field int i of struct
- __ lwz(r3, MemOperand(r4, OFFSET_OF(T, i)));
+ __ lwz(r3, MemOperand(r4, offsetof(T, i)));
__ srwi(r5, r3, Operand(1));
- __ stw(r5, MemOperand(r4, OFFSET_OF(T, i)));
+ __ stw(r5, MemOperand(r4, offsetof(T, i)));
// modify field char c of struct
- __ lbz(r5, MemOperand(r4, OFFSET_OF(T, c)));
+ __ lbz(r5, MemOperand(r4, offsetof(T, c)));
__ add(r3, r5, r3);
__ slwi(r5, r5, Operand(2));
- __ stb(r5, MemOperand(r4, OFFSET_OF(T, c)));
+ __ stb(r5, MemOperand(r4, offsetof(T, c)));
// modify field int16_t s of struct
- __ lhz(r5, MemOperand(r4, OFFSET_OF(T, s)));
+ __ lhz(r5, MemOperand(r4, offsetof(T, s)));
__ add(r3, r5, r3);
__ srwi(r5, r5, Operand(3));
- __ sth(r5, MemOperand(r4, OFFSET_OF(T, s)));
+ __ sth(r5, MemOperand(r4, offsetof(T, s)));
// restore frame
#if V8_TARGET_ARCH_PPC64
@@ -278,59 +278,59 @@ TEST(4) {
__ sub(fp, ip, Operand(4));
__ mov(r4, Operand(r0));
- __ vldr(d6, r4, OFFSET_OF(T, a));
- __ vldr(d7, r4, OFFSET_OF(T, b));
+ __ vldr(d6, r4, offsetof(T, a));
+ __ vldr(d7, r4, offsetof(T, b));
__ vadd(d5, d6, d7);
- __ vstr(d5, r4, OFFSET_OF(T, c));
+ __ vstr(d5, r4, offsetof(T, c));
__ vmov(r2, r3, d5);
__ vmov(d4, r2, r3);
- __ vstr(d4, r4, OFFSET_OF(T, b));
+ __ vstr(d4, r4, offsetof(T, b));
// Load t.x and t.y, switch values, and store back to the struct.
- __ vldr(s0, r4, OFFSET_OF(T, x));
- __ vldr(s31, r4, OFFSET_OF(T, y));
+ __ vldr(s0, r4, offsetof(T, x));
+ __ vldr(s31, r4, offsetof(T, y));
__ vmov(s16, s0);
__ vmov(s0, s31);
__ vmov(s31, s16);
- __ vstr(s0, r4, OFFSET_OF(T, x));
- __ vstr(s31, r4, OFFSET_OF(T, y));
+ __ vstr(s0, r4, offsetof(T, x));
+ __ vstr(s31, r4, offsetof(T, y));
// Move a literal into a register that can be encoded in the instruction.
__ vmov(d4, 1.0);
- __ vstr(d4, r4, OFFSET_OF(T, e));
+ __ vstr(d4, r4, offsetof(T, e));
// Move a literal into a register that requires 64 bits to encode.
// 0x3ff0000010000000 = 1.000000059604644775390625
__ vmov(d4, 1.000000059604644775390625);
- __ vstr(d4, r4, OFFSET_OF(T, d));
+ __ vstr(d4, r4, offsetof(T, d));
// Convert from floating point to integer.
__ vmov(d4, 2.0);
__ vcvt_s32_f64(s31, d4);
- __ vstr(s31, r4, OFFSET_OF(T, i));
+ __ vstr(s31, r4, offsetof(T, i));
// Convert from integer to floating point.
__ mov(lr, Operand(42));
__ vmov(s31, lr);
__ vcvt_f64_s32(d4, s31);
- __ vstr(d4, r4, OFFSET_OF(T, f));
+ __ vstr(d4, r4, offsetof(T, f));
// Test vabs.
- __ vldr(d1, r4, OFFSET_OF(T, g));
+ __ vldr(d1, r4, offsetof(T, g));
__ vabs(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, g));
- __ vldr(d2, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, g));
+ __ vldr(d2, r4, offsetof(T, h));
__ vabs(d0, d2);
- __ vstr(d0, r4, OFFSET_OF(T, h));
+ __ vstr(d0, r4, offsetof(T, h));
// Test vneg.
- __ vldr(d1, r4, OFFSET_OF(T, m));
+ __ vldr(d1, r4, offsetof(T, m));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, m));
- __ vldr(d1, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, m));
+ __ vldr(d1, r4, offsetof(T, n));
__ vneg(d0, d1);
- __ vstr(d0, r4, OFFSET_OF(T, n));
+ __ vstr(d0, r4, offsetof(T, n));
__ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
@@ -677,19 +677,19 @@ TEST(8) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vldm(ia_w, r4, d0, d3);
__ vldm(ia_w, r4, d4, d7);
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vstm(ia_w, r4, d6, d7);
__ vstm(ia_w, r4, d0, d5);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vldm(ia_w, r4, s0, s3);
__ vldm(ia_w, r4, s4, s7);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vstm(ia_w, r4, s6, s7);
__ vstm(ia_w, r4, s0, s5);
@@ -789,22 +789,22 @@ TEST(9) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vldm(ia, r4, d0, d3);
__ addi(r4, r4, Operand(4 * 8));
__ vldm(ia, r4, d4, d7);
- __ addi(r4, r0, Operand(OFFSET_OF(D, a)));
+ __ addi(r4, r0, Operand(offsetof(D, a)));
__ vstm(ia, r4, d6, d7);
__ addi(r4, r4, Operand(2 * 8));
__ vstm(ia, r4, d0, d5);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vldm(ia, r4, s0, s3);
__ addi(r4, r4, Operand(4 * 4));
__ vldm(ia, r4, s4, s7);
- __ addi(r4, r1, Operand(OFFSET_OF(F, a)));
+ __ addi(r4, r1, Operand(offsetof(F, a)));
__ vstm(ia, r4, s6, s7);
__ addi(r4, r4, Operand(2 * 4));
__ vstm(ia, r4, s0, s5);
@@ -905,19 +905,19 @@ TEST(10) {
__ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
__ sub(fp, ip, Operand(4));
- __ addi(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ addi(r4, r0, Operand(offsetof(D, h) + 8));
__ vldm(db_w, r4, d4, d7);
__ vldm(db_w, r4, d0, d3);
- __ addi(r4, r0, Operand(OFFSET_OF(D, h) + 8));
+ __ addi(r4, r0, Operand(offsetof(D, h) + 8));
__ vstm(db_w, r4, d0, d5);
__ vstm(db_w, r4, d6, d7);
- __ addi(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ addi(r4, r1, Operand(offsetof(F, h) + 4));
__ vldm(db_w, r4, s4, s7);
__ vldm(db_w, r4, s0, s3);
- __ addi(r4, r1, Operand(OFFSET_OF(F, h) + 4));
+ __ addi(r4, r1, Operand(offsetof(F, h) + 4));
__ vstm(db_w, r4, s0, s5);
__ vstm(db_w, r4, s6, s7);
@@ -996,28 +996,28 @@ TEST(11) {
Assembler assm(isolate, NULL, 0);
// Test HeapObject untagging.
- __ ldr(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ ldr(r1, MemOperand(r0, offsetof(I, a)));
__ mov(r1, Operand(r1, ASR, 1), SetCC);
__ adc(r1, r1, Operand(r1), LeaveCC, cs);
- __ str(r1, MemOperand(r0, OFFSET_OF(I, a)));
+ __ str(r1, MemOperand(r0, offsetof(I, a)));
- __ ldr(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ ldr(r2, MemOperand(r0, offsetof(I, b)));
__ mov(r2, Operand(r2, ASR, 1), SetCC);
__ adc(r2, r2, Operand(r2), LeaveCC, cs);
- __ str(r2, MemOperand(r0, OFFSET_OF(I, b)));
+ __ str(r2, MemOperand(r0, offsetof(I, b)));
// Test corner cases.
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r1, ASR, 1), SetCC); // Set the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, c)));
+ __ str(r3, MemOperand(r0, offsetof(I, c)));
__ mov(r1, Operand(0xffffffff));
__ mov(r2, Operand::Zero());
__ mov(r3, Operand(r2, ASR, 1), SetCC); // Unset the carry.
__ adc(r3, r1, Operand(r2));
- __ str(r3, MemOperand(r0, OFFSET_OF(I, d)));
+ __ str(r3, MemOperand(r0, offsetof(I, d)));
__ mov(pc, Operand(lr));
diff --git a/deps/v8/test/cctest/test-code-stubs-arm64.cc b/deps/v8/test/cctest/test-code-stubs-arm64.cc
index 6d5b0f49be..8b38b96600 100644
--- a/deps/v8/test/cctest/test-code-stubs-arm64.cc
+++ b/deps/v8/test/cctest/test-code-stubs-arm64.cc
@@ -142,8 +142,8 @@ int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
Simulator::CallArgument(from),
Simulator::CallArgument::End()
};
- return Simulator::current(Isolate::Current())->CallInt64(
- FUNCTION_ADDR(func), args);
+ return static_cast<int32_t>(Simulator::current(Isolate::Current())
+ ->CallInt64(FUNCTION_ADDR(func), args));
#else
return (*func)(from);
#endif
diff --git a/deps/v8/test/cctest/test-code-stubs-mips64.cc b/deps/v8/test/cctest/test-code-stubs-mips64.cc
index 1f7df380e1..9f146f65fd 100644
--- a/deps/v8/test/cctest/test-code-stubs-mips64.cc
+++ b/deps/v8/test/cctest/test-code-stubs-mips64.cc
@@ -144,7 +144,8 @@ int32_t RunGeneratedCodeCallWrapper(ConvertDToIFunc func,
double from) {
#ifdef USE_SIMULATOR
Simulator::current(Isolate::Current())->CallFP(FUNCTION_ADDR(func), from, 0.);
- return Simulator::current(Isolate::Current())->get_register(v0.code());
+ return static_cast<int32_t>(
+ Simulator::current(Isolate::Current())->get_register(v0.code()));
#else
return (*func)(from);
#endif
diff --git a/deps/v8/test/cctest/test-compiler.cc b/deps/v8/test/cctest/test-compiler.cc
index ed8b1c6d99..3b25480a4a 100644
--- a/deps/v8/test/cctest/test-compiler.cc
+++ b/deps/v8/test/cctest/test-compiler.cc
@@ -60,8 +60,8 @@ static Handle<JSFunction> Compile(const char* source) {
Handle<String> source_code = isolate->factory()->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());
@@ -362,7 +362,7 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) {
// Now a feedback vector is allocated.
CHECK(f->shared()->is_compiled());
int expected_slots = 0;
- int expected_ic_slots = FLAG_vector_ics ? 2 : 1;
+ int expected_ic_slots = 2;
CHECK_EQ(expected_slots, f->shared()->feedback_vector()->Slots());
CHECK_EQ(expected_ic_slots, f->shared()->feedback_vector()->ICSlots());
}
@@ -370,40 +370,92 @@ TEST(FeedbackVectorUnaffectedByScopeChanges) {
// Test that optimized code for different closures is actually shared
// immediately by the FastNewClosureStub when run in the same context.
-TEST(OptimizedCodeSharing) {
- // Skip test if --cache-optimized-code is not activated by default because
- // FastNewClosureStub that is baked into the snapshot is incorrect.
- if (!FLAG_cache_optimized_code) return;
+TEST(OptimizedCodeSharing1) {
FLAG_stress_compaction = false;
FLAG_allow_natives_syntax = true;
+ FLAG_cache_optimized_code = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
for (int i = 0; i < 10; i++) {
LocalContext env;
env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
v8::Integer::New(CcTest::isolate(), i));
- CompileRun("function MakeClosure() {"
- " return function() { return x; };"
- "}"
- "var closure0 = MakeClosure();"
- "%DebugPrint(closure0());"
- "%OptimizeFunctionOnNextCall(closure0);"
- "%DebugPrint(closure0());"
- "var closure1 = MakeClosure();"
- "var closure2 = MakeClosure();");
+ CompileRun(
+ "function MakeClosure() {"
+ " return function() { return x; };"
+ "}"
+ "var closure0 = MakeClosure();"
+ "%DebugPrint(closure0());"
+ "%OptimizeFunctionOnNextCall(closure0);"
+ "%DebugPrint(closure0());"
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
Handle<JSFunction> fun1 = v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1"))));
Handle<JSFunction> fun2 = v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2"))));
- CHECK(fun1->IsOptimized()
- || !CcTest::i_isolate()->use_crankshaft() || !fun1->IsOptimizable());
- CHECK(fun2->IsOptimized()
- || !CcTest::i_isolate()->use_crankshaft() || !fun2->IsOptimizable());
+ CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
CHECK_EQ(fun1->code(), fun2->code());
}
}
+// Test that optimized code for different closures is actually shared
+// immediately by the FastNewClosureStub when run different contexts.
+TEST(OptimizedCodeSharing2) {
+ if (FLAG_stress_compaction) return;
+ FLAG_allow_natives_syntax = true;
+ FLAG_cache_optimized_code = true;
+ FLAG_turbo_cache_shared_code = true;
+ const char* flag = "--turbo-filter=*";
+ FlagList::SetFlagsFromString(flag, StrLength(flag));
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Script> script = v8_compile(
+ "function MakeClosure() {"
+ " return function() { return x; };"
+ "}");
+ Handle<Code> reference_code;
+ {
+ LocalContext env;
+ env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
+ v8::Integer::New(CcTest::isolate(), 23));
+ script->GetUnboundScript()->BindToCurrentContext()->Run();
+ CompileRun(
+ "var closure0 = MakeClosure();"
+ "%DebugPrint(closure0());"
+ "%OptimizeFunctionOnNextCall(closure0);"
+ "%DebugPrint(closure0());");
+ Handle<JSFunction> fun0 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure0"))));
+ CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ reference_code = handle(fun0->code());
+ }
+ for (int i = 0; i < 10; i++) {
+ LocalContext env;
+ env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
+ v8::Integer::New(CcTest::isolate(), i));
+ script->GetUnboundScript()->BindToCurrentContext()->Run();
+ CompileRun(
+ "var closure0 = MakeClosure();"
+ "%DebugPrint(closure0());"
+ "%OptimizeFunctionOnNextCall(closure0);"
+ "%DebugPrint(closure0());"
+ "var closure1 = MakeClosure();"
+ "var closure2 = MakeClosure();");
+ Handle<JSFunction> fun1 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1"))));
+ Handle<JSFunction> fun2 = v8::Utils::OpenHandle(
+ *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2"))));
+ CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
+ CHECK_EQ(*reference_code, fun1->code());
+ CHECK_EQ(*reference_code, fun2->code());
+ }
+}
+
+
TEST(CompileFunctionInContext) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -533,6 +585,9 @@ static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) {
int decode_size =
Min(f->code()->instruction_size(),
static_cast<int>(f->code()->back_edge_table_offset()));
+ if (FLAG_enable_embedded_constant_pool) {
+ decode_size = Min(decode_size, f->code()->constant_pool_offset());
+ }
Address end = pc + decode_size;
v8::internal::EmbeddedVector<char, 128> decode_buffer;
diff --git a/deps/v8/test/cctest/test-constantpool.cc b/deps/v8/test/cctest/test-constantpool.cc
index 4592074742..ce3abb0edb 100644
--- a/deps/v8/test/cctest/test-constantpool.cc
+++ b/deps/v8/test/cctest/test-constantpool.cc
@@ -1,337 +1,247 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Test constant pool array code.
+// Copyright 2015 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.
+
+// Test embedded constant pool builder code.
#include "src/v8.h"
-#include "src/factory.h"
-#include "src/objects.h"
+#include "src/assembler.h"
#include "test/cctest/cctest.h"
using namespace v8::internal;
-static ConstantPoolArray::Type kTypes[] = { ConstantPoolArray::INT64,
- ConstantPoolArray::CODE_PTR,
- ConstantPoolArray::HEAP_PTR,
- ConstantPoolArray::INT32 };
-static ConstantPoolArray::LayoutSection kSmall =
- ConstantPoolArray::SMALL_SECTION;
-static ConstantPoolArray::LayoutSection kExtended =
- ConstantPoolArray::EXTENDED_SECTION;
-
-Code* DummyCode(LocalContext* context) {
- CompileRun("function foo() {};");
- i::Handle<i::JSFunction> fun = v8::Utils::OpenHandle(
- *v8::Local<v8::Function>::Cast(
- (*context)->Global()->Get(v8_str("foo"))));
- return fun->code();
-}
+const ConstantPoolEntry::Type kPtrType = ConstantPoolEntry::INTPTR;
+const ConstantPoolEntry::Type kDblType = ConstantPoolEntry::DOUBLE;
+const ConstantPoolEntry::Access kRegAccess = ConstantPoolEntry::REGULAR;
+const ConstantPoolEntry::Access kOvflAccess = ConstantPoolEntry::OVERFLOWED;
+const int kReachBits = 6; // Use reach of 64-bytes to test overflow.
+const int kReach = 1 << kReachBits;
-TEST(ConstantPoolSmall) {
- LocalContext context;
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(context->GetIsolate());
- // Check construction.
- ConstantPoolArray::NumberOfEntries small(3, 1, 2, 1);
- Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+TEST(ConstantPoolPointers) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = kReach / kPointerSize;
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ intptr_t value = 0;
+ bool sharing_ok = true;
- int expected_counts[] = { 3, 1, 2, 1 };
- int expected_first_idx[] = { 0, 3, 4, 6 };
- int expected_last_idx[] = { 2, 3, 5, 6 };
- for (int i = 0; i < 4; i++) {
- CHECK_EQ(expected_counts[i], array->number_of_entries(kTypes[i], kSmall));
- CHECK_EQ(expected_first_idx[i], array->first_index(kTypes[i], kSmall));
- CHECK_EQ(expected_last_idx[i], array->last_index(kTypes[i], kSmall));
+ CHECK(builder.IsEmpty());
+ while (builder.NextAccess(kPtrType) == kRegAccess) {
+ access = builder.AddEntry(pos++, value++, sharing_ok);
+ CHECK_EQ(access, kRegAccess);
}
- CHECK(!array->is_extended_layout());
-
- // Check getters and setters.
- int64_t big_number = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
- Handle<Object> object = factory->NewHeapNumber(4.0, IMMUTABLE, TENURED);
- Code* code = DummyCode(&context);
- array->set(0, big_number);
- array->set(1, 0.5);
- array->set(2, 3e-24);
- array->set(3, code->entry());
- array->set(4, code);
- array->set(5, *object);
- array->set(6, 50);
- CHECK_EQ(big_number, array->get_int64_entry(0));
- CHECK_EQ(0.5, array->get_int64_entry_as_double(1));
- CHECK_EQ(3e-24, array->get_int64_entry_as_double(2));
- CHECK_EQ(code->entry(), array->get_code_ptr_entry(3));
- CHECK_EQ(code, array->get_heap_ptr_entry(4));
- CHECK_EQ(*object, array->get_heap_ptr_entry(5));
- CHECK_EQ(50, array->get_int32_entry(6));
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ access = builder.AddEntry(pos, value, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
}
-TEST(ConstantPoolExtended) {
- LocalContext context;
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(context->GetIsolate());
-
- // Check construction.
- ConstantPoolArray::NumberOfEntries small(1, 2, 3, 4);
- ConstantPoolArray::NumberOfEntries extended(5, 6, 7, 8);
- Handle<ConstantPoolArray> array =
- factory->NewExtendedConstantPoolArray(small, extended);
-
- // Check small section.
- int small_counts[] = { 1, 2, 3, 4 };
- int small_first_idx[] = { 0, 1, 3, 6 };
- int small_last_idx[] = { 0, 2, 5, 9 };
- for (int i = 0; i < 4; i++) {
- CHECK_EQ(small_counts[i], array->number_of_entries(kTypes[i], kSmall));
- CHECK_EQ(small_first_idx[i], array->first_index(kTypes[i], kSmall));
- CHECK_EQ(small_last_idx[i], array->last_index(kTypes[i], kSmall));
- }
+TEST(ConstantPoolDoubles) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = kReach / kDoubleSize;
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ double value = 0.0;
- // Check extended layout.
- CHECK(array->is_extended_layout());
- int extended_counts[] = { 5, 6, 7, 8 };
- int extended_first_idx[] = { 10, 15, 21, 28 };
- int extended_last_idx[] = { 14, 20, 27, 35 };
- for (int i = 0; i < 4; i++) {
- CHECK_EQ(extended_counts[i],
- array->number_of_entries(kTypes[i], kExtended));
- CHECK_EQ(extended_first_idx[i], array->first_index(kTypes[i], kExtended));
- CHECK_EQ(extended_last_idx[i], array->last_index(kTypes[i], kExtended));
+ CHECK(builder.IsEmpty());
+ while (builder.NextAccess(kDblType) == kRegAccess) {
+ access = builder.AddEntry(pos++, value);
+ value += 0.5;
+ CHECK_EQ(access, kRegAccess);
}
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
- // Check small and large section's don't overlap.
- int64_t small_section_int64 = V8_2PART_UINT64_C(0x56781234, DEF09ABC);
- Code* small_section_code_ptr = DummyCode(&context);
- Handle<Object> small_section_heap_ptr =
- factory->NewHeapNumber(4.0, IMMUTABLE, TENURED);
- int32_t small_section_int32 = 0xab12cd45;
-
- int64_t extended_section_int64 = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
- Code* extended_section_code_ptr = DummyCode(&context);
- Handle<Object> extended_section_heap_ptr =
- factory->NewHeapNumber(5.0, IMMUTABLE, TENURED);
- int32_t extended_section_int32 = 0xef67ab89;
-
- for (int i = array->first_index(ConstantPoolArray::INT64, kSmall);
- i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) {
- if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) {
- array->set(i, small_section_int64);
- } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
- array->set(i, small_section_code_ptr->entry());
- } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
- array->set(i, *small_section_heap_ptr);
- } else {
- CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall));
- array->set(i, small_section_int32);
- }
- }
- for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
- i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
- if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
- array->set(i, extended_section_int64);
- } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
- array->set(i, extended_section_code_ptr->entry());
- } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
- array->set(i, *extended_section_heap_ptr);
- } else {
- CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
- array->set(i, extended_section_int32);
- }
- }
+ access = builder.AddEntry(pos, value);
+ CHECK_EQ(access, kOvflAccess);
+}
- for (int i = array->first_index(ConstantPoolArray::INT64, kSmall);
- i <= array->last_index(ConstantPoolArray::INT32, kSmall); i++) {
- if (i <= array->last_index(ConstantPoolArray::INT64, kSmall)) {
- CHECK_EQ(small_section_int64, array->get_int64_entry(i));
- } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kSmall)) {
- CHECK_EQ(small_section_code_ptr->entry(), array->get_code_ptr_entry(i));
- } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kSmall)) {
- CHECK_EQ(*small_section_heap_ptr, array->get_heap_ptr_entry(i));
- } else {
- CHECK(i <= array->last_index(ConstantPoolArray::INT32, kSmall));
- CHECK_EQ(small_section_int32, array->get_int32_entry(i));
- }
- }
- for (int i = array->first_index(ConstantPoolArray::INT64, kExtended);
- i <= array->last_index(ConstantPoolArray::INT32, kExtended); i++) {
- if (i <= array->last_index(ConstantPoolArray::INT64, kExtended)) {
- CHECK_EQ(extended_section_int64, array->get_int64_entry(i));
- } else if (i <= array->last_index(ConstantPoolArray::CODE_PTR, kExtended)) {
- CHECK_EQ(extended_section_code_ptr->entry(),
- array->get_code_ptr_entry(i));
- } else if (i <= array->last_index(ConstantPoolArray::HEAP_PTR, kExtended)) {
- CHECK_EQ(*extended_section_heap_ptr, array->get_heap_ptr_entry(i));
+
+TEST(ConstantPoolMixedTypes) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
+ ((kPointerSize < kDoubleSize) ? 1 : 0));
+ ConstantPoolEntry::Type type = kPtrType;
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = true;
+
+ CHECK(builder.IsEmpty());
+ while (builder.NextAccess(type) == kRegAccess) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
} else {
- CHECK(i <= array->last_index(ConstantPoolArray::INT32, kExtended));
- CHECK_EQ(extended_section_int32, array->get_int32_entry(i));
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
}
+ CHECK_EQ(access, kRegAccess);
}
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
-static void CheckIterator(Handle<ConstantPoolArray> array,
- ConstantPoolArray::Type type,
- int expected_indexes[],
- int count) {
- int i = 0;
- ConstantPoolArray::Iterator iter(*array, type);
- while (!iter.is_finished()) {
- CHECK_EQ(expected_indexes[i++], iter.next_index());
+TEST(ConstantPoolMixedReach) {
+ const int ptrReachBits = kReachBits + 2;
+ const int ptrReach = 1 << ptrReachBits;
+ const int dblReachBits = kReachBits;
+ const int dblReach = kReach;
+ const int dblRegularCount =
+ Min(dblReach / kDoubleSize, ptrReach / (kDoubleSize + kPointerSize));
+ const int ptrRegularCount =
+ ((ptrReach - (dblRegularCount * (kDoubleSize + kPointerSize))) /
+ kPointerSize) +
+ dblRegularCount;
+ ConstantPoolBuilder builder(ptrReachBits, dblReachBits);
+ ConstantPoolEntry::Access access;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = true;
+ int ptrCount = 0;
+ int dblCount = 0;
+
+ CHECK(builder.IsEmpty());
+ while (builder.NextAccess(kDblType) == kRegAccess) {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ dblCount++;
+ CHECK_EQ(access, kRegAccess);
+
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ ptrCount++;
+ CHECK_EQ(access, kRegAccess);
}
- CHECK_EQ(count, i);
-}
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(dblCount, dblRegularCount);
+ while (ptrCount < ptrRegularCount) {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ CHECK_EQ(access, kOvflAccess);
-TEST(ConstantPoolIteratorSmall) {
- LocalContext context;
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(context->GetIsolate());
-
- ConstantPoolArray::NumberOfEntries small(1, 5, 2, 0);
- Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ ptrCount++;
+ CHECK_EQ(access, kRegAccess);
+ }
+ CHECK_EQ(builder.NextAccess(kPtrType), kOvflAccess);
- int expected_int64_indexs[] = { 0 };
- CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 1);
- int expected_code_indexs[] = { 1, 2, 3, 4, 5 };
- CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 5);
- int expected_heap_indexs[] = { 6, 7 };
- CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 2);
- int expected_int32_indexs[1];
- CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 0);
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
-TEST(ConstantPoolIteratorExtended) {
- LocalContext context;
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(context->GetIsolate());
-
- ConstantPoolArray::NumberOfEntries small(1, 0, 0, 4);
- ConstantPoolArray::NumberOfEntries extended(5, 0, 3, 0);
- Handle<ConstantPoolArray> array =
- factory->NewExtendedConstantPoolArray(small, extended);
-
- int expected_int64_indexs[] = { 0, 5, 6, 7, 8, 9 };
- CheckIterator(array, ConstantPoolArray::INT64, expected_int64_indexs, 6);
- int expected_code_indexs[1];
- CheckIterator(array, ConstantPoolArray::CODE_PTR, expected_code_indexs, 0);
- int expected_heap_indexs[] = { 10, 11, 12 };
- CheckIterator(array, ConstantPoolArray::HEAP_PTR, expected_heap_indexs, 3);
- int expected_int32_indexs[] = { 1, 2, 3, 4 };
- CheckIterator(array, ConstantPoolArray::INT32, expected_int32_indexs, 4);
-}
+TEST(ConstantPoolSharing) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
+ ((kPointerSize < kDoubleSize) ? 1 : 0));
+ ConstantPoolEntry::Access access;
+ CHECK(builder.IsEmpty());
-TEST(ConstantPoolPreciseGC) {
- LocalContext context;
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = isolate->heap();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(context->GetIsolate());
-
- ConstantPoolArray::NumberOfEntries small(1, 0, 0, 1);
- Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(small);
-
- // Check that the store buffer knows which entries are pointers and which are
- // not. To do this, make non-pointer entries which look like new space
- // pointers but are actually invalid and ensure the GC doesn't try to move
- // them.
- Handle<HeapObject> object = factory->NewHeapNumber(4.0);
- Object* raw_ptr = *object;
- // If interpreted as a pointer, this should be right inside the heap number
- // which will cause a crash when trying to lookup the 'map' pointer.
- intptr_t invalid_ptr = reinterpret_cast<intptr_t>(raw_ptr) + kInt32Size;
- int32_t invalid_ptr_int32 = static_cast<int32_t>(invalid_ptr);
- int64_t invalid_ptr_int64 = static_cast<int64_t>(invalid_ptr);
- array->set(0, invalid_ptr_int64);
- array->set(1, invalid_ptr_int32);
-
- // Ensure we perform a scan on scavenge for the constant pool's page.
- MemoryChunk::FromAddress(array->address())->set_scan_on_scavenge(true);
- heap->CollectGarbage(NEW_SPACE);
-
- // Check the object was moved by GC.
- CHECK_NE(*object, raw_ptr);
-
- // Check the non-pointer entries weren't changed.
- CHECK_EQ(invalid_ptr_int64, array->get_int64_entry(0));
- CHECK_EQ(invalid_ptr_int32, array->get_int32_entry(1));
+ ConstantPoolEntry::Type type = kPtrType;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = true;
+ while (builder.NextAccess(type) == kRegAccess) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ }
+ CHECK_EQ(access, kRegAccess);
+ }
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ type = kPtrType;
+ ptrValue = 0;
+ dblValue = 0.0;
+ while (pos < kRegularCount * 2) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ }
+ CHECK_EQ(access, kRegAccess);
+ }
+
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
-TEST(ConstantPoolCompacting) {
- if (i::FLAG_never_compact) return;
- i::FLAG_always_compact = true;
- LocalContext context;
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = isolate->heap();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(context->GetIsolate());
-
- ConstantPoolArray::NumberOfEntries small(0, 0, 1, 0);
- ConstantPoolArray::NumberOfEntries extended(0, 0, 1, 0);
- Handle<ConstantPoolArray> array =
- factory->NewExtendedConstantPoolArray(small, extended);
-
- // Start a second old-space page so that the heap pointer added to the
- // constant pool array ends up on the an evacuation candidate page.
- Page* first_page = heap->old_space()->anchor()->next_page();
- {
- HandleScope scope(isolate);
- int dummy_array_size = Page::kMaxRegularHeapObjectSize - 92 * KB;
- Handle<HeapObject> temp =
- factory->NewFixedDoubleArray(dummy_array_size / kDoubleSize, TENURED);
- CHECK(heap->InOldSpace(temp->address()));
- Handle<HeapObject> heap_ptr =
- factory->NewHeapNumber(5.0, IMMUTABLE, TENURED);
- CHECK(heap->InOldSpace(heap_ptr->address()));
- CHECK(!first_page->Contains(heap_ptr->address()));
- array->set(0, *heap_ptr);
- array->set(1, *heap_ptr);
- }
+TEST(ConstantPoolNoSharing) {
+ ConstantPoolBuilder builder(kReachBits, kReachBits);
+ const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
+ ((kPointerSize < kDoubleSize) ? 1 : 0));
+ ConstantPoolEntry::Access access;
- // Check heap pointers are correctly updated on GC.
- Object* old_ptr = array->get_heap_ptr_entry(0);
- Handle<Object> object(old_ptr, isolate);
- CHECK_EQ(old_ptr, *object);
- CHECK_EQ(old_ptr, array->get_heap_ptr_entry(1));
+ CHECK(builder.IsEmpty());
- // Force compacting garbage collection.
- CHECK(FLAG_always_compact);
- heap->CollectAllGarbage();
+ ConstantPoolEntry::Type type = kPtrType;
+ int pos = 0;
+ intptr_t ptrValue = 0;
+ double dblValue = 0.0;
+ bool sharing_ok = false;
+ while (builder.NextAccess(type) == kRegAccess) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ }
+ CHECK_EQ(access, kRegAccess);
+ }
+ CHECK(!builder.IsEmpty());
+ CHECK_EQ(pos, kRegularCount);
+
+ type = kPtrType;
+ ptrValue = 0;
+ dblValue = 0.0;
+ sharing_ok = true;
+ while (pos < kRegularCount * 2) {
+ if (type == kPtrType) {
+ access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
+ type = kDblType;
+ CHECK_EQ(access, kOvflAccess);
+ } else {
+ access = builder.AddEntry(pos++, dblValue);
+ dblValue += 0.5;
+ type = kPtrType;
+ CHECK_EQ(access, kRegAccess);
+ }
+ }
- CHECK_NE(old_ptr, *object);
- CHECK_EQ(*object, array->get_heap_ptr_entry(0));
- CHECK_EQ(*object, array->get_heap_ptr_entry(1));
+ access = builder.AddEntry(pos++, ptrValue, sharing_ok);
+ CHECK_EQ(access, kOvflAccess);
+ access = builder.AddEntry(pos, dblValue);
+ CHECK_EQ(access, kOvflAccess);
}
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 2f6cf6e9a2..a6ffdca179 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -115,8 +115,9 @@ class DebugLocalContext {
v8::Utils::OpenHandle(*context_->Global())));
Handle<v8::internal::String> debug_string =
factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("debug"));
- v8::internal::Runtime::DefineObjectProperty(global, debug_string,
- handle(debug_context->global_proxy(), isolate), DONT_ENUM).Check();
+ v8::internal::JSObject::SetOwnPropertyIgnoreAttributes(
+ global, debug_string, handle(debug_context->global_proxy()), DONT_ENUM)
+ .Check();
}
private:
@@ -211,7 +212,7 @@ static int SetScriptBreakPointByIdFromJS(v8::Isolate* isolate, int script_id,
}
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Handle<v8::String> str =
v8::String::NewFromUtf8(isolate, buffer.start());
v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
@@ -240,7 +241,7 @@ static int SetScriptBreakPointByNameFromJS(v8::Isolate* isolate,
}
buffer[SMALL_STRING_BUFFER_SIZE - 1] = '\0';
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Handle<v8::String> str =
v8::String::NewFromUtf8(isolate, buffer.start());
v8::Handle<v8::Value> value = v8::Script::Compile(str)->Run();
@@ -425,7 +426,8 @@ void CheckDebuggerUnloaded(bool check_functions) {
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
// Check that the debugger has been fully unloaded.
@@ -443,6 +445,7 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
const char* source, const char* name,
int position, v8::internal::RelocInfo::Mode mode,
Code* debug_break) {
+ EnableDebugger();
i::Debug* debug = CcTest::i_isolate()->debug();
// Create function and set the break point.
@@ -486,6 +489,8 @@ void CheckDebugBreakFunction(DebugLocalContext* env,
i::RelocInfo rinfo = location.rinfo();
CHECK(!rinfo.IsPatchedReturnSequence());
}
+
+ DisableDebugger();
}
@@ -964,92 +969,6 @@ static void MessageCallbackCount(v8::Handle<v8::Message> message,
// --- T h e A c t u a l T e s t s
-
-// Test that the debug break function is the expected one for different kinds
-// of break locations.
-TEST(DebugStub) {
- using ::v8::internal::Builtins;
- using ::v8::internal::Isolate;
- DebugLocalContext env;
- v8::HandleScope scope(env->GetIsolate());
-
- CheckDebugBreakFunction(&env,
- "function f1(){}", "f1",
- 0,
- v8::internal::RelocInfo::JS_RETURN,
- NULL);
- CheckDebugBreakFunction(&env,
- "function f2(){x=1;}", "f2",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kStoreIC_DebugBreak));
- CheckDebugBreakFunction(&env,
- "function f3(){var a=x;}", "f3",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kLoadIC_DebugBreak));
-
-// TODO(1240753): Make the test architecture independent or split
-// parts of the debugger into architecture dependent files. This
-// part currently disabled as it is not portable between IA32/ARM.
-// Currently on ICs for keyed store/load on ARM.
-#if !defined (__arm__) && !defined(__thumb__)
- CheckDebugBreakFunction(
- &env,
- "function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
- "f4",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kKeyedStoreIC_DebugBreak));
- CheckDebugBreakFunction(
- &env,
- "function f5(){var index='propertyName'; var a={}; return a[index];}",
- "f5",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kKeyedLoadIC_DebugBreak));
-#endif
-
- CheckDebugBreakFunction(
- &env,
- "function f6(a){return a==null;}",
- "f6",
- 0,
- v8::internal::RelocInfo::CODE_TARGET,
- CcTest::i_isolate()->builtins()->builtin(
- Builtins::kCompareNilIC_DebugBreak));
-
- // Check the debug break code stubs for call ICs with different number of
- // parameters.
- // TODO(verwaest): XXX update test.
- // Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0);
- // Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1);
- // Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4);
-
- // CheckDebugBreakFunction(&env,
- // "function f4_0(){x();}", "f4_0",
- // 0,
- // v8::internal::RelocInfo::CODE_TARGET,
- // *debug_break_0);
-
- // CheckDebugBreakFunction(&env,
- // "function f4_1(){x(1);}", "f4_1",
- // 0,
- // v8::internal::RelocInfo::CODE_TARGET,
- // *debug_break_1);
-
- // CheckDebugBreakFunction(&env,
- // "function f4_4(){x(1,2,3,4);}", "f4_4",
- // 0,
- // v8::internal::RelocInfo::CODE_TARGET,
- // *debug_break_4);
-}
-
-
// Test that the debug info in the VM is in sync with the functions being
// debugged.
TEST(DebugInfo) {
@@ -1064,6 +983,7 @@ TEST(DebugInfo) {
CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
CHECK(!HasDebugInfo(foo));
CHECK(!HasDebugInfo(bar));
+ EnableDebugger();
// One function (foo) is debugged.
int bp1 = SetBreakPoint(foo, 0);
CHECK_EQ(1, v8::internal::GetDebuggedFunctions()->length());
@@ -1081,6 +1001,7 @@ TEST(DebugInfo) {
CHECK(HasDebugInfo(bar));
// No functions are debugged.
ClearBreakPoint(bp2);
+ DisableDebugger();
CHECK_EQ(0, v8::internal::GetDebuggedFunctions()->length());
CHECK(!HasDebugInfo(foo));
CHECK(!HasDebugInfo(bar));
@@ -2288,11 +2209,12 @@ TEST(RemoveBreakPointInBreak) {
v8::Local<v8::Function> foo =
CompileFunction(&env, "function foo(){a=1;}", "foo");
- debug_event_remove_break_point = SetBreakPoint(foo, 0);
// Register the debug event listener pasing the function
v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
+ debug_event_remove_break_point = SetBreakPoint(foo, 0);
+
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@@ -2348,7 +2270,7 @@ TEST(DebuggerStatementBreakpoint) {
v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
- // The debugger statement triggers breakpint hit
+ // The debugger statement triggers breakpoint hit
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@@ -2779,11 +2701,11 @@ TEST(DebugStepLinear) {
// Run foo to allow it to get optimized.
CompileRun("a=0; b=0; c=0; foo();");
- SetBreakPoint(foo, 3);
-
// Register a debug event listener which steps and counts.
v8::Debug::SetDebugEventListener(DebugEventStep);
+ SetBreakPoint(foo, 3);
+
step_action = StepIn;
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3272,6 +3194,13 @@ TEST(DebugStepDoWhile) {
v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
SetBreakPoint(foo, 8); // "var a = 0;"
+ // Looping 0 times.
+ step_action = StepIn;
+ break_point_hit_count = 0;
+ v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)};
+ foo->Call(env->Global(), argc, argv_0);
+ CHECK_EQ(4, break_point_hit_count);
+
// Looping 10 times.
step_action = StepIn;
break_point_hit_count = 0;
@@ -3314,19 +3243,26 @@ TEST(DebugStepFor) {
SetBreakPoint(foo, 8); // "a = 1;"
+ // Looping 0 times.
+ step_action = StepIn;
+ break_point_hit_count = 0;
+ v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)};
+ foo->Call(env->Global(), argc, argv_0);
+ CHECK_EQ(4, break_point_hit_count);
+
// Looping 10 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
foo->Call(env->Global(), argc, argv_10);
- CHECK_EQ(45, break_point_hit_count);
+ CHECK_EQ(34, break_point_hit_count);
// Looping 100 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
foo->Call(env->Global(), argc, argv_100);
- CHECK_EQ(405, break_point_hit_count);
+ CHECK_EQ(304, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);
@@ -3541,14 +3477,14 @@ TEST(DebugConditional) {
step_action = StepIn;
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
- CHECK_EQ(5, break_point_hit_count);
+ CHECK_EQ(4, break_point_hit_count);
step_action = StepIn;
break_point_hit_count = 0;
const int argc = 1;
v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) };
foo->Call(env->Global(), argc, argv_true);
- CHECK_EQ(5, break_point_hit_count);
+ CHECK_EQ(4, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);
@@ -3823,6 +3759,48 @@ TEST(DebugStepFunctionCall) {
}
+// Test that step in works with Function.call.apply.
+TEST(DebugStepFunctionCallApply) {
+ DebugLocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ // Create a function for testing stepping.
+ v8::Local<v8::Function> foo =
+ CompileFunction(&env,
+ "function bar() { }"
+ "function foo(){ debugger;"
+ " Function.call.apply(bar);"
+ " Function.call.apply(Function.call, "
+ "[Function.call, bar]);"
+ "}",
+ "foo");
+
+ // Register a debug event listener which steps and counts.
+ v8::Debug::SetDebugEventListener(DebugEventStep);
+ step_action = StepIn;
+
+ break_point_hit_count = 0;
+ foo->Call(env->Global(), 0, NULL);
+ CHECK_EQ(5, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+
+ // Register a debug event listener which just counts.
+ v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+
+ break_point_hit_count = 0;
+ foo->Call(env->Global(), 0, NULL);
+
+ // Without stepping only the debugger statement is hit.
+ CHECK_EQ(1, break_point_hit_count);
+
+ v8::Debug::SetDebugEventListener(NULL);
+ CheckDebuggerUnloaded();
+}
+
+
// Tests that breakpoint will be hit if it's set in script.
TEST(PauseInScript) {
DebugLocalContext env;
@@ -3856,6 +3834,13 @@ TEST(PauseInScript) {
}
+static void DebugEventCounterCheck(int caught, int uncaught, int message) {
+ CHECK_EQ(caught, exception_hit_count);
+ CHECK_EQ(uncaught, uncaught_exception_hit_count);
+ CHECK_EQ(message, message_callback_count);
+}
+
+
// Test break on exceptions. For each exception break combination the number
// of debug event exception callbacks and message callbacks are collected. The
// number of debug event exception callbacks are used to check that the
@@ -3875,6 +3860,15 @@ TEST(BreakOnException) {
"caught");
v8::Local<v8::Function> notCaught =
CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
+ v8::Local<v8::Function> notCaughtFinally = CompileFunction(
+ &env, "function notCaughtFinally(){try{throws();}finally{}}",
+ "notCaughtFinally");
+ // In this edge case, even though this finally does not propagate the
+ // exception, the debugger considers this uncaught, since we want to break
+ // at the first throw for the general case where finally implicitly rethrows.
+ v8::Local<v8::Function> edgeCaseFinally = CompileFunction(
+ &env, "function caughtFinally(){L:try{throws();}finally{break L;}}",
+ "caughtFinally");
v8::V8::AddMessageListener(MessageCallbackCount);
v8::Debug::SetDebugEventListener(DebugEventCounter);
@@ -3883,117 +3877,117 @@ TEST(BreakOnException) {
DebugEventCounterClear();
MessageCallbackCountClear();
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(0, 0, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
// No break on exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(false, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(0, 0, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
// Break on uncaught exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(false, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(1, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(2, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 3, 2);
// Break on exception and uncaught exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(true, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
// Break on exception
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnException(true, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
// No break on exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(0, 0, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(0, 0, 2);
// Break on uncaught exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), false, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(0, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(0, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(1, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(2, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 3, 2);
// Break on exception and uncaught exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, true);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, message_callback_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
// Break on exception using JavaScript
DebugEventCounterClear();
MessageCallbackCountClear();
ChangeBreakOnExceptionFromJS(env->GetIsolate(), true, false);
caught->Call(env->Global(), 0, NULL);
- CHECK_EQ(1, exception_hit_count);
- CHECK_EQ(0, uncaught_exception_hit_count);
- CHECK_EQ(0, message_callback_count);
+ DebugEventCounterCheck(1, 0, 0);
notCaught->Call(env->Global(), 0, NULL);
- CHECK_EQ(2, exception_hit_count);
- CHECK_EQ(1, uncaught_exception_hit_count);
- CHECK_EQ(1, message_callback_count);
+ DebugEventCounterCheck(2, 1, 1);
+ notCaughtFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(3, 2, 2);
+ edgeCaseFinally->Call(env->Global(), 0, NULL);
+ DebugEventCounterCheck(4, 3, 2);
v8::Debug::SetDebugEventListener(NULL);
CheckDebuggerUnloaded();
@@ -4001,6 +3995,35 @@ TEST(BreakOnException) {
}
+static void try_finally_original_message(v8::Handle<v8::Message> message,
+ v8::Handle<v8::Value> data) {
+ CHECK_EQ(2, message->GetLineNumber());
+ CHECK_EQ(2, message->GetStartColumn());
+ message_callback_count++;
+}
+
+
+TEST(TryFinallyOriginalMessage) {
+ // Test that the debugger plays nicely with the pending message.
+ message_callback_count = 0;
+ DebugEventCounterClear();
+ v8::V8::AddMessageListener(try_finally_original_message);
+ v8::Debug::SetDebugEventListener(DebugEventCounter);
+ ChangeBreakOnException(true, true);
+ DebugLocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ CompileRun(
+ "try {\n"
+ " throw 1;\n"
+ "} finally {\n"
+ "}\n");
+ DebugEventCounterCheck(1, 1, 1);
+ v8::Debug::SetDebugEventListener(NULL);
+ v8::V8::RemoveMessageListeners(try_finally_original_message);
+}
+
+
TEST(EvalJSInDebugEventListenerOnNativeReThrownException) {
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -4023,7 +4046,7 @@ TEST(EvalJSInDebugEventListenerOnNativeReThrownException) {
// ReThrow native error
{
- v8::TryCatch tryCatch;
+ v8::TryCatch tryCatch(env->GetIsolate());
env->GetIsolate()->ThrowException(v8::Exception::TypeError(
v8::String::NewFromUtf8(env->GetIsolate(), "Type error")));
CHECK(tryCatch.HasCaught());
@@ -5532,11 +5555,6 @@ TEST(RecursiveBreakpointsGlobal) {
}
-static void DummyDebugEventListener(
- const v8::Debug::EventDetails& event_details) {
-}
-
-
TEST(SetDebugEventListenerOnUninitializedVM) {
v8::Debug::SetDebugEventListener(DummyDebugEventListener);
}
@@ -5602,7 +5620,7 @@ static void CheckDataParameter(
CHECK(v8::Debug::Call(debugger_call_with_data, data)->IsString());
for (int i = 0; i < 3; i++) {
- v8::TryCatch catcher;
+ v8::TryCatch catcher(args.GetIsolate());
CHECK(v8::Debug::Call(debugger_call_with_data).IsEmpty());
CHECK(catcher.HasCaught());
CHECK(catcher.Exception()->IsString());
@@ -5910,7 +5928,7 @@ TEST(DebugGetLoadedScripts) {
v8::String::NewExternal(env->GetIsolate(), &source_ext_str);
v8::Handle<v8::Script> evil_script(v8::Script::Compile(source));
// "use" evil_script to make the compiler happy.
- (void) evil_script;
+ USE(evil_script);
Handle<i::ExternalTwoByteString> i_source(
i::ExternalTwoByteString::cast(*v8::Utils::OpenHandle(*source)));
// This situation can happen if source was an external string disposed
@@ -5919,12 +5937,23 @@ TEST(DebugGetLoadedScripts) {
bool allow_natives_syntax = i::FLAG_allow_natives_syntax;
i::FLAG_allow_natives_syntax = true;
- CompileRun(
- "var scripts = %DebugGetLoadedScripts();"
- "var count = scripts.length;"
- "for (var i = 0; i < count; ++i) {"
- " scripts[i].line_ends;"
- "}");
+ EnableDebugger();
+ v8::MaybeLocal<v8::Value> result =
+ CompileRun(env.context(),
+ "var scripts = %DebugGetLoadedScripts();"
+ "var count = scripts.length;"
+ "for (var i = 0; i < count; ++i) {"
+ " var lines = scripts[i].lineCount();"
+ " if (lines < 1) throw 'lineCount';"
+ " var last = -1;"
+ " for (var j = 0; j < lines; ++j) {"
+ " var end = scripts[i].lineEnd(j);"
+ " if (last >= end) throw 'lineEnd';"
+ " last = end;"
+ " }"
+ "}");
+ CHECK(!result.IsEmpty());
+ DisableDebugger();
// Must not crash while accessing line_ends.
i::FLAG_allow_natives_syntax = allow_natives_syntax;
@@ -6492,6 +6521,8 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
const char* script = "function f() {};";
const char* resource_name = "test_resource";
+ v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
+
// Set a couple of provisional breakpoint on lines out of the script lines
// range.
int sbp1 = SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name,
@@ -6500,7 +6531,6 @@ TEST(ProvisionalBreakpointOnLineOutOfRange) {
SetScriptBreakPointByNameFromJS(env->GetIsolate(), resource_name, 5, 5);
after_compile_message_count = 0;
- v8::Debug::SetMessageHandler(AfterCompileMessageHandler);
v8::ScriptOrigin origin(
v8::String::NewFromUtf8(env->GetIsolate(), resource_name),
@@ -6925,6 +6955,13 @@ TEST(DebugContextIsPreservedBetweenAccesses) {
}
+TEST(NoDebugContextWhenDebuggerDisabled) {
+ v8::HandleScope scope(CcTest::isolate());
+ v8::Local<v8::Context> context = v8::Debug::GetDebugContext();
+ CHECK(context.IsEmpty());
+}
+
+
static v8::Handle<v8::Value> expected_callback_data;
static void DebugEventContextChecker(const v8::Debug::EventDetails& details) {
CHECK(details.GetEventContext() == expected_context);
@@ -7260,7 +7297,7 @@ static void DebugEventStepNext(
static void RunScriptInANewCFrame(const char* source) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
CompileRun(source);
CHECK(try_catch.HasCaught());
}
@@ -7440,7 +7477,7 @@ TEST(DebugBreakOffThreadTerminate) {
v8::Debug::SetDebugEventListener(DebugBreakTriggerTerminate);
TerminationThread terminator(isolate);
terminator.Start();
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(env->GetIsolate());
v8::Debug::DebugBreak(isolate);
CompileRun("while (true);");
CHECK(try_catch.HasTerminated());
@@ -7456,7 +7493,7 @@ static void DebugEventExpectNoException(
static void TryCatchWrappedThrowCallback(
const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CompileRun("throw 'rejection';");
CHECK(try_catch.HasCaught());
}
diff --git a/deps/v8/test/cctest/test-decls.cc b/deps/v8/test/cctest/test-decls.cc
index f3dc777102..347ca9a6bc 100644
--- a/deps/v8/test/cctest/test-decls.cc
+++ b/deps/v8/test/cctest/test-decls.cc
@@ -130,6 +130,10 @@ void DeclarationContext::InitializeIfNeeded() {
context_.Reset(isolate, context);
context->Enter();
is_initialized_ = true;
+ // Reset counts. Bootstrapping might have called into the interceptor.
+ get_count_ = 0;
+ set_count_ = 0;
+ query_count_ = 0;
PostInitializeContext(context);
}
@@ -143,7 +147,7 @@ void DeclarationContext::Check(const char* source,
// to avoid that.
CcTest::heap()->CollectGarbage(v8::internal::NEW_SPACE);
HandleScope scope(CcTest::isolate());
- TryCatch catcher;
+ TryCatch catcher(CcTest::isolate());
catcher.SetVerbose(true);
Local<Script> script =
Script::Compile(String::NewFromUtf8(CcTest::isolate(), source));
@@ -567,7 +571,7 @@ class SimpleContext {
Expectations expectations,
v8::Handle<Value> value = Local<Value>()) {
HandleScope scope(context_->GetIsolate());
- TryCatch catcher;
+ TryCatch catcher(context_->GetIsolate());
catcher.SetVerbose(true);
Local<Script> script =
Script::Compile(String::NewFromUtf8(context_->GetIsolate(), source));
diff --git a/deps/v8/test/cctest/test-deoptimization.cc b/deps/v8/test/cctest/test-deoptimization.cc
index 674291524d..1d512e0a75 100644
--- a/deps/v8/test/cctest/test-deoptimization.cc
+++ b/deps/v8/test/cctest/test-deoptimization.cc
@@ -112,8 +112,6 @@ static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
TEST(DeoptimizeSimple) {
- i::FLAG_turbo_deoptimization = true;
-
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -152,8 +150,6 @@ TEST(DeoptimizeSimple) {
TEST(DeoptimizeSimpleWithArguments) {
- i::FLAG_turbo_deoptimization = true;
-
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -193,8 +189,6 @@ TEST(DeoptimizeSimpleWithArguments) {
TEST(DeoptimizeSimpleNested) {
- i::FLAG_turbo_deoptimization = true;
-
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -220,7 +214,6 @@ TEST(DeoptimizeSimpleNested) {
TEST(DeoptimizeRecursive) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -248,7 +241,6 @@ TEST(DeoptimizeRecursive) {
TEST(DeoptimizeMultiple) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -277,7 +269,6 @@ TEST(DeoptimizeMultiple) {
TEST(DeoptimizeConstructor) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -316,7 +307,6 @@ TEST(DeoptimizeConstructor) {
TEST(DeoptimizeConstructorMultiple) {
- i::FLAG_turbo_deoptimization = true;
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -346,7 +336,6 @@ TEST(DeoptimizeConstructorMultiple) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationADDString) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
AllowNativesSyntaxNoInlining options;
v8::Isolate::CreateParams create_params;
@@ -451,7 +440,6 @@ static void TestDeoptimizeBinaryOpHelper(LocalContext* env,
UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -474,7 +462,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationADD) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -497,7 +484,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationSUB) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -520,7 +506,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationMUL) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -543,7 +528,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationDIV) {
UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -566,7 +550,6 @@ UNINITIALIZED_TEST(DeoptimizeBinaryOperationMOD) {
UNINITIALIZED_TEST(DeoptimizeCompare) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -623,7 +606,6 @@ UNINITIALIZED_TEST(DeoptimizeCompare) {
UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
@@ -716,7 +698,6 @@ UNINITIALIZED_TEST(DeoptimizeLoadICStoreIC) {
UNINITIALIZED_TEST(DeoptimizeLoadICStoreICNested) {
- i::FLAG_turbo_deoptimization = true;
i::FLAG_concurrent_recompilation = false;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
diff --git a/deps/v8/test/cctest/test-disasm-arm64.cc b/deps/v8/test/cctest/test-disasm-arm64.cc
index 208f1f5afb..b3b50acf9d 100644
--- a/deps/v8/test/cctest/test-disasm-arm64.cc
+++ b/deps/v8/test/cctest/test-disasm-arm64.cc
@@ -83,10 +83,11 @@ using namespace v8::internal;
abort(); \
}
-#define CLEANUP() \
- delete disasm; \
- delete decoder; \
- delete assm
+#define CLEANUP() \
+ delete disasm; \
+ delete decoder; \
+ delete assm; \
+ free(buf)
static bool vm_initialized = false;
diff --git a/deps/v8/test/cctest/test-disasm-mips.cc b/deps/v8/test/cctest/test-disasm-mips.cc
index b66554e55e..c04cd23bf5 100644
--- a/deps/v8/test/cctest/test-disasm-mips.cc
+++ b/deps/v8/test/cctest/test-disasm-mips.cc
@@ -92,6 +92,45 @@ if (failure) { \
}
+#define COMPARE_PC_REL_COMPACT(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + 4 + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_REL(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_JUMP(asm_, compare_string, target) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ int instr_index = target >> 2; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, reinterpret_cast<byte *>( \
+ ((uint32_t)(progcounter + 1) & ~0xfffffff) | \
+ (instr_index << 2))); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
TEST(Type0) {
SET_UP();
@@ -199,39 +238,241 @@ TEST(Type0) {
COMPARE(modu(v0, v1, a0),
"006410db modu v0, v1, a0");
- COMPARE(bovc(a0, a0, static_cast<int16_t>(0)),
- "20840000 bovc a0, a0, 0");
- COMPARE(bovc(a1, a0, static_cast<int16_t>(0)),
- "20a40000 bovc a1, a0, 0");
- COMPARE(bovc(a1, a0, 32767),
- "20a47fff bovc a1, a0, 32767");
- COMPARE(bovc(a1, a0, -32768),
- "20a48000 bovc a1, a0, -32768");
-
- COMPARE(bnvc(a0, a0, static_cast<int16_t>(0)),
- "60840000 bnvc a0, a0, 0");
- COMPARE(bnvc(a1, a0, static_cast<int16_t>(0)),
- "60a40000 bnvc a1, a0, 0");
- COMPARE(bnvc(a1, a0, 32767),
- "60a47fff bnvc a1, a0, 32767");
- COMPARE(bnvc(a1, a0, -32768),
- "60a48000 bnvc a1, a0, -32768");
-
- COMPARE(beqzc(a0, 0),
- "d8800000 beqzc a0, 0x0");
- COMPARE(beqzc(a0, 0xfffff), // 0x0fffff == 1048575.
- "d88fffff beqzc a0, 0xfffff");
- COMPARE(beqzc(a0, 0x100000), // 0x100000 == -1048576.
- "d8900000 beqzc a0, 0x100000");
-
- COMPARE(bnezc(a0, 0),
- "f8800000 bnezc a0, 0x0");
- COMPARE(bnezc(a0, 0xfffff), // 0x0fffff == 1048575.
- "f88fffff bnezc a0, 0xfffff");
- COMPARE(bnezc(a0, 0x100000), // 0x100000 == -1048576.
- "f8900000 bnezc a0, 0x100000");
+ COMPARE_PC_REL_COMPACT(bovc(a0, a0, static_cast<int16_t>(0)),
+ "20840000 bovc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, static_cast<int16_t>(0)),
+ "20a40000 bovc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, 32767),
+ "20a47fff bovc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -32768),
+ "20a48000 bovc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(bnvc(a0, a0, static_cast<int16_t>(0)),
+ "60840000 bnvc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, static_cast<int16_t>(0)),
+ "60a40000 bnvc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, 32767),
+ "60a47fff bnvc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, -32768),
+ "60a48000 bnvc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(beqzc(a0, -1048576),
+ "d8900000 beqzc a0, -1048576", -1048576);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, -1), "d89fffff beqzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0), "d8800000 beqzc a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 1), "d8800001 beqzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 1048575),
+ "d88fffff beqzc a0, 1048575", 1048575);
+
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0x0", 0);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "f88fffff bnezc a0, 0xfffff", 1048575);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0x100000), // 0x100000 == -1048576.
+ "f8900000 bnezc a0, 0x100000", -1048576);
+
+ COMPARE_PC_REL_COMPACT(bc(-33554432), "ca000000 bc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(bc(-1), "cbffffff bc -1", -1);
+ COMPARE_PC_REL_COMPACT(bc(0), "c8000000 bc 0", 0);
+ COMPARE_PC_REL_COMPACT(bc(1), "c8000001 bc 1", 1);
+ COMPARE_PC_REL_COMPACT(bc(33554431), "c9ffffff bc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(balc(-33554432), "ea000000 balc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(balc(-1), "ebffffff balc -1", -1);
+ COMPARE_PC_REL_COMPACT(balc(0), "e8000000 balc 0", 0);
+ COMPARE_PC_REL_COMPACT(balc(1), "e8000001 balc 1", 1);
+ COMPARE_PC_REL_COMPACT(balc(33554431), "e9ffffff balc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -32768),
+ "18858000 bgeuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -1),
+ "1885ffff bgeuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1),
+ "18850001 bgeuc a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 32767),
+ "18857fff bgeuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -32768),
+ "18848000 bgezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 32767),
+ "18847fff bgezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -32768),
+ "18048000 blezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 32767),
+ "18047fff blezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -32768),
+ "1c858000 bltuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -1),
+ "1c85ffff bltuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 1), "1c850001 bltuc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 32767),
+ "1c857fff bltuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -32768),
+ "1c848000 bltzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -1), "1c84ffff bltzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 1), "1c840001 bltzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 32767),
+ "1c847fff bltzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -32768),
+ "1c048000 bgtzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -1), "1c04ffff bgtzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 1), "1c040001 bgtzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 32767),
+ "1c047fff bgtzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -32768),
+ "58848000 bgezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -1), "5884ffff bgezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 1), "58840001 bgezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 32767),
+ "58847fff bgezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -32768),
+ "58858000 bgec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -1),
+ "5885ffff bgec a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 1), "58850001 bgec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 32767),
+ "58857fff bgec a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezc(a0, -32768),
+ "58048000 blezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezc(a0, -1), "5804ffff blezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 1), "58040001 blezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 32767),
+ "58047fff blezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -32768),
+ "5c848000 bltzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -1), "5c84ffff bltzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 1), "5c840001 bltzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 32767),
+ "5c847fff bltzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -32768),
+ "5c858000 bltc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -1),
+ "5c85ffff bltc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 32767),
+ "5c857fff bltc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -32768),
+ "5c048000 bgtzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -1), "5c04ffff bgtzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 1), "5c040001 bgtzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 32767),
+ "5c047fff bgtzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1eqz(-32768, f1),
+ "45218000 bc1eqz f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1eqz(-1, f1), "4521ffff bc1eqz f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(1, f1), "45210001 bc1eqz f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(32767, f1),
+ "45217fff bc1eqz f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1nez(-32768, f1),
+ "45a18000 bc1nez f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1nez(-1, f1), "45a1ffff bc1nez f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1nez(1, f1), "45a10001 bc1nez f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1nez(32767, f1),
+ "45a17fff bc1nez f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -1), "20a4ffff bovc a1, a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bovc(a0, a0, 1), "20840001 bovc a0, a0, 1",
+ 1);
+
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -32768),
+ "20858000 beqc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1), "2085ffff beqc a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 32767),
+ "20857fff beqc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -32768),
+ "60858000 bnec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -1), "6085ffff bnec a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 1), "60850001 bnec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 32767),
+ "60857fff bnec a0, a1, 32767", 32767);
}
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -32768),
+ "14858000 bne a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -1), "1485ffff bne a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 1), "14850001 bne a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 32767),
+ "14857fff bne a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -32768),
+ "10858000 beq a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -1), "1085ffff beq a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 1), "10850001 beq a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 32767),
+ "10857fff beq a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltz(a0, -32768), "04808000 bltz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bltz(a0, -1), "0480ffff bltz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 1), "04800001 bltz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 32767), "04807fff bltz a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgez(a0, -32768), "04818000 bgez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgez(a0, -1), "0481ffff bgez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 1), "04810001 bgez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 32767), "04817fff bgez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(blez(a0, -32768), "18808000 blez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(blez(a0, -1), "1880ffff blez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 1), "18800001 blez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 32767), "18807fff blez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -32768), "1c808000 bgtz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -1), "1c80ffff bgtz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 1), "1c800001 bgtz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 32767), "1c807fff bgtz a0, 32767",
+ 32767);
+
+ COMPARE_PC_JUMP(j(0x4), "08000001 j 0x4", 0x4);
+ COMPARE_PC_JUMP(j(0xffffffc), "0bffffff j 0xffffffc", 0xffffffc);
+
+ COMPARE_PC_JUMP(jal(0x4), "0c000001 jal 0x4", 0x4);
+ COMPARE_PC_JUMP(jal(0xffffffc), "0fffffff jal 0xffffffc",
+ 0xffffffc);
+
COMPARE(addiu(a0, a1, 0x0),
"24a40000 addiu a0, a1, 0");
COMPARE(addiu(s0, s1, 32767),
@@ -506,7 +747,7 @@ TEST(Type0) {
}
}
- if (IsMipsArchVariant(kMips32r2)) {
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
COMPARE(ins_(a0, a1, 31, 1),
"7ca4ffc4 ins a0, a1, 31, 1");
COMPARE(ins_(s6, s7, 30, 2),
@@ -520,26 +761,280 @@ TEST(Type0) {
COMPARE(ext_(v0, v1, 0, 32),
"7c62f800 ext v0, v1, 0, 32");
}
+ COMPARE(add_s(f4, f6, f8), "46083100 add.s f4, f6, f8");
+ COMPARE(add_d(f12, f14, f16), "46307300 add.d f12, f14, f16");
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(bitswap(a0, a1), "7c052020 bitswap a0, a1");
+ COMPARE(bitswap(t8, s0), "7c10c020 bitswap t8, s0");
+ }
+
+ COMPARE(abs_s(f6, f8), "46004185 abs.s f6, f8");
+ COMPARE(abs_d(f10, f12), "46206285 abs.d f10, f12");
+
+ COMPARE(div_s(f2, f4, f6), "46062083 div.s f2, f4, f6");
+ COMPARE(div_d(f2, f4, f6), "46262083 div.d f2, f4, f6");
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(align(v0, a0, a1, 0), "7c851220 align v0, a0, a1, 0");
+ COMPARE(align(v0, a0, a1, 1), "7c851260 align v0, a0, a1, 1");
+ COMPARE(align(v0, a0, a1, 2), "7c8512a0 align v0, a0, a1, 2");
+ COMPARE(align(v0, a0, a1, 3), "7c8512e0 align v0, a0, a1, 3");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(aluipc(v0, 0), "ec5f0000 aluipc v0, 0");
+ COMPARE(aluipc(v0, 1), "ec5f0001 aluipc v0, 1");
+ COMPARE(aluipc(v0, 32767), "ec5f7fff aluipc v0, 32767");
+ COMPARE(aluipc(v0, -32768), "ec5f8000 aluipc v0, -32768");
+ COMPARE(aluipc(v0, -1), "ec5fffff aluipc v0, -1");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(auipc(t8, 0), "ef1e0000 auipc t8, 0");
+ COMPARE(auipc(t8, 1), "ef1e0001 auipc t8, 1");
+ COMPARE(auipc(t8, 32767), "ef1e7fff auipc t8, 32767");
+ COMPARE(auipc(t8, -32768), "ef1e8000 auipc t8, -32768");
+ COMPARE(auipc(t8, -1), "ef1effff auipc t8, -1");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(lwpc(t1, 0), "ed280000 lwpc t1, 0");
+ COMPARE(lwpc(t1, 4), "ed280004 lwpc t1, 4");
+ COMPARE(lwpc(t1, -4), "ed2ffffc lwpc t1, -4");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(jic(t0, -32768), "d8088000 jic t0, -32768");
+ COMPARE(jic(t0, -1), "d808ffff jic t0, -1");
+ COMPARE(jic(t0, 0), "d8080000 jic t0, 0");
+ COMPARE(jic(t0, 4), "d8080004 jic t0, 4");
+ COMPARE(jic(t0, 32767), "d8087fff jic t0, 32767");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(addiupc(a0, 262143), "ec83ffff addiupc a0, 262143");
+ COMPARE(addiupc(a0, -1), "ec87ffff addiupc a0, -1");
+ COMPARE(addiupc(v0, 0), "ec400000 addiupc v0, 0");
+ COMPARE(addiupc(s1, 1), "ee200001 addiupc s1, 1");
+ COMPARE(addiupc(a0, -262144), "ec840000 addiupc a0, -262144");
+ }
+
+ if (IsMipsArchVariant(kMips32r6)) {
+ COMPARE(jialc(a0, -32768), "f8048000 jialc a0, 0x8000");
+ COMPARE(jialc(a0, -1), "f804ffff jialc a0, 0xffff");
+ COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0x0");
+ COMPARE(jialc(s1, 1), "f8110001 jialc s1, 0x1");
+ COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 0x7fff");
+ }
VERIFY_RUN();
}
-// Tests only seleqz, selnez, seleqz.fmt and selnez.fmt
TEST(Type1) {
+ SET_UP();
if (IsMipsArchVariant(kMips32r6)) {
- SET_UP();
COMPARE(seleqz(a0, a1, a2), "00a62035 seleqz a0, a1, a2");
COMPARE(selnez(a0, a1, a2), "00a62037 selnez a0, a1, a2");
- COMPARE(seleqz(D, f3, f4, f5), "462520d4 seleqz.d f3, f4, f5");
- COMPARE(selnez(D, f3, f4, f5), "462520d7 selnez.d f3, f4, f5");
+ COMPARE(seleqz_d(f3, f4, f5), "462520d4 seleqz.d f3, f4, f5");
+ COMPARE(selnez_d(f3, f4, f5), "462520d7 selnez.d f3, f4, f5");
+ COMPARE(seleqz_s(f3, f4, f5), "460520d4 seleqz.s f3, f4, f5");
+ COMPARE(selnez_s(f3, f4, f5), "460520d7 selnez.s f3, f4, f5");
COMPARE(min_d(f3, f4, f5), "462520dc min.d f3, f4, f5");
COMPARE(max_d(f3, f4, f5), "462520de max.d f3, f4, f5");
+
+ COMPARE(sel_s(f3, f4, f5), "460520d0 sel.s f3, f4, f5");
+ COMPARE(sel_d(f3, f4, f5), "462520d0 sel.d f3, f4, f5");
+
COMPARE(rint_d(f8, f6), "4620321a rint.d f8, f6");
+ COMPARE(rint_s(f8, f6), "4600321a rint.s f8, f6");
+
+ COMPARE(min_s(f3, f4, f5), "460520dc min.s f3, f4, f5");
+ COMPARE(max_s(f3, f4, f5), "460520de max.s f3, f4, f5");
+
+ COMPARE(mina_d(f3, f4, f5), "462520dd mina.d f3, f4, f5");
+ COMPARE(mina_s(f3, f4, f5), "460520dd mina.s f3, f4, f5");
+
+ COMPARE(maxa_d(f3, f4, f5), "462520df maxa.d f3, f4, f5");
+ COMPARE(maxa_s(f3, f4, f5), "460520df maxa.s f3, f4, f5");
+ }
+
+ COMPARE(trunc_w_d(f8, f6), "4620320d trunc.w.d f8, f6");
+ COMPARE(trunc_w_s(f8, f6), "4600320d trunc.w.s f8, f6");
+
+ COMPARE(round_w_s(f8, f6), "4600320c round.w.s f8, f6");
+ COMPARE(round_w_d(f8, f6), "4620320c round.w.d f8, f6");
+
+ COMPARE(round_l_s(f8, f6), "46003208 round.l.s f8, f6");
+ COMPARE(round_l_d(f8, f6), "46203208 round.l.d f8, f6");
+
+ COMPARE(floor_w_s(f8, f6), "4600320f floor.w.s f8, f6");
+ COMPARE(floor_w_d(f8, f6), "4620320f floor.w.d f8, f6");
+
+ COMPARE(floor_l_s(f8, f6), "4600320b floor.l.s f8, f6");
+ COMPARE(floor_l_d(f8, f6), "4620320b floor.l.d f8, f6");
+
+ COMPARE(ceil_w_s(f8, f6), "4600320e ceil.w.s f8, f6");
+ COMPARE(ceil_w_d(f8, f6), "4620320e ceil.w.d f8, f6");
+
+ COMPARE(ceil_l_s(f8, f6), "4600320a ceil.l.s f8, f6");
+ COMPARE(ceil_l_d(f8, f6), "4620320a ceil.l.d f8, f6");
+
+ COMPARE(sub_s(f10, f8, f6), "46064281 sub.s f10, f8, f6");
+ COMPARE(sub_d(f10, f8, f6), "46264281 sub.d f10, f8, f6");
+
+ COMPARE(sqrt_s(f8, f6), "46003204 sqrt.s f8, f6");
+ COMPARE(sqrt_d(f8, f6), "46203204 sqrt.d f8, f6");
+
+ COMPARE(neg_s(f8, f6), "46003207 neg.s f8, f6");
+ COMPARE(neg_d(f8, f6), "46203207 neg.d f8, f6");
+
+ COMPARE(mul_s(f8, f6, f4), "46043202 mul.s f8, f6, f4");
+ COMPARE(mul_d(f8, f6, f4), "46243202 mul.d f8, f6, f4");
+
+ if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+ COMPARE(rsqrt_s(f8, f6), "46003216 rsqrt.s f8, f6");
+ COMPARE(rsqrt_d(f8, f6), "46203216 rsqrt.d f8, f6");
+
+ COMPARE(recip_s(f8, f6), "46003215 recip.s f8, f6");
+ COMPARE(recip_d(f8, f6), "46203215 recip.d f8, f6");
+ }
+
+ COMPARE(mov_s(f6, f4), "46002186 mov.s f6, f4");
+ COMPARE(mov_d(f6, f4), "46202186 mov.d f6, f4");
+
+ if (IsMipsArchVariant(kMips32r2)) {
+ COMPARE(trunc_l_d(f8, f6), "46203209 trunc.l.d f8, f6");
+ COMPARE(trunc_l_s(f8, f6), "46003209 trunc.l.s f8, f6");
+
+ COMPARE(movz_s(f6, f4, t0), "46082192 movz.s f6, f4, t0");
+ COMPARE(movz_d(f6, f4, t0), "46282192 movz.d f6, f4, t0");
+
+ COMPARE(movt_s(f6, f4, 4), "46112191 movt.s f6, f4, cc(1)");
+ COMPARE(movt_d(f6, f4, 4), "46312191 movt.d f6, f4, cc(1)");
+
+ COMPARE(movf_s(f6, f4, 4), "46102191 movf.s f6, f4, cc(1)");
+ COMPARE(movf_d(f6, f4, 4), "46302191 movf.d f6, f4, cc(1)");
+
+ COMPARE(movn_s(f6, f4, t0), "46082193 movn.s f6, f4, t0");
+ COMPARE(movn_d(f6, f4, t0), "46282193 movn.d f6, f4, t0");
+ }
+ VERIFY_RUN();
+}
+
+
+TEST(Type2) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ SET_UP();
+
+ COMPARE(class_s(f3, f4), "460020db class.s f3, f4");
+ COMPARE(class_d(f2, f3), "4620189b class.d f2, f3");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(C_FMT_DISASM) {
+ if (IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)) {
+ SET_UP();
+
+ COMPARE(c_s(F, f8, f10, 0), "460a4030 c.f.s f8, f10, cc(0)");
+ COMPARE(c_d(F, f8, f10, 0), "462a4030 c.f.d f8, f10, cc(0)");
+
+ COMPARE(c_s(UN, f8, f10, 2), "460a4231 c.un.s f8, f10, cc(2)");
+ COMPARE(c_d(UN, f8, f10, 2), "462a4231 c.un.d f8, f10, cc(2)");
+
+ COMPARE(c_s(EQ, f8, f10, 4), "460a4432 c.eq.s f8, f10, cc(4)");
+ COMPARE(c_d(EQ, f8, f10, 4), "462a4432 c.eq.d f8, f10, cc(4)");
+
+ COMPARE(c_s(UEQ, f8, f10, 6), "460a4633 c.ueq.s f8, f10, cc(6)");
+ COMPARE(c_d(UEQ, f8, f10, 6), "462a4633 c.ueq.d f8, f10, cc(6)");
+
+ COMPARE(c_s(OLT, f8, f10, 0), "460a4034 c.olt.s f8, f10, cc(0)");
+ COMPARE(c_d(OLT, f8, f10, 0), "462a4034 c.olt.d f8, f10, cc(0)");
+
+ COMPARE(c_s(ULT, f8, f10, 2), "460a4235 c.ult.s f8, f10, cc(2)");
+ COMPARE(c_d(ULT, f8, f10, 2), "462a4235 c.ult.d f8, f10, cc(2)");
+
+ COMPARE(c_s(OLE, f8, f10, 4), "460a4436 c.ole.s f8, f10, cc(4)");
+ COMPARE(c_d(OLE, f8, f10, 4), "462a4436 c.ole.d f8, f10, cc(4)");
+
+ COMPARE(c_s(ULE, f8, f10, 6), "460a4637 c.ule.s f8, f10, cc(6)");
+ COMPARE(c_d(ULE, f8, f10, 6), "462a4637 c.ule.d f8, f10, cc(6)");
VERIFY_RUN();
}
}
+
+
+TEST(COND_FMT_DISASM) {
+ if (IsMipsArchVariant(kMips32r6)) {
+ SET_UP();
+
+ COMPARE(cmp_s(F, f6, f8, f10), "468a4180 cmp.af.s f6, f8, f10");
+ COMPARE(cmp_d(F, f6, f8, f10), "46aa4180 cmp.af.d f6, f8, f10");
+
+ COMPARE(cmp_s(UN, f6, f8, f10), "468a4181 cmp.un.s f6, f8, f10");
+ COMPARE(cmp_d(UN, f6, f8, f10), "46aa4181 cmp.un.d f6, f8, f10");
+
+ COMPARE(cmp_s(EQ, f6, f8, f10), "468a4182 cmp.eq.s f6, f8, f10");
+ COMPARE(cmp_d(EQ, f6, f8, f10), "46aa4182 cmp.eq.d f6, f8, f10");
+
+ COMPARE(cmp_s(UEQ, f6, f8, f10), "468a4183 cmp.ueq.s f6, f8, f10");
+ COMPARE(cmp_d(UEQ, f6, f8, f10), "46aa4183 cmp.ueq.d f6, f8, f10");
+
+ COMPARE(cmp_s(LT, f6, f8, f10), "468a4184 cmp.lt.s f6, f8, f10");
+ COMPARE(cmp_d(LT, f6, f8, f10), "46aa4184 cmp.lt.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULT, f6, f8, f10), "468a4185 cmp.ult.s f6, f8, f10");
+ COMPARE(cmp_d(ULT, f6, f8, f10), "46aa4185 cmp.ult.d f6, f8, f10");
+
+ COMPARE(cmp_s(LE, f6, f8, f10), "468a4186 cmp.le.s f6, f8, f10");
+ COMPARE(cmp_d(LE, f6, f8, f10), "46aa4186 cmp.le.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULE, f6, f8, f10), "468a4187 cmp.ule.s f6, f8, f10");
+ COMPARE(cmp_d(ULE, f6, f8, f10), "46aa4187 cmp.ule.d f6, f8, f10");
+
+ COMPARE(cmp_s(ORD, f6, f8, f10), "468a4191 cmp.or.s f6, f8, f10");
+ COMPARE(cmp_d(ORD, f6, f8, f10), "46aa4191 cmp.or.d f6, f8, f10");
+
+ COMPARE(cmp_s(UNE, f6, f8, f10), "468a4192 cmp.une.s f6, f8, f10");
+ COMPARE(cmp_d(UNE, f6, f8, f10), "46aa4192 cmp.une.d f6, f8, f10");
+
+ COMPARE(cmp_s(NE, f6, f8, f10), "468a4193 cmp.ne.s f6, f8, f10");
+ COMPARE(cmp_d(NE, f6, f8, f10), "46aa4193 cmp.ne.d f6, f8, f10");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(CVT_DISSASM) {
+ SET_UP();
+ COMPARE(cvt_d_s(f22, f24), "4600c5a1 cvt.d.s f22, f24");
+ COMPARE(cvt_d_w(f22, f24), "4680c5a1 cvt.d.w f22, f24");
+ if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) {
+ COMPARE(cvt_d_l(f22, f24), "46a0c5a1 cvt.d.l f22, f24");
+ }
+
+ if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) {
+ COMPARE(cvt_l_s(f22, f24), "4600c5a5 cvt.l.s f22, f24");
+ COMPARE(cvt_l_d(f22, f24), "4620c5a5 cvt.l.d f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+ if (IsMipsArchVariant(kMips32r6) || IsMipsArchVariant(kMips32r2)) {
+ COMPARE(cvt_s_l(f22, f24), "46a0c5a0 cvt.s.l f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+
+ VERIFY_RUN();
+}
diff --git a/deps/v8/test/cctest/test-disasm-mips64.cc b/deps/v8/test/cctest/test-disasm-mips64.cc
index 492265b2e7..225a1e7f0b 100644
--- a/deps/v8/test/cctest/test-disasm-mips64.cc
+++ b/deps/v8/test/cctest/test-disasm-mips64.cc
@@ -92,6 +92,45 @@ if (failure) { \
}
+#define COMPARE_PC_REL_COMPACT(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + 4 + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_REL(asm_, compare_string, offset) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, progcounter + (offset << 2)); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
+#define COMPARE_PC_JUMP(asm_, compare_string, target) \
+ { \
+ int pc_offset = assm.pc_offset(); \
+ byte *progcounter = &buffer[pc_offset]; \
+ char str_with_address[100]; \
+ int instr_index = target >> 2; \
+ snprintf(str_with_address, sizeof(str_with_address), "%s -> %p", \
+ compare_string, reinterpret_cast<byte *>( \
+ ((uint64_t)(progcounter + 1) & ~0xfffffff) | \
+ (instr_index << 2))); \
+ assm.asm_; \
+ if (!DisassembleAndCompare(progcounter, str_with_address)) failure = true; \
+ }
+
+
TEST(Type0) {
SET_UP();
@@ -279,38 +318,6 @@ TEST(Type0) {
"0064109f ddivu v0, v1, a0");
COMPARE(dmodu(v0, v1, a0),
"006410df dmodu v0, v1, a0");
-
- COMPARE(bovc(a0, a0, static_cast<int16_t>(0)),
- "20840000 bovc a0, a0, 0");
- COMPARE(bovc(a1, a0, static_cast<int16_t>(0)),
- "20a40000 bovc a1, a0, 0");
- COMPARE(bovc(a1, a0, 32767),
- "20a47fff bovc a1, a0, 32767");
- COMPARE(bovc(a1, a0, -32768),
- "20a48000 bovc a1, a0, -32768");
-
- COMPARE(bnvc(a0, a0, static_cast<int16_t>(0)),
- "60840000 bnvc a0, a0, 0");
- COMPARE(bnvc(a1, a0, static_cast<int16_t>(0)),
- "60a40000 bnvc a1, a0, 0");
- COMPARE(bnvc(a1, a0, 32767),
- "60a47fff bnvc a1, a0, 32767");
- COMPARE(bnvc(a1, a0, -32768),
- "60a48000 bnvc a1, a0, -32768");
-
- COMPARE(beqzc(a0, 0),
- "d8800000 beqzc a0, 0x0");
- COMPARE(beqzc(a0, 0xfffff), // 0x0fffff == 1048575.
- "d88fffff beqzc a0, 0xfffff");
- COMPARE(beqzc(a0, 0x100000), // 0x100000 == -1048576.
- "d8900000 beqzc a0, 0x100000");
-
- COMPARE(bnezc(a0, 0),
- "f8800000 bnezc a0, 0x0");
- COMPARE(bnezc(a0, 0xfffff), // 0x0fffff == 1048575.
- "f88fffff bnezc a0, 0xfffff");
- COMPARE(bnezc(a0, 0x100000), // 0x100000 == -1048576.
- "f8900000 bnezc a0, 0x100000");
}
COMPARE(addiu(a0, a1, 0x0),
@@ -669,23 +676,551 @@ TEST(Type0) {
COMPARE(ext_(v0, v1, 0, 32),
"7c62f800 ext v0, v1, 0, 32");
+ COMPARE(add_s(f4, f6, f8), "46083100 add.s f4, f6, f8");
+ COMPARE(add_d(f12, f14, f16), "46307300 add.d f12, f14, f16");
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(bitswap(a0, a1), "7c052020 bitswap a0, a1");
+ COMPARE(bitswap(t8, s0), "7c10c020 bitswap t8, s0");
+ COMPARE(dbitswap(a0, a1), "7c052024 dbitswap a0, a1");
+ COMPARE(dbitswap(t8, s0), "7c10c024 dbitswap t8, s0");
+ }
+
+ COMPARE(abs_s(f6, f8), "46004185 abs.s f6, f8");
+ COMPARE(abs_d(f10, f12), "46206285 abs.d f10, f12");
+
+ COMPARE(div_s(f2, f4, f6), "46062083 div.s f2, f4, f6");
+ COMPARE(div_d(f2, f4, f6), "46262083 div.d f2, f4, f6");
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(align(v0, a0, a1, 0), "7c851220 align v0, a0, a1, 0");
+ COMPARE(align(v0, a0, a1, 1), "7c851260 align v0, a0, a1, 1");
+ COMPARE(align(v0, a0, a1, 2), "7c8512a0 align v0, a0, a1, 2");
+ COMPARE(align(v0, a0, a1, 3), "7c8512e0 align v0, a0, a1, 3");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(dalign(v0, a0, a1, 0), "7c851224 dalign v0, a0, a1, 0");
+ COMPARE(dalign(v0, a0, a1, 1), "7c851264 dalign v0, a0, a1, 1");
+ COMPARE(dalign(v0, a0, a1, 2), "7c8512a4 dalign v0, a0, a1, 2");
+ COMPARE(dalign(v0, a0, a1, 3), "7c8512e4 dalign v0, a0, a1, 3");
+ COMPARE(dalign(v0, a0, a1, 4), "7c851324 dalign v0, a0, a1, 4");
+ COMPARE(dalign(v0, a0, a1, 5), "7c851364 dalign v0, a0, a1, 5");
+ COMPARE(dalign(v0, a0, a1, 6), "7c8513a4 dalign v0, a0, a1, 6");
+ COMPARE(dalign(v0, a0, a1, 7), "7c8513e4 dalign v0, a0, a1, 7");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(aluipc(v0, 0), "ec5f0000 aluipc v0, 0");
+ COMPARE(aluipc(v0, 1), "ec5f0001 aluipc v0, 1");
+ COMPARE(aluipc(v0, 32767), "ec5f7fff aluipc v0, 32767");
+ COMPARE(aluipc(v0, -32768), "ec5f8000 aluipc v0, -32768");
+ COMPARE(aluipc(v0, -1), "ec5fffff aluipc v0, -1");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(auipc(t8, 0), "ef1e0000 auipc t8, 0");
+ COMPARE(auipc(t8, 1), "ef1e0001 auipc t8, 1");
+ COMPARE(auipc(t8, 32767), "ef1e7fff auipc t8, 32767");
+ COMPARE(auipc(t8, -32768), "ef1e8000 auipc t8, -32768");
+ COMPARE(auipc(t8, -1), "ef1effff auipc t8, -1");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(lwpc(a5, 0), "ed280000 lwpc a5, 0");
+ COMPARE(lwpc(a5, 4), "ed280004 lwpc a5, 4");
+ COMPARE(lwpc(a5, -4), "ed2ffffc lwpc a5, -4");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(lwupc(a0, -262144), "ec940000 lwupc a0, -262144");
+ COMPARE(lwupc(a0, -1), "ec97ffff lwupc a0, -1");
+ COMPARE(lwupc(a0, 0), "ec900000 lwupc a0, 0");
+ COMPARE(lwupc(a0, 1), "ec900001 lwupc a0, 1");
+ COMPARE(lwupc(a0, 262143), "ec93ffff lwupc a0, 262143");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(jic(t0, 16), "d80c0010 jic t0, 16");
+ COMPARE(jic(t0, 4), "d80c0004 jic t0, 4");
+ COMPARE(jic(t0, -32), "d80cffe0 jic t0, -32");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 16), "d8800010 beqzc a0, 0x10",
+ 16);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 4), "d8800004 beqzc a0, 0x4", 4);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, -32),
+ "d89fffe0 beqzc a0, 0x1fffe0", -32);
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(ldpc(v0, 256), "ec580100 ldpc v0, 256");
+ COMPARE(ldpc(a0, -1), "ec9bffff ldpc a0, -1");
+ COMPARE(ldpc(a1, 0), "ecb80000 ldpc a1, 0");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(addiupc(a0, 262143), "ec83ffff addiupc a0, 262143");
+ COMPARE(addiupc(a0, -1), "ec87ffff addiupc a0, -1");
+ COMPARE(addiupc(v0, 0), "ec400000 addiupc v0, 0");
+ COMPARE(addiupc(s1, 1), "ee200001 addiupc s1, 1");
+ COMPARE(addiupc(a0, -262144), "ec840000 addiupc a0, -262144");
+ }
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE(jialc(a0, -32768), "f8048000 jialc a0, 0x8000");
+ COMPARE(jialc(a0, -1), "f804ffff jialc a0, 0xffff");
+ COMPARE(jialc(v0, 0), "f8020000 jialc v0, 0x0");
+ COMPARE(jialc(s1, 1), "f8110001 jialc s1, 0x1");
+ COMPARE(jialc(a0, 32767), "f8047fff jialc a0, 0x7fff");
+ }
+
VERIFY_RUN();
}
TEST(Type1) {
+ SET_UP();
if (kArchVariant == kMips64r6) {
- SET_UP();
COMPARE(seleqz(a0, a1, a2), "00a62035 seleqz a0, a1, a2");
COMPARE(selnez(a0, a1, a2), "00a62037 selnez a0, a1, a2");
COMPARE(seleqz(D, f3, f4, f5), "462520d4 seleqz.d f3, f4, f5");
COMPARE(selnez(D, f3, f4, f5), "462520d7 selnez.d f3, f4, f5");
+ COMPARE(seleqz(S, f3, f4, f5), "460520d4 seleqz.s f3, f4, f5");
+ COMPARE(selnez(S, f3, f4, f5), "460520d7 selnez.s f3, f4, f5");
COMPARE(min_d(f3, f4, f5), "462520dc min.d f3, f4, f5");
COMPARE(max_d(f3, f4, f5), "462520de max.d f3, f4, f5");
+
+ COMPARE(sel(S, f3, f4, f5), "460520d0 sel.s f3, f4, f5");
+ COMPARE(sel(D, f3, f4, f5), "462520d0 sel.d f3, f4, f5");
+
COMPARE(rint_d(f8, f6), "4620321a rint.d f8, f6");
+
+ COMPARE(min_s(f3, f4, f5), "460520dc min.s f3, f4, f5");
+ COMPARE(max_s(f3, f4, f5), "460520de max.s f3, f4, f5");
+
+ COMPARE(rint(S, f8, f6), "4600321a rint.s f8, f6");
+
+ COMPARE(mina_d(f3, f4, f5), "462520dd mina.d f3, f4, f5");
+ COMPARE(mina_s(f3, f4, f5), "460520dd mina.s f3, f4, f5");
+
+ COMPARE(maxa_d(f3, f4, f5), "462520df maxa.d f3, f4, f5");
+ COMPARE(maxa_s(f3, f4, f5), "460520df maxa.s f3, f4, f5");
+ }
+ COMPARE(trunc_w_d(f8, f6), "4620320d trunc.w.d f8, f6");
+ COMPARE(trunc_w_s(f8, f6), "4600320d trunc.w.s f8, f6");
+
+ COMPARE(round_w_s(f8, f6), "4600320c round.w.s f8, f6");
+ COMPARE(round_w_d(f8, f6), "4620320c round.w.d f8, f6");
+
+ COMPARE(round_l_s(f8, f6), "46003208 round.l.s f8, f6");
+ COMPARE(round_l_d(f8, f6), "46203208 round.l.d f8, f6");
+
+ COMPARE(floor_w_s(f8, f6), "4600320f floor.w.s f8, f6");
+ COMPARE(floor_w_d(f8, f6), "4620320f floor.w.d f8, f6");
+
+ COMPARE(floor_l_s(f8, f6), "4600320b floor.l.s f8, f6");
+ COMPARE(floor_l_d(f8, f6), "4620320b floor.l.d f8, f6");
+
+ COMPARE(ceil_w_s(f8, f6), "4600320e ceil.w.s f8, f6");
+ COMPARE(ceil_w_d(f8, f6), "4620320e ceil.w.d f8, f6");
+
+ COMPARE(ceil_l_s(f8, f6), "4600320a ceil.l.s f8, f6");
+ COMPARE(ceil_l_d(f8, f6), "4620320a ceil.l.d f8, f6");
+
+ COMPARE(sub_s(f10, f8, f6), "46064281 sub.s f10, f8, f6");
+ COMPARE(sub_d(f10, f8, f6), "46264281 sub.d f10, f8, f6");
+
+ COMPARE(sqrt_s(f8, f6), "46003204 sqrt.s f8, f6");
+ COMPARE(sqrt_d(f8, f6), "46203204 sqrt.d f8, f6");
+
+ COMPARE(neg_s(f8, f6), "46003207 neg.s f8, f6");
+ COMPARE(neg_d(f8, f6), "46203207 neg.d f8, f6");
+
+ COMPARE(mul_s(f8, f6, f4), "46043202 mul.s f8, f6, f4");
+ COMPARE(mul_d(f8, f6, f4), "46243202 mul.d f8, f6, f4");
+
+ COMPARE(rsqrt_s(f8, f6), "46003216 rsqrt.s f8, f6");
+ COMPARE(rsqrt_d(f8, f6), "46203216 rsqrt.d f8, f6");
+
+ COMPARE(recip_s(f8, f6), "46003215 recip.s f8, f6");
+ COMPARE(recip_d(f8, f6), "46203215 recip.d f8, f6");
+
+ COMPARE(mov_s(f6, f4), "46002186 mov.s f6, f4");
+ COMPARE(mov_d(f6, f4), "46202186 mov.d f6, f4");
+ if (kArchVariant == kMips64r2) {
+ COMPARE(trunc_l_d(f8, f6), "46203209 trunc.l.d f8, f6");
+ COMPARE(trunc_l_s(f8, f6), "46003209 trunc.l.s f8, f6");
+
+ COMPARE(movz_s(f6, f4, t0), "460c2192 movz.s f6, f4, t0");
+ COMPARE(movz_d(f6, f4, t0), "462c2192 movz.d f6, f4, t0");
+
+ COMPARE(movt_s(f6, f4, 4), "46112191 movt.s f6, f4, cc(1)");
+ COMPARE(movt_d(f6, f4, 4), "46312191 movt.d f6, f4, cc(1)");
+
+ COMPARE(movf_s(f6, f4, 4), "46102191 movf.s f6, f4, cc(1)");
+ COMPARE(movf_d(f6, f4, 4), "46302191 movf.d f6, f4, cc(1)");
+
+ COMPARE(movn_s(f6, f4, t0), "460c2193 movn.s f6, f4, t0");
+ COMPARE(movn_d(f6, f4, t0), "462c2193 movn.d f6, f4, t0");
+ }
+ VERIFY_RUN();
+}
+
+
+TEST(Type2) {
+ if (kArchVariant == kMips64r6) {
+ SET_UP();
+
+ COMPARE(class_s(f3, f4), "460020db class.s f3, f4");
+ COMPARE(class_d(f2, f3), "4620189b class.d f2, f3");
+
VERIFY_RUN();
}
}
+
+
+TEST(Type3) {
+ SET_UP();
+
+ if (kArchVariant == kMips64r6) {
+ COMPARE_PC_REL_COMPACT(bovc(a0, a0, static_cast<int16_t>(0)),
+ "20840000 bovc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, static_cast<int16_t>(0)),
+ "20a40000 bovc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, 32767),
+ "20a47fff bovc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -32768),
+ "20a48000 bovc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(bnvc(a0, a0, static_cast<int16_t>(0)),
+ "60840000 bnvc a0, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, static_cast<int16_t>(0)),
+ "60a40000 bnvc a1, a0, 0", 0);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, 32767),
+ "60a47fff bnvc a1, a0, 32767", 32767);
+ COMPARE_PC_REL_COMPACT(bnvc(a1, a0, -32768),
+ "60a48000 bnvc a1, a0, -32768", -32768);
+
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0), "d8800000 beqzc a0, 0x0", 0);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "d88fffff beqzc a0, 0xfffff", 1048575);
+ COMPARE_PC_REL_COMPACT(beqzc(a0, 0x100000), // 0x100000 == -1048576.
+ "d8900000 beqzc a0, 0x100000", -1048576);
+
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0), "f8800000 bnezc a0, 0x0", 0);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0xfffff), // 0x0fffff == 1048575.
+ "f88fffff bnezc a0, 0xfffff", 1048575);
+ COMPARE_PC_REL_COMPACT(bnezc(a0, 0x100000), // 0x100000 == -1048576.
+ "f8900000 bnezc a0, 0x100000", -1048576);
+
+ COMPARE_PC_REL_COMPACT(bc(-33554432), "ca000000 bc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(bc(-1), "cbffffff bc -1", -1);
+ COMPARE_PC_REL_COMPACT(bc(0), "c8000000 bc 0", 0);
+ COMPARE_PC_REL_COMPACT(bc(1), "c8000001 bc 1", 1);
+ COMPARE_PC_REL_COMPACT(bc(33554431), "c9ffffff bc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(balc(-33554432), "ea000000 balc -33554432",
+ -33554432);
+ COMPARE_PC_REL_COMPACT(balc(-1), "ebffffff balc -1", -1);
+ COMPARE_PC_REL_COMPACT(balc(0), "e8000000 balc 0", 0);
+ COMPARE_PC_REL_COMPACT(balc(1), "e8000001 balc 1", 1);
+ COMPARE_PC_REL_COMPACT(balc(33554431), "e9ffffff balc 33554431",
+ 33554431);
+
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -32768),
+ "18858000 bgeuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, -1),
+ "1885ffff bgeuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 1),
+ "18850001 bgeuc a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgeuc(a0, a1, 32767),
+ "18857fff bgeuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -32768),
+ "18848000 bgezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, -1), "1884ffff bgezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 1), "18840001 bgezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezalc(a0, 32767),
+ "18847fff bgezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -32768),
+ "18048000 blezalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, -1), "1804ffff blezalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 1), "18040001 blezalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezalc(a0, 32767),
+ "18047fff blezalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -32768),
+ "1c858000 bltuc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, -1),
+ "1c85ffff bltuc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 1), "1c850001 bltuc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltuc(a0, a1, 32767),
+ "1c857fff bltuc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -32768),
+ "1c848000 bltzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, -1), "1c84ffff bltzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 1), "1c840001 bltzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzalc(a0, 32767),
+ "1c847fff bltzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -32768),
+ "1c048000 bgtzalc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, -1), "1c04ffff bgtzalc a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 1), "1c040001 bgtzalc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzalc(a0, 32767),
+ "1c047fff bgtzalc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -32768),
+ "58848000 bgezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, -1), "5884ffff bgezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 1), "58840001 bgezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgezc(a0, 32767),
+ "58847fff bgezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -32768),
+ "58858000 bgec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, -1),
+ "5885ffff bgec a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 1), "58850001 bgec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bgec(a0, a1, 32767),
+ "58857fff bgec a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(blezc(a0, -32768),
+ "58048000 blezc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(blezc(a0, -1), "5804ffff blezc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 1), "58040001 blezc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blezc(a0, 32767),
+ "58047fff blezc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -32768),
+ "5c848000 bltzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, -1), "5c84ffff bltzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 1), "5c840001 bltzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltzc(a0, 32767),
+ "5c847fff bltzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -32768),
+ "5c858000 bltc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, -1),
+ "5c85ffff bltc a0, a1, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 1), "5c850001 bltc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bltc(a0, a1, 32767),
+ "5c857fff bltc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -32768),
+ "5c048000 bgtzc a0, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, -1), "5c04ffff bgtzc a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 1), "5c040001 bgtzc a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtzc(a0, 32767),
+ "5c047fff bgtzc a0, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1eqz(-32768, f1),
+ "45218000 bc1eqz f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1eqz(-1, f1), "4521ffff bc1eqz f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(1, f1), "45210001 bc1eqz f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1eqz(32767, f1),
+ "45217fff bc1eqz f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bc1nez(-32768, f1),
+ "45a18000 bc1nez f1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bc1nez(-1, f1), "45a1ffff bc1nez f1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bc1nez(1, f1), "45a10001 bc1nez f1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bc1nez(32767, f1),
+ "45a17fff bc1nez f1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bovc(a1, a0, -1), "20a4ffff bovc a1, a0, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bovc(a0, a0, 1), "20840001 bovc a0, a0, 1",
+ 1);
+
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -32768),
+ "20858000 beqc a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, -1), "2085ffff beqc a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 1), "20850001 beqc a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(beqc(a0, a1, 32767),
+ "20857fff beqc a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -32768),
+ "60858000 bnec a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, -1), "6085ffff bnec a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 1), "60850001 bnec a0, a1, 1",
+ 1);
+ COMPARE_PC_REL_COMPACT(bnec(a0, a1, 32767),
+ "60857fff bnec a0, a1, 32767", 32767);
+ }
+
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -32768),
+ "14858000 bne a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, -1), "1485ffff bne a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 1), "14850001 bne a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(bne(a0, a1, 32767),
+ "14857fff bne a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -32768),
+ "10858000 beq a0, a1, -32768", -32768);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, -1), "1085ffff beq a0, a1, -1",
+ -1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 1), "10850001 beq a0, a1, 1", 1);
+ COMPARE_PC_REL_COMPACT(beq(a0, a1, 32767),
+ "10857fff beq a0, a1, 32767", 32767);
+
+ COMPARE_PC_REL_COMPACT(bltz(a0, -32768), "04808000 bltz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bltz(a0, -1), "0480ffff bltz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 1), "04800001 bltz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bltz(a0, 32767), "04807fff bltz a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgez(a0, -32768), "04818000 bgez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgez(a0, -1), "0481ffff bgez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 1), "04810001 bgez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgez(a0, 32767), "04817fff bgez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(blez(a0, -32768), "18808000 blez a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(blez(a0, -1), "1880ffff blez a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 1), "18800001 blez a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(blez(a0, 32767), "18807fff blez a0, 32767",
+ 32767);
+
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -32768), "1c808000 bgtz a0, -32768",
+ -32768);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, -1), "1c80ffff bgtz a0, -1", -1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 1), "1c800001 bgtz a0, 1", 1);
+ COMPARE_PC_REL_COMPACT(bgtz(a0, 32767), "1c807fff bgtz a0, 32767",
+ 32767);
+
+ COMPARE_PC_JUMP(j(0x4), "08000001 j 0x4", 0x4);
+ COMPARE_PC_JUMP(j(0xffffffc), "0bffffff j 0xffffffc", 0xffffffc);
+
+ COMPARE_PC_JUMP(jal(0x4), "0c000001 jal 0x4", 0x4);
+ COMPARE_PC_JUMP(jal(0xffffffc), "0fffffff jal 0xffffffc",
+ 0xffffffc);
+
+ VERIFY_RUN();
+}
+
+
+TEST(C_FMT_DISASM) {
+ if (kArchVariant == kMips64r2) {
+ SET_UP();
+
+ COMPARE(c_s(F, f8, f10, 0), "460a4030 c.f.s f8, f10, cc(0)");
+ COMPARE(c_d(F, f8, f10, 0), "462a4030 c.f.d f8, f10, cc(0)");
+
+ COMPARE(c_s(UN, f8, f10, 2), "460a4231 c.un.s f8, f10, cc(2)");
+ COMPARE(c_d(UN, f8, f10, 2), "462a4231 c.un.d f8, f10, cc(2)");
+
+ COMPARE(c_s(EQ, f8, f10, 4), "460a4432 c.eq.s f8, f10, cc(4)");
+ COMPARE(c_d(EQ, f8, f10, 4), "462a4432 c.eq.d f8, f10, cc(4)");
+
+ COMPARE(c_s(UEQ, f8, f10, 6), "460a4633 c.ueq.s f8, f10, cc(6)");
+ COMPARE(c_d(UEQ, f8, f10, 6), "462a4633 c.ueq.d f8, f10, cc(6)");
+
+ COMPARE(c_s(OLT, f8, f10, 0), "460a4034 c.olt.s f8, f10, cc(0)");
+ COMPARE(c_d(OLT, f8, f10, 0), "462a4034 c.olt.d f8, f10, cc(0)");
+
+ COMPARE(c_s(ULT, f8, f10, 2), "460a4235 c.ult.s f8, f10, cc(2)");
+ COMPARE(c_d(ULT, f8, f10, 2), "462a4235 c.ult.d f8, f10, cc(2)");
+
+ COMPARE(c_s(OLE, f8, f10, 4), "460a4436 c.ole.s f8, f10, cc(4)");
+ COMPARE(c_d(OLE, f8, f10, 4), "462a4436 c.ole.d f8, f10, cc(4)");
+
+ COMPARE(c_s(ULE, f8, f10, 6), "460a4637 c.ule.s f8, f10, cc(6)");
+ COMPARE(c_d(ULE, f8, f10, 6), "462a4637 c.ule.d f8, f10, cc(6)");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(COND_FMT_DISASM) {
+ if (kArchVariant == kMips64r6) {
+ SET_UP();
+
+ COMPARE(cmp_s(F, f6, f8, f10), "468a4180 cmp.af.s f6, f8, f10");
+ COMPARE(cmp_d(F, f6, f8, f10), "46aa4180 cmp.af.d f6, f8, f10");
+
+ COMPARE(cmp_s(UN, f6, f8, f10), "468a4181 cmp.un.s f6, f8, f10");
+ COMPARE(cmp_d(UN, f6, f8, f10), "46aa4181 cmp.un.d f6, f8, f10");
+
+ COMPARE(cmp_s(EQ, f6, f8, f10), "468a4182 cmp.eq.s f6, f8, f10");
+ COMPARE(cmp_d(EQ, f6, f8, f10), "46aa4182 cmp.eq.d f6, f8, f10");
+
+ COMPARE(cmp_s(UEQ, f6, f8, f10), "468a4183 cmp.ueq.s f6, f8, f10");
+ COMPARE(cmp_d(UEQ, f6, f8, f10), "46aa4183 cmp.ueq.d f6, f8, f10");
+
+ COMPARE(cmp_s(LT, f6, f8, f10), "468a4184 cmp.lt.s f6, f8, f10");
+ COMPARE(cmp_d(LT, f6, f8, f10), "46aa4184 cmp.lt.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULT, f6, f8, f10), "468a4185 cmp.ult.s f6, f8, f10");
+ COMPARE(cmp_d(ULT, f6, f8, f10), "46aa4185 cmp.ult.d f6, f8, f10");
+
+ COMPARE(cmp_s(LE, f6, f8, f10), "468a4186 cmp.le.s f6, f8, f10");
+ COMPARE(cmp_d(LE, f6, f8, f10), "46aa4186 cmp.le.d f6, f8, f10");
+
+ COMPARE(cmp_s(ULE, f6, f8, f10), "468a4187 cmp.ule.s f6, f8, f10");
+ COMPARE(cmp_d(ULE, f6, f8, f10), "46aa4187 cmp.ule.d f6, f8, f10");
+
+ COMPARE(cmp_s(ORD, f6, f8, f10), "468a4191 cmp.or.s f6, f8, f10");
+ COMPARE(cmp_d(ORD, f6, f8, f10), "46aa4191 cmp.or.d f6, f8, f10");
+
+ COMPARE(cmp_s(UNE, f6, f8, f10), "468a4192 cmp.une.s f6, f8, f10");
+ COMPARE(cmp_d(UNE, f6, f8, f10), "46aa4192 cmp.une.d f6, f8, f10");
+
+ COMPARE(cmp_s(NE, f6, f8, f10), "468a4193 cmp.ne.s f6, f8, f10");
+ COMPARE(cmp_d(NE, f6, f8, f10), "46aa4193 cmp.ne.d f6, f8, f10");
+
+ VERIFY_RUN();
+ }
+}
+
+
+TEST(CVT_DISSASM) {
+ SET_UP();
+ COMPARE(cvt_d_s(f22, f24), "4600c5a1 cvt.d.s f22, f24");
+ COMPARE(cvt_d_w(f22, f24), "4680c5a1 cvt.d.w f22, f24");
+ if (kArchVariant == kMips64r6 || kArchVariant == kMips64r2) {
+ COMPARE(cvt_d_l(f22, f24), "46a0c5a1 cvt.d.l f22, f24");
+ }
+
+ if (kArchVariant == kMips64r6 || kArchVariant == kMips64r2) {
+ COMPARE(cvt_l_s(f22, f24), "4600c5a5 cvt.l.s f22, f24");
+ COMPARE(cvt_l_d(f22, f24), "4620c5a5 cvt.l.d f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+ if (kArchVariant == kMips64r6 || kArchVariant == kMips64r2) {
+ COMPARE(cvt_s_l(f22, f24), "46a0c5a0 cvt.s.l f22, f24");
+ }
+
+ COMPARE(cvt_s_d(f22, f24), "4620c5a0 cvt.s.d f22, f24");
+ COMPARE(cvt_s_w(f22, f24), "4680c5a0 cvt.s.w f22, f24");
+
+ VERIFY_RUN();
+}
diff --git a/deps/v8/test/cctest/test-extra.js b/deps/v8/test/cctest/test-extra.js
new file mode 100644
index 0000000000..829ddee01a
--- /dev/null
+++ b/deps/v8/test/cctest/test-extra.js
@@ -0,0 +1,14 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function (global, exports) {
+ 'use strict';
+ exports.testExtraShouldReturnFive = function () {
+ return 5;
+ };
+
+ exports.testExtraShouldCallToRuntime = function() {
+ return exports.runtime(3);
+ };
+})
diff --git a/deps/v8/test/cctest/test-feedback-vector.cc b/deps/v8/test/cctest/test-feedback-vector.cc
index e94de7b552..cf8a730fb7 100644
--- a/deps/v8/test/cctest/test-feedback-vector.cc
+++ b/deps/v8/test/cctest/test-feedback-vector.cc
@@ -46,19 +46,13 @@ TEST(VectorStructure) {
CHECK_EQ(1, vector->ICSlots());
ZoneFeedbackVectorSpec spec(zone, 3, 5);
- if (FLAG_vector_ics) {
- for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
- }
+ for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
vector = factory->NewTypeFeedbackVector(&spec);
CHECK_EQ(3, vector->Slots());
CHECK_EQ(5, vector->ICSlots());
int metadata_length = vector->ic_metadata_length();
- if (!FLAG_vector_ics) {
- CHECK_EQ(0, metadata_length);
- } else {
- CHECK(metadata_length > 0);
- }
+ CHECK(metadata_length > 0);
int index = vector->GetIndex(FeedbackVectorSlot(0));
@@ -79,11 +73,6 @@ TEST(VectorStructure) {
TEST(VectorICMetadata) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
- if (!FLAG_vector_ics) {
- // If FLAG_vector_ics is false, we only store CALL_ICs in the vector, so
- // there is no need for metadata to describe the slots.
- return;
- }
Isolate* isolate = CcTest::i_isolate();
Factory* factory = isolate->factory();
Zone* zone = isolate->runtime_zone();
@@ -259,7 +248,7 @@ TEST(VectorCallICStates) {
TEST(VectorLoadICStates) {
- if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
+ if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
@@ -313,7 +302,7 @@ TEST(VectorLoadICStates) {
TEST(VectorLoadICSlotSharing) {
- if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
+ if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
@@ -322,7 +311,7 @@ TEST(VectorLoadICSlotSharing) {
// Function f has 3 LoadICs, one for each o, but the ICs share the same
// feedback vector IC slot.
CompileRun(
- "var o = 10;"
+ "o = 10;"
"function f() {"
" var x = o + 10;"
" return o + x + o;"
@@ -341,7 +330,7 @@ TEST(VectorLoadICSlotSharing) {
TEST(VectorLoadICOnSmi) {
- if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
+ if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
diff --git a/deps/v8/test/cctest/test-fuzz-arm64.cc b/deps/v8/test/cctest/test-fuzz-arm64.cc
index ada609fe78..8f6651a6a9 100644
--- a/deps/v8/test/cctest/test-fuzz-arm64.cc
+++ b/deps/v8/test/cctest/test-fuzz-arm64.cc
@@ -43,7 +43,7 @@ TEST(FUZZ_decoder) {
Instruction buffer[kInstructionSize];
for (int i = 0; i < instruction_count; i++) {
- uint32_t instr = mrand48();
+ uint32_t instr = static_cast<uint32_t>(mrand48());
buffer->SetInstructionBits(instr);
decoder.Decode(buffer);
}
@@ -64,7 +64,7 @@ TEST(FUZZ_disasm) {
decoder.AppendVisitor(&disasm);
for (int i = 0; i < instruction_count; i++) {
- uint32_t instr = mrand48();
+ uint32_t instr = static_cast<uint32_t>(mrand48());
buffer->SetInstructionBits(instr);
decoder.Decode(buffer);
}
diff --git a/deps/v8/test/cctest/test-global-object.cc b/deps/v8/test/cctest/test-global-object.cc
index b0ed29daf1..9cc755e4e1 100644
--- a/deps/v8/test/cctest/test-global-object.cc
+++ b/deps/v8/test/cctest/test-global-object.cc
@@ -29,15 +29,13 @@
#include "test/cctest/cctest.h"
-using namespace v8;
-
// This test fails if properties on the prototype of the global object appear
// as declared globals.
TEST(StrictUndeclaredGlobalVariable) {
- HandleScope scope(CcTest::isolate());
+ v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::String> var_name = v8_str("x");
LocalContext context;
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
v8::Local<v8::Script> script = v8_compile("\"use strict\"; x = 42;");
v8::Handle<v8::Object> proto = v8::Object::New(CcTest::isolate());
v8::Handle<v8::Object> global =
diff --git a/deps/v8/test/cctest/test-hashing.cc b/deps/v8/test/cctest/test-hashing.cc
index c8ae4f30e5..9e5de2e05a 100644
--- a/deps/v8/test/cctest/test-hashing.cc
+++ b/deps/v8/test/cctest/test-hashing.cc
@@ -131,7 +131,7 @@ void check(uint32_t key) {
#endif
uint32_t runtime_hash = ComputeIntegerHash(key, isolate->heap()->HashSeed());
- CHECK(runtime_hash == codegen_hash);
+ CHECK_EQ(runtime_hash, codegen_hash);
}
diff --git a/deps/v8/test/cctest/test-hashmap.cc b/deps/v8/test/cctest/test-hashmap.cc
index fb56225fb4..b45d6c7183 100644
--- a/deps/v8/test/cctest/test-hashmap.cc
+++ b/deps/v8/test/cctest/test-hashmap.cc
@@ -171,7 +171,7 @@ void TestSet(IntKeyHash hash, int size) {
}
-TEST(Set) {
+TEST(HashSet) {
TestSet(Hash, 100);
TestSet(CollisionHash, 50);
}
diff --git a/deps/v8/test/cctest/test-heap.cc b/deps/v8/test/cctest/test-heap.cc
index f0a6ad5d26..d85310225a 100644
--- a/deps/v8/test/cctest/test-heap.cc
+++ b/deps/v8/test/cctest/test-heap.cc
@@ -59,6 +59,7 @@ TEST(HeapMaps) {
Heap* heap = CcTest::heap();
CheckMap(heap->meta_map(), MAP_TYPE, Map::kSize);
CheckMap(heap->heap_number_map(), HEAP_NUMBER_TYPE, HeapNumber::kSize);
+ CheckMap(heap->float32x4_map(), FLOAT32X4_TYPE, Float32x4::kSize);
CheckMap(heap->fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
CheckMap(heap->string_map(), STRING_TYPE, kVariableSizeSentinel);
}
@@ -213,6 +214,60 @@ TEST(HeapObjects) {
}
+template <typename T, typename LANE_TYPE, int LANES>
+static void CheckSimdLanes(T* value) {
+ // Get the original values, and check that all lanes can be set to new values
+ // without disturbing the other lanes.
+ LANE_TYPE lane_values[LANES];
+ for (int i = 0; i < LANES; i++) {
+ lane_values[i] = value->get_lane(i);
+ }
+ for (int i = 0; i < LANES; i++) {
+ lane_values[i] += 1;
+ value->set_lane(i, lane_values[i]);
+ for (int j = 0; j < LANES; j++) {
+ CHECK_EQ(lane_values[j], value->get_lane(j));
+ }
+ }
+}
+
+
+TEST(SimdObjects) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ Factory* factory = isolate->factory();
+
+ HandleScope sc(isolate);
+
+ Handle<Object> value = factory->NewFloat32x4(1, 2, 3, 4);
+ CHECK(value->IsFloat32x4());
+ CHECK(value->BooleanValue()); // SIMD values map to true.
+
+ Float32x4* float32x4 = *Handle<Float32x4>::cast(value);
+ CheckSimdLanes<Float32x4, float, 4>(float32x4);
+
+ // Check ToString for SIMD values.
+ // TODO(bbudge): Switch to Check* style function to test ToString().
+ value = factory->NewFloat32x4(1, 2, 3, 4);
+ float32x4 = *Handle<Float32x4>::cast(value);
+ std::ostringstream os;
+ float32x4->Float32x4Print(os);
+ CHECK_EQ("1, 2, 3, 4", os.str());
+
+ // Check unusual lane values.
+ float32x4->set_lane(0, 0);
+ CHECK_EQ(0, float32x4->get_lane(0));
+ float32x4->set_lane(1, -0.0);
+ CHECK_EQ(-0.0, float32x4->get_lane(1));
+ float quiet_NaN = std::numeric_limits<float>::quiet_NaN();
+ float signaling_NaN = std::numeric_limits<float>::signaling_NaN();
+ float32x4->set_lane(2, quiet_NaN);
+ CHECK(std::isnan(float32x4->get_lane(2)));
+ float32x4->set_lane(3, signaling_NaN);
+ CHECK(std::isnan(float32x4->get_lane(3)));
+}
+
+
TEST(Tagging) {
CcTest::InitializeVM();
int request = 24;
@@ -730,29 +785,27 @@ TEST(JSArray) {
JSArray::Initialize(array, 0);
// Set array length to 0.
- JSArray::SetElementsLength(array, handle(Smi::FromInt(0), isolate)).Check();
+ JSArray::SetLength(array, 0);
CHECK_EQ(Smi::FromInt(0), array->length());
// Must be in fast mode.
CHECK(array->HasFastSmiOrObjectElements());
// array[length] = name.
- JSReceiver::SetElement(array, 0, name, NONE, SLOPPY).Check();
+ JSReceiver::SetElement(array, 0, name, SLOPPY).Check();
CHECK_EQ(Smi::FromInt(1), array->length());
element = i::Object::GetElement(isolate, array, 0).ToHandleChecked();
CHECK_EQ(*element, *name);
// Set array length with larger than smi value.
- Handle<Object> length =
- factory->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
- JSArray::SetElementsLength(array, length).Check();
+ JSArray::SetLength(array, static_cast<uint32_t>(Smi::kMaxValue) + 1);
uint32_t int_length = 0;
- CHECK(length->ToArrayIndex(&int_length));
- CHECK_EQ(*length, array->length());
+ CHECK(array->length()->ToArrayIndex(&int_length));
+ CHECK_EQ(static_cast<uint32_t>(Smi::kMaxValue) + 1, int_length);
CHECK(array->HasDictionaryElements()); // Must be in slow mode.
// array[length] = name.
- JSReceiver::SetElement(array, int_length, name, NONE, SLOPPY).Check();
+ JSReceiver::SetElement(array, int_length, name, SLOPPY).Check();
uint32_t new_int_length = 0;
CHECK(array->length()->ToArrayIndex(&new_int_length));
CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
@@ -783,8 +836,8 @@ TEST(JSObjectCopy) {
JSReceiver::SetProperty(obj, first, one, SLOPPY).Check();
JSReceiver::SetProperty(obj, second, two, SLOPPY).Check();
- JSReceiver::SetElement(obj, 0, first, NONE, SLOPPY).Check();
- JSReceiver::SetElement(obj, 1, second, NONE, SLOPPY).Check();
+ JSReceiver::SetElement(obj, 0, first, SLOPPY).Check();
+ JSReceiver::SetElement(obj, 1, second, SLOPPY).Check();
// Make the clone.
Handle<Object> value1, value2;
@@ -809,8 +862,8 @@ TEST(JSObjectCopy) {
JSReceiver::SetProperty(clone, first, two, SLOPPY).Check();
JSReceiver::SetProperty(clone, second, one, SLOPPY).Check();
- JSReceiver::SetElement(clone, 0, second, NONE, SLOPPY).Check();
- JSReceiver::SetElement(clone, 1, first, NONE, SLOPPY).Check();
+ JSReceiver::SetElement(clone, 0, second, SLOPPY).Check();
+ JSReceiver::SetElement(clone, 1, first, SLOPPY).Check();
value1 = Object::GetElement(isolate, obj, 1).ToHandleChecked();
value2 = Object::GetElement(isolate, clone, 0).ToHandleChecked();
@@ -896,9 +949,8 @@ TEST(Iteration) {
// Allocate a JS array to OLD_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewJSArray(10);
- objs[next_objs_index++] = factory->NewJSArray(10,
- FAST_HOLEY_ELEMENTS,
- TENURED);
+ objs[next_objs_index++] =
+ factory->NewJSArray(10, FAST_HOLEY_ELEMENTS, Strength::WEAK, TENURED);
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
objs[next_objs_index++] = factory->NewStringFromStaticChars("abcdefghij");
@@ -1142,7 +1194,7 @@ TEST(TestCodeFlushingPreAged) {
TEST(TestCodeFlushingIncremental) {
// If we do not flush code this test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
+ if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_optimize_for_size = false;
CcTest::InitializeVM();
@@ -1211,7 +1263,7 @@ TEST(TestCodeFlushingIncremental) {
TEST(TestCodeFlushingIncrementalScavenge) {
// If we do not flush code this test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
+ if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_optimize_for_size = false;
CcTest::InitializeVM();
@@ -1280,7 +1332,7 @@ TEST(TestCodeFlushingIncrementalScavenge) {
TEST(TestCodeFlushingIncrementalAbort) {
// If we do not flush code this test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally) return;
+ if (!FLAG_flush_code) return;
i::FLAG_allow_natives_syntax = true;
i::FLAG_optimize_for_size = false;
CcTest::InitializeVM();
@@ -1328,8 +1380,10 @@ TEST(TestCodeFlushingIncrementalAbort) {
// disabled.
int position = 0;
Handle<Object> breakpoint_object(Smi::FromInt(0), isolate);
+ EnableDebugger();
isolate->debug()->SetBreakPoint(function, breakpoint_object, &position);
isolate->debug()->ClearAllBreakPoints();
+ DisableDebugger();
// Force optimization now that code flushing is disabled.
{ v8::HandleScope scope(CcTest::isolate());
@@ -1346,8 +1400,7 @@ TEST(TestCodeFlushingIncrementalAbort) {
TEST(CompilationCacheCachingBehavior) {
// If we do not flush code, or have the compilation cache turned off, this
// test is invalid.
- if (!FLAG_flush_code || !FLAG_flush_code_incrementally ||
- !FLAG_compilation_cache) {
+ if (!FLAG_flush_code || !FLAG_compilation_cache) {
return;
}
CcTest::InitializeVM();
@@ -1377,7 +1430,8 @@ TEST(CompilationCacheCachingBehavior) {
// On first compilation, only a hash is inserted in the code cache. We can't
// find that value.
MaybeHandle<SharedFunctionInfo> info = compilation_cache->LookupScript(
- source, Handle<Object>(), 0, 0, false, true, native_context,
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
language_mode);
CHECK(info.is_null());
@@ -1388,16 +1442,20 @@ TEST(CompilationCacheCachingBehavior) {
// On second compilation, the hash is replaced by a real cache entry mapping
// the source to the shared function info containing the code.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(!info.is_null());
heap->CollectAllGarbage();
// On second compilation, the hash is replaced by a real cache entry mapping
// the source to the shared function info containing the code.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(!info.is_null());
while (!info.ToHandleChecked()->code()->IsOld()) {
@@ -1406,8 +1464,10 @@ TEST(CompilationCacheCachingBehavior) {
heap->CollectAllGarbage();
// Ensure code aging cleared the entry from the cache.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(info.is_null());
{
@@ -1417,8 +1477,10 @@ TEST(CompilationCacheCachingBehavior) {
// On first compilation, only a hash is inserted in the code cache. We can't
// find that value.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(info.is_null());
for (int i = 0; i < CompilationCacheTable::kHashGenerations; i++) {
@@ -1432,8 +1494,10 @@ TEST(CompilationCacheCachingBehavior) {
// If we aged the cache before caching the script, ensure that we didn't cache
// on next compilation.
- info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, false,
- true, native_context, language_mode);
+ info = compilation_cache->LookupScript(
+ source, Handle<Object>(), 0, 0,
+ v8::ScriptOriginOptions(false, true, false), native_context,
+ language_mode);
CHECK(info.is_null());
}
@@ -1682,13 +1746,13 @@ TEST(TestSizeOfRegExpCode) {
// Adjust source below and this check to match
// RegExpImple::kRegExpTooLargeToOptimize.
- DCHECK_EQ(i::RegExpImpl::kRegExpTooLargeToOptimize, 10 * KB);
+ DCHECK_EQ(i::RegExpImpl::kRegExpTooLargeToOptimize, 20 * KB);
// Compile a regexp that is much larger if we are using regexp optimizations.
CompileRun(
"var reg_exp_source = '(?:a|bc|def|ghij|klmno|pqrstu)';"
"var half_size_reg_exp;"
- "while (reg_exp_source.length < 10 * 1024) {"
+ "while (reg_exp_source.length < 20 * 1024) {"
" half_size_reg_exp = reg_exp_source;"
" reg_exp_source = reg_exp_source + reg_exp_source;"
"}"
@@ -1719,7 +1783,11 @@ TEST(TestSizeOfRegExpCode) {
int size_of_regexp_code = size_with_regexp - initial_size;
- CHECK_LE(size_of_regexp_code, 1 * MB);
+ // On some platforms the debug-code flag causes huge amounts of regexp code
+ // to be emitted, breaking this test.
+ if (!FLAG_debug_code) {
+ CHECK_LE(size_of_regexp_code, 1 * MB);
+ }
// Small regexp is half the size, but compiles to more than twice the code
// due to the optimization steps.
@@ -1773,6 +1841,271 @@ TEST(TestSizeOfObjects) {
}
+TEST(TestAlignmentCalculations) {
+ // Maximum fill amounts are consistent.
+ int maximum_double_misalignment = kDoubleSize - kPointerSize;
+ int maximum_simd128_misalignment = kSimd128Size - kPointerSize;
+ int max_word_fill = Heap::GetMaximumFillToAlign(kWordAligned);
+ CHECK_EQ(0, max_word_fill);
+ int max_double_fill = Heap::GetMaximumFillToAlign(kDoubleAligned);
+ CHECK_EQ(maximum_double_misalignment, max_double_fill);
+ int max_double_unaligned_fill = Heap::GetMaximumFillToAlign(kDoubleUnaligned);
+ CHECK_EQ(maximum_double_misalignment, max_double_unaligned_fill);
+ int max_simd128_unaligned_fill =
+ Heap::GetMaximumFillToAlign(kSimd128Unaligned);
+ CHECK_EQ(maximum_simd128_misalignment, max_simd128_unaligned_fill);
+
+ Address base = reinterpret_cast<Address>(NULL);
+ int fill = 0;
+
+ // Word alignment never requires fill.
+ fill = Heap::GetFillToAlign(base, kWordAligned);
+ CHECK_EQ(0, fill);
+ fill = Heap::GetFillToAlign(base + kPointerSize, kWordAligned);
+ CHECK_EQ(0, fill);
+
+ // No fill is required when address is double aligned.
+ fill = Heap::GetFillToAlign(base, kDoubleAligned);
+ CHECK_EQ(0, fill);
+ // Fill is required if address is not double aligned.
+ fill = Heap::GetFillToAlign(base + kPointerSize, kDoubleAligned);
+ CHECK_EQ(maximum_double_misalignment, fill);
+ // kDoubleUnaligned has the opposite fill amounts.
+ fill = Heap::GetFillToAlign(base, kDoubleUnaligned);
+ CHECK_EQ(maximum_double_misalignment, fill);
+ fill = Heap::GetFillToAlign(base + kPointerSize, kDoubleUnaligned);
+ CHECK_EQ(0, fill);
+
+ // 128 bit SIMD types have 2 or 4 possible alignments, depending on platform.
+ fill = Heap::GetFillToAlign(base, kSimd128Unaligned);
+ CHECK_EQ((3 * kPointerSize) & kSimd128AlignmentMask, fill);
+ fill = Heap::GetFillToAlign(base + kPointerSize, kSimd128Unaligned);
+ CHECK_EQ((2 * kPointerSize) & kSimd128AlignmentMask, fill);
+ fill = Heap::GetFillToAlign(base + 2 * kPointerSize, kSimd128Unaligned);
+ CHECK_EQ(kPointerSize, fill);
+ fill = Heap::GetFillToAlign(base + 3 * kPointerSize, kSimd128Unaligned);
+ CHECK_EQ(0, fill);
+}
+
+
+static HeapObject* NewSpaceAllocateAligned(int size,
+ AllocationAlignment alignment) {
+ Heap* heap = CcTest::heap();
+ AllocationResult allocation =
+ heap->new_space()->AllocateRawAligned(size, alignment);
+ HeapObject* obj = NULL;
+ allocation.To(&obj);
+ heap->CreateFillerObjectAt(obj->address(), size);
+ return obj;
+}
+
+
+// Get new space allocation into the desired alignment.
+static Address AlignNewSpace(AllocationAlignment alignment, int offset) {
+ Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
+ int fill = Heap::GetFillToAlign(*top_addr, alignment);
+ if (fill) {
+ NewSpaceAllocateAligned(fill + offset, kWordAligned);
+ }
+ return *top_addr;
+}
+
+
+TEST(TestAlignedAllocation) {
+ // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
+ const intptr_t double_misalignment = kDoubleSize - kPointerSize;
+ Address* top_addr = CcTest::heap()->new_space()->allocation_top_address();
+ Address start;
+ HeapObject* obj;
+ HeapObject* filler;
+ if (double_misalignment) {
+ // Allocate a pointer sized object that must be double aligned at an
+ // aligned address.
+ start = AlignNewSpace(kDoubleAligned, 0);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ // There is no filler.
+ CHECK_EQ(kPointerSize, *top_addr - start);
+
+ // Allocate a second pointer sized object that must be double aligned at an
+ // unaligned address.
+ start = AlignNewSpace(kDoubleAligned, kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kPointerSize);
+ CHECK_EQ(kPointerSize + double_misalignment, *top_addr - start);
+
+ // Similarly for kDoubleUnaligned.
+ start = AlignNewSpace(kDoubleUnaligned, 0);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ CHECK_EQ(kPointerSize, *top_addr - start);
+ start = AlignNewSpace(kDoubleUnaligned, kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kPointerSize);
+ CHECK_EQ(kPointerSize + double_misalignment, *top_addr - start);
+ }
+
+ // Now test SIMD alignment. There are 2 or 4 possible alignments, depending
+ // on platform.
+ start = AlignNewSpace(kSimd128Unaligned, 0);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is no filler.
+ CHECK_EQ(kPointerSize, *top_addr - start);
+ start = AlignNewSpace(kSimd128Unaligned, kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kSimd128Size - kPointerSize);
+ CHECK_EQ(kPointerSize + kSimd128Size - kPointerSize, *top_addr - start);
+
+ if (double_misalignment) {
+ // Test the 2 other alignments possible on 32 bit platforms.
+ start = AlignNewSpace(kSimd128Unaligned, 2 * kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == 2 * kPointerSize);
+ CHECK_EQ(kPointerSize + 2 * kPointerSize, *top_addr - start);
+ start = AlignNewSpace(kSimd128Unaligned, 3 * kPointerSize);
+ obj = NewSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ CHECK(obj != filler && filler->IsFiller() &&
+ filler->Size() == kPointerSize);
+ CHECK_EQ(kPointerSize + kPointerSize, *top_addr - start);
+ }
+}
+
+
+static HeapObject* OldSpaceAllocateAligned(int size,
+ AllocationAlignment alignment) {
+ Heap* heap = CcTest::heap();
+ AllocationResult allocation =
+ heap->old_space()->AllocateRawAligned(size, alignment);
+ HeapObject* obj = NULL;
+ allocation.To(&obj);
+ heap->CreateFillerObjectAt(obj->address(), size);
+ return obj;
+}
+
+
+// Get old space allocation into the desired alignment.
+static Address AlignOldSpace(AllocationAlignment alignment, int offset) {
+ Address* top_addr = CcTest::heap()->old_space()->allocation_top_address();
+ int fill = Heap::GetFillToAlign(*top_addr, alignment);
+ int allocation = fill + offset;
+ if (allocation) {
+ OldSpaceAllocateAligned(allocation, kWordAligned);
+ }
+ Address top = *top_addr;
+ // Now force the remaining allocation onto the free list.
+ CcTest::heap()->old_space()->EmptyAllocationInfo();
+ return top;
+}
+
+
+// Test the case where allocation must be done from the free list, so filler
+// may precede or follow the object.
+TEST(TestAlignedOverAllocation) {
+ // Double misalignment is 4 on 32-bit platforms, 0 on 64-bit ones.
+ const intptr_t double_misalignment = kDoubleSize - kPointerSize;
+ Address start;
+ HeapObject* obj;
+ HeapObject* filler1;
+ HeapObject* filler2;
+ if (double_misalignment) {
+ start = AlignOldSpace(kDoubleAligned, 0);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ // The object is aligned, and a filler object is created after.
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ filler1 = HeapObject::FromAddress(start + kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ // Try the opposite alignment case.
+ start = AlignOldSpace(kDoubleAligned, kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleAligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment));
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1);
+ CHECK(filler1->IsFiller());
+ CHECK(filler1->Size() == kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+
+ // Similarly for kDoubleUnaligned.
+ start = AlignOldSpace(kDoubleUnaligned, 0);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ // The object is aligned, and a filler object is created after.
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ filler1 = HeapObject::FromAddress(start + kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ // Try the opposite alignment case.
+ start = AlignOldSpace(kDoubleUnaligned, kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kDoubleUnaligned);
+ CHECK(IsAddressAligned(obj->address(), kDoubleAlignment, kPointerSize));
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ }
+
+ // Now test SIMD alignment. There are 2 or 4 possible alignments, depending
+ // on platform.
+ start = AlignOldSpace(kSimd128Unaligned, 0);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object after the object.
+ filler1 = HeapObject::FromAddress(start + kPointerSize);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kSimd128Size - kPointerSize);
+ start = AlignOldSpace(kSimd128Unaligned, kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There is a filler object before the object.
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kSimd128Size - kPointerSize);
+
+ if (double_misalignment) {
+ // Test the 2 other alignments possible on 32 bit platforms.
+ start = AlignOldSpace(kSimd128Unaligned, 2 * kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There are filler objects before and after the object.
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == 2 * kPointerSize);
+ filler2 = HeapObject::FromAddress(start + 3 * kPointerSize);
+ CHECK(obj != filler2 && filler2->IsFiller() &&
+ filler2->Size() == kPointerSize);
+ start = AlignOldSpace(kSimd128Unaligned, 3 * kPointerSize);
+ obj = OldSpaceAllocateAligned(kPointerSize, kSimd128Unaligned);
+ CHECK(IsAddressAligned(obj->address(), kSimd128Alignment, kPointerSize));
+ // There are filler objects before and after the object.
+ filler1 = HeapObject::FromAddress(start);
+ CHECK(obj != filler1 && filler1->IsFiller() &&
+ filler1->Size() == kPointerSize);
+ filler2 = HeapObject::FromAddress(start + 2 * kPointerSize);
+ CHECK(obj != filler2 && filler2->IsFiller() &&
+ filler2->Size() == 2 * kPointerSize);
+ }
+}
+
+
TEST(TestSizeOfObjectsVsHeapIteratorPrecision) {
CcTest::InitializeVM();
HeapIterator iterator(CcTest::heap());
@@ -2118,7 +2451,7 @@ TEST(InstanceOfStubWriteBarrier) {
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
Handle<JSFunction> f =
v8::Utils::OpenHandle(
@@ -2191,7 +2524,8 @@ TEST(PrototypeTransitionClearing) {
TransitionArray::GetPrototypeTransitions(baseObject->map());
for (int i = initialTransitions; i < initialTransitions + transitions; i++) {
int j = TransitionArray::kProtoTransitionHeaderSize + i;
- CHECK(trans->get(j)->IsMap());
+ CHECK(trans->get(j)->IsWeakCell());
+ CHECK(WeakCell::cast(trans->get(j))->value()->IsMap());
}
// Make sure next prototype is placed on an old-space evacuation candidate.
@@ -2200,7 +2534,8 @@ TEST(PrototypeTransitionClearing) {
{
AlwaysAllocateScope always_allocate(isolate);
SimulateFullSpace(space);
- prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
}
// Add a prototype on an evacuation candidate and verify that transition
@@ -2244,7 +2579,7 @@ TEST(ResetSharedFunctionInfoCountersDuringIncrementalMarking) {
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
// The following calls will increment CcTest::heap()->global_ic_age().
CcTest::isolate()->ContextDisposedNotification();
SimulateIncrementalMarking(CcTest::heap());
@@ -2302,7 +2637,7 @@ TEST(IdleNotificationFinishMarking) {
SimulateFullSpace(CcTest::heap()->old_space());
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
CHECK_EQ(CcTest::heap()->gc_count(), 0);
@@ -3071,7 +3406,6 @@ TEST(TransitionArraySimpleToFull) {
TEST(Regress2143a) {
- i::FLAG_collect_maps = true;
i::FLAG_incremental_marking = true;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
@@ -3111,7 +3445,6 @@ TEST(Regress2143a) {
TEST(Regress2143b) {
- i::FLAG_collect_maps = true;
i::FLAG_incremental_marking = true;
i::FLAG_allow_natives_syntax = true;
CcTest::InitializeVM();
@@ -3203,6 +3536,31 @@ TEST(ReleaseOverReservedPages) {
CHECK_EQ(1, old_space->CountTotalPages());
}
+static int forced_gc_counter = 0;
+
+void MockUseCounterCallback(v8::Isolate* isolate,
+ v8::Isolate::UseCounterFeature feature) {
+ isolate->GetCallingContext();
+ if (feature == v8::Isolate::kForcedGC) {
+ forced_gc_counter++;
+ }
+}
+
+
+TEST(CountForcedGC) {
+ i::FLAG_expose_gc = true;
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ v8::HandleScope scope(CcTest::isolate());
+
+ isolate->SetUseCounterCallback(MockUseCounterCallback);
+
+ forced_gc_counter = 0;
+ const char* source = "gc();";
+ CompileRun(source);
+ CHECK_GT(forced_gc_counter, 0);
+}
+
TEST(Regress2237) {
i::FLAG_stress_compaction = false;
@@ -3255,41 +3613,6 @@ TEST(PrintSharedFunctionInfo) {
#endif // OBJECT_PRINT
-TEST(Regress2211) {
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
-
- v8::Handle<v8::String> value = v8_str("val string");
- Smi* hash = Smi::FromInt(321);
- Factory* factory = CcTest::i_isolate()->factory();
-
- for (int i = 0; i < 2; i++) {
- // Store identity hash first and common hidden property second.
- v8::Handle<v8::Object> obj = v8::Object::New(CcTest::isolate());
- Handle<JSObject> internal_obj = v8::Utils::OpenHandle(*obj);
- CHECK(internal_obj->HasFastProperties());
-
- // In the first iteration, set hidden value first and identity hash second.
- // In the second iteration, reverse the order.
- if (i == 0) obj->SetHiddenValue(v8_str("key string"), value);
- JSObject::SetIdentityHash(internal_obj, handle(hash, CcTest::i_isolate()));
- if (i == 1) obj->SetHiddenValue(v8_str("key string"), value);
-
- // Check values.
- CHECK_EQ(hash,
- internal_obj->GetHiddenProperty(factory->identity_hash_string()));
- CHECK(value->Equals(obj->GetHiddenValue(v8_str("key string"))));
-
- // Check size.
- FieldIndex index = FieldIndex::ForDescriptor(internal_obj->map(), 0);
- ObjectHashTable* hashtable = ObjectHashTable::cast(
- internal_obj->RawFastPropertyAt(index));
- // HashTable header (5) and 4 initial entries (8).
- CHECK_LE(hashtable->SizeFor(hashtable->length()), 13 * kPointerSize);
- }
-}
-
-
TEST(IncrementalMarkingPreservesMonomorphicCallIC) {
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
@@ -3447,23 +3770,15 @@ TEST(IncrementalMarkingPreservesMonomorphicIC) {
CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, MONOMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == MONOMORPHIC);
- }
+ CheckVectorIC(f, 0, MONOMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, MONOMORPHIC);
- CHECK(ic_after->ic_state() == DEFAULT);
- } else {
- CHECK(ic_after->ic_state() == MONOMORPHIC);
- }
+ CheckVectorIC(f, 0, MONOMORPHIC);
+ CHECK(ic_after->ic_state() == DEFAULT);
}
@@ -3487,12 +3802,8 @@ TEST(IncrementalMarkingClearsMonomorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, MONOMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == MONOMORPHIC);
- }
+ CheckVectorIC(f, 0, MONOMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
@@ -3500,12 +3811,8 @@ TEST(IncrementalMarkingClearsMonomorphicIC) {
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorICCleared(f, 0);
- CHECK(ic_after->ic_state() == DEFAULT);
- } else {
- CHECK(IC::IsCleared(ic_after));
- }
+ CheckVectorICCleared(f, 0);
+ CHECK(ic_after->ic_state() == DEFAULT);
}
@@ -3536,24 +3843,16 @@ TEST(IncrementalMarkingPreservesPolymorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, POLYMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == POLYMORPHIC);
- }
+ CheckVectorIC(f, 0, POLYMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, POLYMORPHIC);
- CHECK(ic_after->ic_state() == DEFAULT);
- } else {
- CHECK(ic_after->ic_state() == POLYMORPHIC);
- }
+ CheckVectorIC(f, 0, POLYMORPHIC);
+ CHECK(ic_after->ic_state() == DEFAULT);
}
@@ -3584,25 +3883,16 @@ TEST(IncrementalMarkingClearsPolymorphicIC) {
*v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorIC(f, 0, POLYMORPHIC);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(ic_before->ic_state() == POLYMORPHIC);
- }
+ CheckVectorIC(f, 0, POLYMORPHIC);
+ CHECK(ic_before->ic_state() == DEFAULT);
// Fire context dispose notification.
CcTest::isolate()->ContextDisposedNotification();
SimulateIncrementalMarking(CcTest::heap());
CcTest::heap()->CollectAllGarbage();
- Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
- if (FLAG_vector_ics) {
- CheckVectorICCleared(f, 0);
- CHECK(ic_before->ic_state() == DEFAULT);
- } else {
- CHECK(IC::IsCleared(ic_after));
- }
+ CheckVectorICCleared(f, 0);
+ CHECK(ic_before->ic_state() == DEFAULT);
}
@@ -3718,7 +4008,6 @@ UNINITIALIZED_TEST(ReleaseStackTraceData) {
TEST(Regress159140) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -3780,7 +4069,6 @@ TEST(Regress159140) {
TEST(Regress165495) {
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -3828,7 +4116,6 @@ TEST(Regress165495) {
TEST(Regress169209) {
i::FLAG_stress_compaction = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
@@ -3944,9 +4231,8 @@ TEST(Regress169928) {
JSArray::kSize + AllocationMemento::kSize +
kPointerSize);
- Handle<JSArray> array = factory->NewJSArrayWithElements(array_data,
- FAST_SMI_ELEMENTS,
- NOT_TENURED);
+ Handle<JSArray> array =
+ factory->NewJSArrayWithElements(array_data, FAST_SMI_ELEMENTS);
CHECK_EQ(Smi::FromInt(2), array->length());
CHECK(array->HasFastSmiOrObjectElements());
@@ -3954,8 +4240,9 @@ TEST(Regress169928) {
// We need filler the size of AllocationMemento object, plus an extra
// fill pointer value.
HeapObject* obj = NULL;
- AllocationResult allocation = CcTest::heap()->new_space()->AllocateRaw(
- AllocationMemento::kSize + kPointerSize);
+ AllocationResult allocation =
+ CcTest::heap()->new_space()->AllocateRawUnaligned(
+ AllocationMemento::kSize + kPointerSize);
CHECK(allocation.To(&obj));
Address addr_obj = obj->address();
CcTest::heap()->CreateFillerObjectAt(
@@ -3977,7 +4264,6 @@ TEST(Regress168801) {
i::FLAG_always_compact = true;
i::FLAG_cache_optimized_code = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -4034,7 +4320,6 @@ TEST(Regress173458) {
i::FLAG_always_compact = true;
i::FLAG_cache_optimized_code = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_flush_code_incrementally = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
Heap* heap = isolate->heap();
@@ -4119,7 +4404,7 @@ TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
"};"
"f(10 * 1024 * 1024);");
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- if (marking->IsStopped()) marking->Start();
+ if (marking->IsStopped()) marking->Start(Heap::kNoGCFlags);
// This big step should be sufficient to mark the whole array.
marking->Step(100 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
DCHECK(marking->IsComplete() ||
@@ -4390,7 +4675,6 @@ static int GetCodeChainLength(Code* code) {
TEST(NextCodeLinkIsWeak) {
i::FLAG_always_opt = false;
i::FLAG_allow_natives_syntax = true;
- i::FLAG_turbo_deoptimization = true;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
v8::internal::Heap* heap = CcTest::heap();
@@ -4705,9 +4989,8 @@ Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
void CheckIC(Code* code, Code::Kind kind, SharedFunctionInfo* shared,
int ic_slot, InlineCacheState state) {
- if (FLAG_vector_ics &&
- (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
- kind == Code::CALL_IC)) {
+ if (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC ||
+ kind == Code::CALL_IC) {
TypeFeedbackVector* vector = shared->feedback_vector();
FeedbackVectorICSlot slot(ic_slot);
if (kind == Code::LOAD_IC) {
@@ -4849,7 +5132,7 @@ TEST(WeakCellsWithIncrementalMarking) {
Handle<WeakCell> weak_cell = factory->NewWeakCell(value);
CHECK(weak_cell->value()->IsFixedArray());
IncrementalMarking* marking = heap->incremental_marking();
- if (marking->IsStopped()) marking->Start();
+ if (marking->IsStopped()) marking->Start(Heap::kNoGCFlags);
marking->Step(128, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
heap->CollectGarbage(NEW_SPACE);
CHECK(weak_cell->value()->IsFixedArray());
@@ -5117,7 +5400,7 @@ TEST(Regress388880) {
// that would cause crash.
IncrementalMarking* marking = CcTest::heap()->incremental_marking();
marking->Abort();
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
CHECK(marking->IsMarking());
// Now everything is set up for crashing in JSObject::MigrateFastToFast()
@@ -5143,7 +5426,7 @@ TEST(Regress3631) {
"}"
"weak_map");
if (marking->IsStopped()) {
- marking->Start();
+ marking->Start(Heap::kNoGCFlags);
}
// Incrementally mark the backing store.
Handle<JSObject> obj =
@@ -5319,7 +5602,7 @@ static void TestRightTrimFixedTypedArray(i::ExternalArrayType type,
Heap* heap = isolate->heap();
Handle<FixedTypedArrayBase> array =
- factory->NewFixedTypedArray(initial_length, type);
+ factory->NewFixedTypedArray(initial_length, type, true);
int old_size = array->size();
heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*array,
elements_to_trim);
@@ -5369,7 +5652,7 @@ TEST(WeakFixedArray) {
Handle<HeapNumber> number = CcTest::i_isolate()->factory()->NewHeapNumber(1);
Handle<WeakFixedArray> array = WeakFixedArray::Add(Handle<Object>(), number);
array->Remove(number);
- array->Compact();
+ array->Compact<WeakFixedArray::NullCallback>();
WeakFixedArray::Add(array, number);
}
@@ -5379,7 +5662,7 @@ TEST(PreprocessStackTrace) {
FLAG_gc_interval = -1;
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
CompileRun("throw new Error();");
CHECK(try_catch.HasCaught());
Isolate* isolate = CcTest::i_isolate();
@@ -5405,3 +5688,370 @@ TEST(PreprocessStackTrace) {
CHECK(!element->IsCode());
}
}
+
+
+static bool utils_has_been_collected = false;
+
+static void UtilsHasBeenCollected(
+ const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
+ utils_has_been_collected = true;
+ data.GetParameter()->Reset();
+}
+
+
+TEST(BootstrappingExports) {
+ FLAG_expose_natives_as = "natives";
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+
+ if (Snapshot::HaveASnapshotToStartFrom(CcTest::i_isolate())) return;
+
+ utils_has_been_collected = false;
+
+ v8::Persistent<v8::Object> utils;
+
+ {
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::Object> natives =
+ CcTest::global()->Get(v8_str("natives"))->ToObject(isolate);
+ utils.Reset(isolate, natives->Get(v8_str("utils"))->ToObject(isolate));
+ natives->Delete(v8_str("utils"));
+ }
+
+ utils.SetWeak(&utils, UtilsHasBeenCollected,
+ v8::WeakCallbackType::kParameter);
+
+ CcTest::heap()->CollectAllAvailableGarbage("fire weak callbacks");
+
+ CHECK(utils_has_been_collected);
+}
+
+
+TEST(Regress1878) {
+ FLAG_allow_natives_syntax = true;
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Function> constructor =
+ v8::Utils::ToLocal(CcTest::i_isolate()->internal_array_function());
+ CcTest::global()->Set(v8_str("InternalArray"), constructor);
+
+ v8::TryCatch try_catch(isolate);
+
+ CompileRun(
+ "var a = Array();"
+ "for (var i = 0; i < 1000; i++) {"
+ " var ai = new InternalArray(10000);"
+ " if (%HaveSameMap(ai, a)) throw Error();"
+ " if (!%HasFastObjectElements(ai)) throw Error();"
+ "}"
+ "for (var i = 0; i < 1000; i++) {"
+ " var ai = new InternalArray(10000);"
+ " if (%HaveSameMap(ai, a)) throw Error();"
+ " if (!%HasFastObjectElements(ai)) throw Error();"
+ "}");
+
+ CHECK(!try_catch.HasCaught());
+}
+
+
+void AllocateInSpace(Isolate* isolate, size_t bytes, AllocationSpace space) {
+ CHECK(bytes >= FixedArray::kHeaderSize);
+ CHECK(bytes % kPointerSize == 0);
+ Factory* factory = isolate->factory();
+ HandleScope scope(isolate);
+ AlwaysAllocateScope always_allocate(isolate);
+ int elements =
+ static_cast<int>((bytes - FixedArray::kHeaderSize) / kPointerSize);
+ Handle<FixedArray> array = factory->NewFixedArray(
+ elements, space == NEW_SPACE ? NOT_TENURED : TENURED);
+ CHECK((space == NEW_SPACE) == isolate->heap()->InNewSpace(*array));
+ CHECK_EQ(bytes, static_cast<size_t>(array->Size()));
+}
+
+
+TEST(NewSpaceAllocationCounter) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ size_t counter1 = heap->NewSpaceAllocationCounter();
+ heap->CollectGarbage(NEW_SPACE);
+ const size_t kSize = 1024;
+ AllocateInSpace(isolate, kSize, NEW_SPACE);
+ size_t counter2 = heap->NewSpaceAllocationCounter();
+ CHECK_EQ(kSize, counter2 - counter1);
+ heap->CollectGarbage(NEW_SPACE);
+ size_t counter3 = heap->NewSpaceAllocationCounter();
+ CHECK_EQ(0U, counter3 - counter2);
+ // Test counter overflow.
+ size_t max_counter = -1;
+ heap->set_new_space_allocation_counter(max_counter - 10 * kSize);
+ size_t start = heap->NewSpaceAllocationCounter();
+ for (int i = 0; i < 20; i++) {
+ AllocateInSpace(isolate, kSize, NEW_SPACE);
+ size_t counter = heap->NewSpaceAllocationCounter();
+ CHECK_EQ(kSize, counter - start);
+ start = counter;
+ }
+}
+
+
+TEST(OldSpaceAllocationCounter) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ size_t counter1 = heap->OldGenerationAllocationCounter();
+ heap->CollectGarbage(NEW_SPACE);
+ heap->CollectGarbage(NEW_SPACE);
+ const size_t kSize = 1024;
+ AllocateInSpace(isolate, kSize, OLD_SPACE);
+ size_t counter2 = heap->OldGenerationAllocationCounter();
+ // TODO(ulan): replace all CHECK_LE with CHECK_EQ after v8:4148 is fixed.
+ CHECK_LE(kSize, counter2 - counter1);
+ heap->CollectGarbage(NEW_SPACE);
+ size_t counter3 = heap->OldGenerationAllocationCounter();
+ CHECK_EQ(0u, counter3 - counter2);
+ AllocateInSpace(isolate, kSize, OLD_SPACE);
+ heap->CollectGarbage(OLD_SPACE);
+ size_t counter4 = heap->OldGenerationAllocationCounter();
+ CHECK_LE(kSize, counter4 - counter3);
+ // Test counter overflow.
+ size_t max_counter = -1;
+ heap->set_old_generation_allocation_counter(max_counter - 10 * kSize);
+ size_t start = heap->OldGenerationAllocationCounter();
+ for (int i = 0; i < 20; i++) {
+ AllocateInSpace(isolate, kSize, OLD_SPACE);
+ size_t counter = heap->OldGenerationAllocationCounter();
+ CHECK_LE(kSize, counter - start);
+ start = counter;
+ }
+}
+
+
+TEST(NewSpaceAllocationThroughput) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, counter1, 0);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, counter2, 0);
+ size_t throughput =
+ tracer->NewSpaceAllocationThroughputInBytesPerMillisecond();
+ CHECK_EQ((counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, counter3, 0);
+ throughput = tracer->NewSpaceAllocationThroughputInBytesPerMillisecond();
+ CHECK_EQ((counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+TEST(NewSpaceAllocationThroughput2) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, counter1, 0);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, counter2, 0);
+ size_t throughput =
+ tracer->NewSpaceAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, counter3, 0);
+ throughput = tracer->NewSpaceAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+static void CheckLeak(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ Isolate* isolate = CcTest::i_isolate();
+ Object* message =
+ *reinterpret_cast<Object**>(isolate->pending_message_obj_address());
+ CHECK(message->IsTheHole());
+}
+
+
+TEST(MessageObjectLeak) {
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
+ global->Set(v8::String::NewFromUtf8(isolate, "check"),
+ v8::FunctionTemplate::New(isolate, CheckLeak));
+ v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
+ v8::Context::Scope cscope(context);
+
+ const char* test =
+ "try {"
+ " throw 'message 1';"
+ "} catch (e) {"
+ "}"
+ "check();"
+ "L: try {"
+ " throw 'message 2';"
+ "} finally {"
+ " break L;"
+ "}"
+ "check();";
+ CompileRun(test);
+
+ const char* flag = "--turbo-filter=*";
+ FlagList::SetFlagsFromString(flag, StrLength(flag));
+ FLAG_always_opt = true;
+ FLAG_turbo_try_catch = true;
+ FLAG_turbo_try_finally = true;
+
+ CompileRun(test);
+}
+
+
+static void CheckEqualSharedFunctionInfos(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ Handle<Object> obj1 = v8::Utils::OpenHandle(*args[0]);
+ Handle<Object> obj2 = v8::Utils::OpenHandle(*args[1]);
+ Handle<JSFunction> fun1 = Handle<JSFunction>::cast(obj1);
+ Handle<JSFunction> fun2 = Handle<JSFunction>::cast(obj2);
+ CHECK(fun1->shared() == fun2->shared());
+}
+
+
+static void RemoveCodeAndGC(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ Isolate* isolate = CcTest::i_isolate();
+ Handle<Object> obj = v8::Utils::OpenHandle(*args[0]);
+ Handle<JSFunction> fun = Handle<JSFunction>::cast(obj);
+ fun->ReplaceCode(*isolate->builtins()->CompileLazy());
+ fun->shared()->ReplaceCode(*isolate->builtins()->CompileLazy());
+ isolate->heap()->CollectAllAvailableGarbage("remove code and gc");
+}
+
+
+TEST(CanonicalSharedFunctionInfo) {
+ CcTest::InitializeVM();
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
+ global->Set(isolate, "check", v8::FunctionTemplate::New(
+ isolate, CheckEqualSharedFunctionInfos));
+ global->Set(isolate, "remove",
+ v8::FunctionTemplate::New(isolate, RemoveCodeAndGC));
+ v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
+ v8::Context::Scope cscope(context);
+ CompileRun(
+ "function f() { return function g() {}; }"
+ "var g1 = f();"
+ "remove(f);"
+ "var g2 = f();"
+ "check(g1, g2);");
+
+ CompileRun(
+ "function f() { return (function() { return function g() {}; })(); }"
+ "var g1 = f();"
+ "remove(f);"
+ "var g2 = f();"
+ "check(g1, g2);");
+}
+
+
+TEST(OldGenerationAllocationThroughput) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, 0, counter1);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, 0, counter2);
+ size_t throughput =
+ tracer->OldGenerationAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, 0, counter3);
+ throughput =
+ tracer->OldGenerationAllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ((counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+TEST(AllocationThroughput) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ GCTracer* tracer = heap->tracer();
+ int time1 = 100;
+ size_t counter1 = 1000;
+ tracer->SampleAllocation(time1, counter1, counter1);
+ int time2 = 200;
+ size_t counter2 = 2000;
+ tracer->SampleAllocation(time2, counter2, counter2);
+ size_t throughput = tracer->AllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ(2 * (counter2 - counter1) / (time2 - time1), throughput);
+ int time3 = 1000;
+ size_t counter3 = 30000;
+ tracer->SampleAllocation(time3, counter3, counter3);
+ throughput = tracer->AllocationThroughputInBytesPerMillisecond(100);
+ CHECK_EQ(2 * (counter3 - counter1) / (time3 - time1), throughput);
+}
+
+
+TEST(SlotsBufferObjectSlotsRemoval) {
+ CcTest::InitializeVM();
+ v8::HandleScope scope(CcTest::isolate());
+ Isolate* isolate = CcTest::i_isolate();
+ Heap* heap = isolate->heap();
+ Factory* factory = isolate->factory();
+
+ SlotsBuffer* buffer = new SlotsBuffer(NULL);
+ void* fake_object[1];
+
+ Handle<FixedArray> array = factory->NewFixedArray(2, TENURED);
+ CHECK(heap->old_space()->Contains(*array));
+ array->set(0, reinterpret_cast<Object*>(fake_object), SKIP_WRITE_BARRIER);
+
+ // Firstly, let's test the regular slots buffer entry.
+ buffer->Add(HeapObject::RawField(*array, FixedArray::kHeaderSize));
+ DCHECK(reinterpret_cast<void*>(buffer->Get(0)) ==
+ HeapObject::RawField(*array, FixedArray::kHeaderSize));
+ SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer,
+ array->address(),
+ array->address() + array->Size());
+ DCHECK(reinterpret_cast<void*>(buffer->Get(0)) ==
+ HeapObject::RawField(heap->empty_fixed_array(),
+ FixedArrayBase::kLengthOffset));
+
+ // Secondly, let's test the typed slots buffer entry.
+ SlotsBuffer::AddTo(NULL, &buffer, SlotsBuffer::EMBEDDED_OBJECT_SLOT,
+ array->address() + FixedArray::kHeaderSize,
+ SlotsBuffer::FAIL_ON_OVERFLOW);
+ DCHECK(reinterpret_cast<void*>(buffer->Get(1)) ==
+ reinterpret_cast<Object**>(SlotsBuffer::EMBEDDED_OBJECT_SLOT));
+ DCHECK(reinterpret_cast<void*>(buffer->Get(2)) ==
+ HeapObject::RawField(*array, FixedArray::kHeaderSize));
+ SlotsBuffer::RemoveObjectSlots(CcTest::i_isolate()->heap(), buffer,
+ array->address(),
+ array->address() + array->Size());
+ DCHECK(reinterpret_cast<void*>(buffer->Get(1)) ==
+ HeapObject::RawField(heap->empty_fixed_array(),
+ FixedArrayBase::kLengthOffset));
+ DCHECK(reinterpret_cast<void*>(buffer->Get(2)) ==
+ HeapObject::RawField(heap->empty_fixed_array(),
+ FixedArrayBase::kLengthOffset));
+ delete buffer;
+}
diff --git a/deps/v8/test/cctest/test-hydrogen-types.cc b/deps/v8/test/cctest/test-hydrogen-types.cc
index 0ac53bde09..93fdf7b32d 100644
--- a/deps/v8/test/cctest/test-hydrogen-types.cc
+++ b/deps/v8/test/cctest/test-hydrogen-types.cc
@@ -8,7 +8,6 @@
using namespace v8::internal;
-
static const HType kTypes[] = {
#define DECLARE_TYPE(Name, mask) HType::Name(),
HTYPE_LIST(DECLARE_TYPE)
diff --git a/deps/v8/test/cctest/test-log.cc b/deps/v8/test/cctest/test-log.cc
index 90245b7882..0938a9ede2 100644
--- a/deps/v8/test/cctest/test-log.cc
+++ b/deps/v8/test/cctest/test-log.cc
@@ -482,7 +482,7 @@ TEST(EquivalenceOfLoggingAndTraversal) {
i::Vector<const char> source = TestSources::GetScriptsSource();
v8::Handle<v8::String> source_str = v8::String::NewFromUtf8(
isolate, source.start(), v8::String::kNormalString, source.length());
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
v8::Handle<v8::Script> script = CompileWithOrigin(source_str, "");
if (script.IsEmpty()) {
v8::String::Utf8Value exception(try_catch.Exception());
diff --git a/deps/v8/test/cctest/test-microtask-delivery.cc b/deps/v8/test/cctest/test-microtask-delivery.cc
index 601290cf3a..5befdfba9f 100644
--- a/deps/v8/test/cctest/test-microtask-delivery.cc
+++ b/deps/v8/test/cctest/test-microtask-delivery.cc
@@ -29,7 +29,6 @@
#include "test/cctest/cctest.h"
-using namespace v8;
namespace i = v8::internal;
namespace {
@@ -38,7 +37,7 @@ class HarmonyIsolate {
HarmonyIsolate() {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- isolate_ = Isolate::New(create_params);
+ isolate_ = v8::Isolate::New(create_params);
isolate_->Enter();
}
@@ -47,17 +46,17 @@ class HarmonyIsolate {
isolate_->Dispose();
}
- Isolate* GetIsolate() const { return isolate_; }
+ v8::Isolate* GetIsolate() const { return isolate_; }
private:
- Isolate* isolate_;
+ v8::Isolate* isolate_;
};
}
TEST(MicrotaskDeliverySimple) {
HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
+ v8::HandleScope scope(isolate.GetIsolate());
LocalContext context(isolate.GetIsolate());
CompileRun(
"var ordering = [];"
@@ -95,16 +94,16 @@ TEST(MicrotaskDeliverySimple) {
TEST(MicrotaskPerIsolateState) {
HarmonyIsolate isolate;
- HandleScope scope(isolate.GetIsolate());
+ v8::HandleScope scope(isolate.GetIsolate());
LocalContext context1(isolate.GetIsolate());
isolate.GetIsolate()->SetAutorunMicrotasks(false);
CompileRun(
"var obj = { calls: 0 };");
- Handle<Value> obj = CompileRun("obj");
+ v8::Handle<v8::Value> obj = CompileRun("obj");
{
LocalContext context2(isolate.GetIsolate());
- context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
- obj);
+ context2->Global()->Set(
+ v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj);
CompileRun(
"var resolver = {};"
"new Promise(function(resolve) {"
@@ -118,8 +117,8 @@ TEST(MicrotaskPerIsolateState) {
}
{
LocalContext context3(isolate.GetIsolate());
- context3->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
- obj);
+ context3->Global()->Set(
+ v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj);
CompileRun(
"var foo = { id: 1 };"
"Object.observe(foo, function() {"
@@ -129,8 +128,8 @@ TEST(MicrotaskPerIsolateState) {
}
{
LocalContext context4(isolate.GetIsolate());
- context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"),
- obj);
+ context4->Global()->Set(
+ v8::String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj);
isolate.GetIsolate()->RunMicrotasks();
CHECK_EQ(2, CompileRun("obj.calls")->Int32Value());
}
diff --git a/deps/v8/test/cctest/test-migrations.cc b/deps/v8/test/cctest/test-migrations.cc
index 14bdcea3c6..0cefd54ceb 100644
--- a/deps/v8/test/cctest/test-migrations.cc
+++ b/deps/v8/test/cctest/test-migrations.cc
@@ -503,8 +503,7 @@ TEST(ReconfigureAccessorToNonExistingDataFieldHeavy) {
CHECK(obj->map()->instance_descriptors()->GetValue(0)->IsAccessorPair());
Handle<Object> value(Smi::FromInt(42), isolate);
- JSObject::SetOwnPropertyIgnoreAttributes(
- obj, foo_str, value, NONE, JSObject::DONT_FORCE_FIELD).ToHandleChecked();
+ JSObject::SetOwnPropertyIgnoreAttributes(obj, foo_str, value, NONE).Check();
// Check that the property contains |value|.
CHECK_EQ(1, obj->map()->NumberOfOwnDescriptors());
diff --git a/deps/v8/test/cctest/test-parsing.cc b/deps/v8/test/cctest/test-parsing.cc
index 58a5955685..cbb79b16da 100644
--- a/deps/v8/test/cctest/test-parsing.cc
+++ b/deps/v8/test/cctest/test-parsing.cc
@@ -73,7 +73,6 @@ TEST(ScanKeywords) {
i::Scanner scanner(&unicode_cache);
// The scanner should parse Harmony keywords for this test.
scanner.SetHarmonyModules(true);
- scanner.SetHarmonyClasses(true);
scanner.Initialize(&stream);
CHECK_EQ(key_token.token, scanner.Next());
CHECK_EQ(i::Token::EOS, scanner.Next());
@@ -277,7 +276,7 @@ TEST(PreparseFunctionDataIsUsed) {
for (unsigned i = 0; i < arraysize(good_code); i++) {
v8::ScriptCompiler::Source good_source(v8_str(good_code[i]));
v8::ScriptCompiler::Compile(isolate, &good_source,
- v8::ScriptCompiler::kProduceDataToCache);
+ v8::ScriptCompiler::kProduceParserCache);
const v8::ScriptCompiler::CachedData* cached_data =
good_source.GetCachedData();
@@ -291,7 +290,9 @@ TEST(PreparseFunctionDataIsUsed) {
v8_str(bad_code[i]), new v8::ScriptCompiler::CachedData(
cached_data->data, cached_data->length));
v8::Local<v8::Value> result =
- v8::ScriptCompiler::Compile(isolate, &bad_source)->Run();
+ v8::ScriptCompiler::Compile(isolate, &bad_source,
+ v8::ScriptCompiler::kConsumeParserCache)
+ ->Run();
CHECK(result->IsInt32());
CHECK_EQ(25, result->Int32Value());
}
@@ -976,10 +977,10 @@ TEST(ScopeUsesArgumentsSuperThis) {
SUPER_PROPERTY = 1 << 1,
THIS = 1 << 2,
INNER_ARGUMENTS = 1 << 3,
- INNER_SUPER_PROPERTY = 1 << 4,
- INNER_THIS = 1 << 5
+ EVAL = 1 << 4
};
+ // clang-format off
static const struct {
const char* body;
int expected;
@@ -992,8 +993,8 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"return this + arguments[0]", ARGUMENTS | THIS},
{"return this + arguments[0] + super.x",
ARGUMENTS | SUPER_PROPERTY | THIS},
- {"return x => this + x", INNER_THIS},
- {"return x => super.f() + x", INNER_SUPER_PROPERTY},
+ {"return x => this + x", THIS},
+ {"return x => super.f() + x", SUPER_PROPERTY},
{"this.foo = 42;", THIS},
{"this.foo();", THIS},
{"if (foo()) { this.f() }", THIS},
@@ -1006,9 +1007,7 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"while (true) { while (true) { while (true) return this } }", THIS},
{"while (true) { while (true) { while (true) return super.f() } }",
SUPER_PROPERTY},
- {"if (1) { return () => { while (true) new this() } }", INNER_THIS},
- // Note that propagation of the inner_uses_this() value does not
- // cross boundaries of normal functions onto parent scopes.
+ {"if (1) { return () => { while (true) new this() } }", THIS},
{"return function (x) { return this + x }", NONE},
{"return { m(x) { return super.m() + x } }", NONE},
{"var x = function () { this.foo = 42 };", NONE},
@@ -1019,17 +1018,22 @@ TEST(ScopeUsesArgumentsSuperThis) {
{"return { m(x) { return () => super.m() } }", NONE},
// Flags must be correctly set when using block scoping.
{"\"use strict\"; while (true) { let x; this, arguments; }",
- INNER_ARGUMENTS | INNER_THIS},
+ INNER_ARGUMENTS | THIS},
{"\"use strict\"; while (true) { let x; this, super.f(), arguments; }",
- INNER_ARGUMENTS | INNER_SUPER_PROPERTY | INNER_THIS},
- {"\"use strict\"; if (foo()) { let x; this.f() }", INNER_THIS},
- {"\"use strict\"; if (foo()) { let x; super.f() }",
- INNER_SUPER_PROPERTY},
+ INNER_ARGUMENTS | SUPER_PROPERTY | THIS},
+ {"\"use strict\"; if (foo()) { let x; this.f() }", THIS},
+ {"\"use strict\"; if (foo()) { let x; super.f() }", SUPER_PROPERTY},
{"\"use strict\"; if (1) {"
" let x; return { m() { return this + super.m() + arguments } }"
"}",
NONE},
+ {"eval(42)", EVAL},
+ {"if (1) { eval(42) }", EVAL},
+ {"eval('super.x')", EVAL},
+ {"eval('this.x')", EVAL},
+ {"eval('arguments')", EVAL},
};
+ // clang-format on
i::Isolate* isolate = CcTest::i_isolate();
i::Factory* factory = isolate->factory();
@@ -1045,7 +1049,6 @@ TEST(ScopeUsesArgumentsSuperThis) {
for (unsigned i = 0; i < arraysize(source_data); ++i) {
// Super property is only allowed in constructor and method.
if (((source_data[i].expected & SUPER_PROPERTY) ||
- (source_data[i].expected & INNER_SUPER_PROPERTY) ||
(source_data[i].expected == NONE)) && j != 2) {
continue;
}
@@ -1063,8 +1066,6 @@ TEST(ScopeUsesArgumentsSuperThis) {
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
parser.set_allow_harmony_arrow_functions(true);
- parser.set_allow_harmony_classes(true);
- parser.set_allow_harmony_object_literals(true);
parser.set_allow_harmony_sloppy(true);
info.set_global();
CHECK(parser.Parse(&info));
@@ -1086,18 +1087,71 @@ TEST(ScopeUsesArgumentsSuperThis) {
scope->uses_arguments());
CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0,
scope->uses_super_property());
- CHECK_EQ((source_data[i].expected & THIS) != 0, scope->uses_this());
+ if ((source_data[i].expected & THIS) != 0) {
+ // Currently the is_used() flag is conservative; all variables in a
+ // script scope are marked as used.
+ CHECK(scope->LookupThis()->is_used());
+ }
CHECK_EQ((source_data[i].expected & INNER_ARGUMENTS) != 0,
scope->inner_uses_arguments());
- CHECK_EQ((source_data[i].expected & INNER_SUPER_PROPERTY) != 0,
- scope->inner_uses_super_property());
- CHECK_EQ((source_data[i].expected & INNER_THIS) != 0,
- scope->inner_uses_this());
+ CHECK_EQ((source_data[i].expected & EVAL) != 0, scope->calls_eval());
}
}
}
+static void CheckParsesToNumber(const char* source, bool with_dot) {
+ v8::V8::Initialize();
+ HandleAndZoneScope handles;
+
+ i::Isolate* isolate = CcTest::i_isolate();
+ i::Factory* factory = isolate->factory();
+
+ std::string full_source = "function f() { return ";
+ full_source += source;
+ full_source += "; }";
+
+ i::Handle<i::String> source_code =
+ factory->NewStringFromUtf8(i::CStrVector(full_source.c_str()))
+ .ToHandleChecked();
+
+ i::Handle<i::Script> script = factory->NewScript(source_code);
+
+ i::ParseInfo info(handles.main_zone(), script);
+ i::Parser parser(&info);
+ parser.set_allow_harmony_arrow_functions(true);
+ parser.set_allow_harmony_sloppy(true);
+ info.set_global();
+ info.set_lazy(false);
+ info.set_allow_lazy_parsing(false);
+ info.set_toplevel(true);
+
+ i::CompilationInfo compilation_info(&info);
+ CHECK(i::Compiler::ParseAndAnalyze(&info));
+
+ CHECK(info.scope()->declarations()->length() == 1);
+ i::FunctionLiteral* fun =
+ info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
+ CHECK(fun->body()->length() == 1);
+ CHECK(fun->body()->at(0)->IsReturnStatement());
+ i::ReturnStatement* ret = fun->body()->at(0)->AsReturnStatement();
+ CHECK(ret->expression()->IsLiteral());
+ i::Literal* lit = ret->expression()->AsLiteral();
+ const i::AstValue* val = lit->raw_value();
+ CHECK(with_dot == val->ContainsDot());
+}
+
+
+TEST(ParseNumbers) {
+ CheckParsesToNumber("1.34", true);
+ CheckParsesToNumber("134", false);
+ CheckParsesToNumber("134e44", false);
+ CheckParsesToNumber("134.e44", true);
+ CheckParsesToNumber("134.44e44", true);
+ CheckParsesToNumber(".44", true);
+}
+
+
TEST(ScopePositions) {
// Test the parser for correctly setting the start and end positions
// of a scope. We check the scope positions of exactly one scope
@@ -1348,40 +1402,24 @@ const char* ReadString(unsigned* start) {
i::Handle<i::String> FormatMessage(i::Vector<unsigned> data) {
i::Isolate* isolate = CcTest::i_isolate();
- i::Factory* factory = isolate->factory();
- const char* message =
- ReadString(&data[i::PreparseDataConstants::kMessageTextPos]);
- i::Handle<i::String> format = v8::Utils::OpenHandle(
- *v8::String::NewFromUtf8(CcTest::isolate(), message));
+ int message = data[i::PreparseDataConstants::kMessageTemplatePos];
int arg_count = data[i::PreparseDataConstants::kMessageArgCountPos];
- const char* arg = NULL;
- i::Handle<i::JSArray> args_array;
+ i::Handle<i::Object> arg_object;
if (arg_count == 1) {
// Position after text found by skipping past length field and
// length field content words.
- int pos = i::PreparseDataConstants::kMessageTextPos + 1 +
- data[i::PreparseDataConstants::kMessageTextPos];
- arg = ReadString(&data[pos]);
- args_array = factory->NewJSArray(1);
- i::JSArray::SetElement(args_array, 0, v8::Utils::OpenHandle(*v8_str(arg)),
- NONE, i::SLOPPY).Check();
+ const char* arg =
+ ReadString(&data[i::PreparseDataConstants::kMessageArgPos]);
+ arg_object =
+ v8::Utils::OpenHandle(*v8::String::NewFromUtf8(CcTest::isolate(), arg));
+ i::DeleteArray(arg);
} else {
CHECK_EQ(0, arg_count);
- args_array = factory->NewJSArray(0);
+ arg_object = isolate->factory()->undefined_value();
}
- i::Handle<i::JSObject> builtins(isolate->js_builtins_object());
- i::Handle<i::Object> format_fun =
- i::Object::GetProperty(isolate, builtins, "$formatMessage")
- .ToHandleChecked();
- i::Handle<i::Object> arg_handles[] = { format, args_array };
- i::Handle<i::Object> result = i::Execution::Call(
- isolate, format_fun, builtins, 2, arg_handles).ToHandleChecked();
- CHECK(result->IsString());
- i::DeleteArray(message);
- i::DeleteArray(arg);
data.Dispose();
- return i::Handle<i::String>::cast(result);
+ return i::MessageTemplate::FormatMessage(isolate, message, arg_object);
}
@@ -1390,15 +1428,16 @@ enum ParserFlag {
kAllowNatives,
kAllowHarmonyModules,
kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonyRestParameters,
kAllowHarmonySloppy,
kAllowHarmonyUnicode,
kAllowHarmonyComputedPropertyNames,
kAllowHarmonySpreadCalls,
kAllowHarmonyDestructuring,
- kAllowStrongMode
+ kAllowHarmonySpreadArrays,
+ kAllowHarmonyNewTarget,
+ kAllowStrongMode,
+ kNoLegacyConst
};
@@ -1414,11 +1453,8 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
parser->set_allow_lazy(flags.Contains(kAllowLazy));
parser->set_allow_natives(flags.Contains(kAllowNatives));
parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules));
- parser->set_allow_harmony_object_literals(
- flags.Contains(kAllowHarmonyObjectLiterals));
parser->set_allow_harmony_arrow_functions(
flags.Contains(kAllowHarmonyArrowFunctions));
- parser->set_allow_harmony_classes(flags.Contains(kAllowHarmonyClasses));
parser->set_allow_harmony_rest_params(
flags.Contains(kAllowHarmonyRestParameters));
parser->set_allow_harmony_spreadcalls(
@@ -1429,7 +1465,11 @@ void SetParserFlags(i::ParserBase<Traits>* parser,
flags.Contains(kAllowHarmonyComputedPropertyNames));
parser->set_allow_harmony_destructuring(
flags.Contains(kAllowHarmonyDestructuring));
+ parser->set_allow_harmony_spread_arrays(
+ flags.Contains(kAllowHarmonySpreadArrays));
+ parser->set_allow_harmony_new_target(flags.Contains(kAllowHarmonyNewTarget));
parser->set_allow_strong_mode(flags.Contains(kAllowStrongMode));
+ parser->set_allow_legacy_const(!flags.Contains(kNoLegacyConst));
}
@@ -1702,7 +1742,7 @@ TEST(StrictOctal) {
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(
v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
const char* script =
"\"use strict\"; \n"
"a = function() { \n"
@@ -1982,8 +2022,7 @@ TEST(NoErrorsFutureStrictReservedWords) {
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
- static const ParserFlag classes_flags[] = {kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses};
+ static const ParserFlag classes_flags[] = {kAllowHarmonyArrowFunctions};
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
classes_flags, arraysize(classes_flags));
}
@@ -2996,10 +3035,7 @@ TEST(NoErrorsDeclsInCase) {
nullptr
};
- static const ParserFlag always_flags[] = {kAllowHarmonyClasses};
-
- RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -3579,6 +3615,10 @@ TEST(ErrorsArrowFunctions) {
"(foo ? bar : baz) => {}",
"(a, foo ? bar : baz) => {}",
"(foo ? bar : baz, a) => {}",
+ "(a.b, c) => {}",
+ "(c, a.b) => {}",
+ "(a['b'], c) => {}",
+ "(c, a['b']) => {}",
NULL
};
@@ -3727,8 +3767,6 @@ TEST(SuperNoErrors) {
static const ParserFlag always_flags[] = {
kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
@@ -3759,11 +3797,7 @@ TEST(SuperErrors) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonySloppy};
RunParserSyncTest(context_data, expression_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -3779,12 +3813,8 @@ TEST(SuperCall) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions,
+ kAllowHarmonySloppy};
RunParserSyncTest(context_data, success_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
@@ -3834,12 +3864,8 @@ TEST(SuperNewNoErrors) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions,
+ kAllowHarmonySloppy};
RunParserSyncTest(context_data, expression_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -3872,12 +3898,8 @@ TEST(SuperNewErrors) {
NULL
};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyArrowFunctions,
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
- kAllowHarmonySloppy
- };
+ static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions,
+ kAllowHarmonySloppy};
RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -3918,8 +3940,6 @@ TEST(SuperErrorsNonMethods) {
};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
@@ -3943,9 +3963,7 @@ TEST(NoErrorsMethodDefinition) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, object_literal_body_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, object_literal_body_data, kSuccess);
}
@@ -4019,9 +4037,7 @@ TEST(MethodDefinitionNames) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kSuccess);
}
@@ -4040,9 +4056,7 @@ TEST(MethodDefinitionStrictFormalParamereters) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, params_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, params_data, kError);
}
@@ -4061,15 +4075,11 @@ TEST(MethodDefinitionEvalArguments) {
"arguments",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
-
// Fail in strict mode
- RunParserSyncTest(strict_context_data, data, kError, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(strict_context_data, data, kError);
// OK in sloppy mode
- RunParserSyncTest(sloppy_context_data, data, kSuccess, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(sloppy_context_data, data, kSuccess);
}
@@ -4088,12 +4098,9 @@ TEST(MethodDefinitionDuplicateEvalArguments) {
"arguments, a, arguments",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
-
// In strict mode, the error is using "eval" or "arguments" as parameter names
// In sloppy mode, the error is that eval / arguments are duplicated
- RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
- arraysize(always_flags));
+ RunParserSyncTest(context_data, data, kError);
}
@@ -4127,9 +4134,7 @@ TEST(MethodDefinitionDuplicateProperty) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, params_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, params_data, kSuccess);
}
@@ -4151,8 +4156,7 @@ TEST(ClassExpressionNoErrors) {
"class name extends class base {} {}",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses, kAllowHarmonySloppy};
+ static const ParserFlag always_flags[] = {kAllowHarmonySloppy};
RunParserSyncTest(context_data, class_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -4171,9 +4175,7 @@ TEST(ClassDeclarationNoErrors) {
"class name extends class base {} {}",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyClasses};
- RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, statement_data, kSuccess);
}
@@ -4215,8 +4217,6 @@ TEST(ClassBodyNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
@@ -4274,8 +4274,6 @@ TEST(ClassPropertyNameNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
@@ -4306,8 +4304,6 @@ TEST(ClassExpressionErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_data, kError, NULL, 0,
@@ -4344,7 +4340,6 @@ TEST(ClassDeclarationErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_data, kError, NULL, 0,
@@ -4374,8 +4369,6 @@ TEST(ClassNameErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_name, kError, NULL, 0,
@@ -4408,8 +4401,6 @@ TEST(ClassGetterParamNameErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_name, kError, NULL, 0,
@@ -4437,8 +4428,6 @@ TEST(ClassStaticPrototypeErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4465,8 +4454,6 @@ TEST(ClassSpecialConstructorErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4488,8 +4475,6 @@ TEST(ClassConstructorNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
@@ -4507,8 +4492,6 @@ TEST(ClassMultipleConstructorErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4530,8 +4513,6 @@ TEST(ClassMultiplePropertyNamesNoErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
@@ -4551,8 +4532,6 @@ TEST(ClassesAreStrictErrors) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy
};
RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
@@ -4605,9 +4584,7 @@ TEST(ObjectLiteralPropertyShorthandKeywordsError) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kError);
}
@@ -4628,14 +4605,11 @@ TEST(ObjectLiteralPropertyShorthandStrictKeywords) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kSuccess);
const char* context_strict_data[][2] = {{"'use strict'; ({", "});"},
{NULL, NULL}};
- RunParserSyncTest(context_strict_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_strict_data, name_data, kError);
}
@@ -4657,9 +4631,7 @@ TEST(ObjectLiteralPropertyShorthandError) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kError);
}
@@ -4672,9 +4644,7 @@ TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) {
NULL
};
- static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
- RunParserSyncTest(context_data, name_data, kError, NULL, 0,
- always_flags, arraysize(always_flags));
+ RunParserSyncTest(context_data, name_data, kError);
}
@@ -5136,6 +5106,24 @@ TEST(ParseRestParametersErrors) {
}
+TEST(RestParameterInSetterMethodError) {
+ const char* context_data[][2] = {
+ {"'use strict';({ set prop(", ") {} }).prop = 1;"},
+ {"'use strict';(class { static set prop(", ") {} }).prop = 1;"},
+ {"'use strict';(new (class { set prop(", ") {} })).prop = 1;"},
+ {"({ set prop(", ") {} }).prop = 1;"},
+ {"(class { static set prop(", ") {} }).prop = 1;"},
+ {"(new (class { set prop(", ") {} })).prop = 1;"},
+ {nullptr, nullptr}};
+ const char* data[] = {"...a", "...arguments", "...eval", nullptr};
+
+ static const ParserFlag always_flags[] = {kAllowHarmonyRestParameters,
+ kAllowHarmonySloppy};
+ RunParserSyncTest(context_data, data, kError, nullptr, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
TEST(RestParametersEvalArguments) {
const char* strict_context_data[][2] =
{{"'use strict';(function(",
@@ -5253,18 +5241,15 @@ TEST(LexicalScopingSloppyMode) {
"(class C {})",
"(class C extends D {})",
NULL};
- static const ParserFlag always_true_flags[] = {kAllowHarmonyClasses};
static const ParserFlag always_false_flags[] = {kAllowHarmonySloppy};
- RunParserSyncTest(context_data, bad_data, kError, NULL, 0,
- always_true_flags, arraysize(always_true_flags),
+ RunParserSyncTest(context_data, bad_data, kError, NULL, 0, NULL, 0,
always_false_flags, arraysize(always_false_flags));
const char* good_data[] = {
"let = 1;",
"for(let = 1;;){}",
NULL};
- RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0,
- always_true_flags, arraysize(always_true_flags),
+ RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0, NULL, 0,
always_false_flags, arraysize(always_false_flags));
}
@@ -5286,9 +5271,7 @@ TEST(ComputedPropertyName) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy,
};
RunParserSyncTest(context_data, error_data, kError, NULL, 0,
@@ -5317,9 +5300,7 @@ TEST(ComputedPropertyNameShorthandError) {
NULL};
static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses,
kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
kAllowHarmonySloppy,
};
RunParserSyncTest(context_data, error_data, kError, NULL, 0,
@@ -5387,7 +5368,6 @@ TEST(BasicImportExportParsing) {
i::Zone zone;
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
- parser.set_allow_harmony_classes(true);
parser.set_allow_harmony_modules(true);
info.set_module();
if (!parser.Parse(&info)) {
@@ -5414,7 +5394,6 @@ TEST(BasicImportExportParsing) {
i::Zone zone;
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
- parser.set_allow_harmony_classes(true);
parser.set_allow_harmony_modules(true);
info.set_global();
CHECK(!parser.Parse(&info));
@@ -5504,7 +5483,6 @@ TEST(ImportExportParsingErrors) {
i::Zone zone;
i::ParseInfo info(&zone, script);
i::Parser parser(&info);
- parser.set_allow_harmony_classes(true);
parser.set_allow_harmony_modules(true);
info.set_module();
CHECK(!parser.Parse(&info));
@@ -5617,7 +5595,6 @@ TEST(DuplicateProtoNoError) {
static const ParserFlag always_flags[] = {
kAllowHarmonyComputedPropertyNames,
- kAllowHarmonyObjectLiterals,
};
RunParserSyncTest(context_data, error_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
@@ -5645,8 +5622,7 @@ TEST(DeclarationsError) {
"class C {}",
NULL};
- static const ParserFlag always_flags[] = {kAllowHarmonyClasses,
- kAllowStrongMode};
+ static const ParserFlag always_flags[] = {kAllowStrongMode};
RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -5730,8 +5706,7 @@ TEST(PropertyNameEvalArguments) {
NULL};
- static const ParserFlag always_flags[] = {
- kAllowHarmonyClasses, kAllowHarmonyObjectLiterals, kAllowStrongMode};
+ static const ParserFlag always_flags[] = {kAllowStrongMode};
RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
always_flags, arraysize(always_flags));
}
@@ -5915,10 +5890,8 @@ TEST(StrongConstructorThis) {
"class C { constructor() { label: 0; this.a = 0; this.b = 6; } }",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowStrongMode, kAllowHarmonyClasses, kAllowHarmonyObjectLiterals,
- kAllowHarmonyArrowFunctions
- };
+ static const ParserFlag always_flags[] = {kAllowStrongMode,
+ kAllowHarmonyArrowFunctions};
RunParserSyncTest(sloppy_context_data, error_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(strict_context_data, error_data, kSuccess, NULL, 0,
@@ -5971,10 +5944,8 @@ TEST(StrongConstructorSuper) {
"class C extends Object { constructor() { 3; super(3); this.x = 0; } }",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowStrongMode, kAllowHarmonyClasses, kAllowHarmonyObjectLiterals,
- kAllowHarmonyArrowFunctions
- };
+ static const ParserFlag always_flags[] = {kAllowStrongMode,
+ kAllowHarmonyArrowFunctions};
RunParserSyncTest(sloppy_context_data, error_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(strict_context_data, error_data, kSuccess, NULL, 0,
@@ -6019,9 +5990,7 @@ TEST(StrongConstructorReturns) {
"class C extends Array { constructor() { super(); this.a = 9; return } }",
NULL};
- static const ParserFlag always_flags[] = {
- kAllowStrongMode, kAllowHarmonyClasses, kAllowHarmonyObjectLiterals
- };
+ static const ParserFlag always_flags[] = {kAllowStrongMode};
RunParserSyncTest(sloppy_context_data, error_data, kError, NULL, 0,
always_flags, arraysize(always_flags));
RunParserSyncTest(strict_context_data, error_data, kSuccess, NULL, 0,
@@ -6219,7 +6188,7 @@ TEST(StrongModeFreeVariablesDeclaredByPreviousScript) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
// Introduce a bunch of variables, in all language modes.
const char* script1 =
@@ -6278,7 +6247,7 @@ TEST(StrongModeFreeVariablesDeclaredByLanguage) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
const char* script1 =
"\"use strong\"; \n"
@@ -6294,7 +6263,7 @@ TEST(StrongModeFreeVariablesDeclaredInGlobalPrototype) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
const char* script1 = "this.__proto__.my_var = 0;\n";
CompileRun(v8_str(script1));
@@ -6313,7 +6282,7 @@ TEST(StrongModeFreeVariablesNotDeclared) {
v8::V8::Initialize();
v8::HandleScope scope(CcTest::isolate());
v8::Context::Scope context_scope(v8::Context::New(CcTest::isolate()));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(CcTest::isolate());
// Test that referencing unintroduced variables in sloppy mode is ok.
const char* script1 =
@@ -6330,7 +6299,7 @@ TEST(StrongModeFreeVariablesNotDeclared) {
"if (false) { \n"
" not_there2; \n"
"} \n";
- v8::TryCatch try_catch2;
+ v8::TryCatch try_catch2(CcTest::isolate());
v8::Script::Compile(v8_str(script2));
CHECK(try_catch2.HasCaught());
v8::String::Utf8Value exception(try_catch2.Exception());
@@ -6351,7 +6320,7 @@ TEST(StrongModeFreeVariablesNotDeclared) {
" not_there3; \n"
" } \n"
"})(); \n";
- v8::TryCatch try_catch2;
+ v8::TryCatch try_catch2(CcTest::isolate());
v8::Script::Compile(v8_str(script3));
CHECK(try_catch2.HasCaught());
v8::String::Utf8Value exception(try_catch2.Exception());
@@ -6366,30 +6335,59 @@ TEST(StrongModeFreeVariablesNotDeclared) {
TEST(DestructuringPositiveTests) {
i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
{"var ", " = {};"},
{"'use strict'; const ", " = {};"},
+ {"function f(", ") {}"},
+ {"function f(argument1, ", ") {}"},
+ {"var f = (", ") => {};"},
+ {"var f = (argument1,", ") => {};"},
{NULL, NULL}};
// clang-format off
const char* data[] = {
"a",
"{ x : y }",
+ "{ x : y = 1 }",
"[a]",
+ "[a = 1]",
"[a,b,c]",
+ "[a, b = 42, c]",
"{ x : x, y : y }",
+ "{ x : x = 1, y : y }",
+ "{ x : x, y : y = 42 }",
"[]",
"{}",
"[{x:x, y:y}, [a,b,c]]",
+ "[{x:x = 1, y:y = 2}, [a = 3, b = 4, c = 5]]",
+ "{x}",
+ "{x, y}",
+ "{x = 42, y = 15}",
"[a,,b]",
"{42 : x}",
+ "{42 : x = 42}",
"{42e-2 : x}",
+ "{42e-2 : x = 42}",
+ "{x : y, x : z}",
"{'hi' : x}",
+ "{'hi' : x = 42}",
"{var: x}",
+ "{var: x = 42}",
+ "{[x] : z}",
+ "{[1+1] : z}",
+ "{[foo()] : z}",
+ "{}",
+ "[...rest]",
+ "[a,b,...rest]",
+ "[a,,...rest]",
NULL};
// clang-format on
- static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring};
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
arraysize(always_flags));
}
@@ -6397,12 +6395,21 @@ TEST(DestructuringPositiveTests) {
TEST(DestructuringNegativeTests) {
i::FLAG_harmony_destructuring = true;
- static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring};
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
{ // All modes.
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
{"var ", " = {};"},
{"'use strict'; const ", " = {};"},
+ {"function f(", ") {}"},
+ {"function f(argument1, ", ") {}"},
+ {"var f = (", ") => {};"},
+ {"var f = ", " => {};"},
+ {"var f = (argument1,", ") => {};"},
{NULL, NULL}};
// clang-format off
@@ -6435,7 +6442,6 @@ TEST(DestructuringNegativeTests) {
"a >>> a",
"function a() {}",
"a`bcd`",
- "x => x",
"this",
"null",
"true",
@@ -6443,25 +6449,61 @@ TEST(DestructuringNegativeTests) {
"1",
"'abc'",
"class {}",
- "() => x",
"{+2 : x}",
"{-2 : x}",
"var",
"[var]",
"{x : {y : var}}",
+ "{x : x = a+}",
+ "{x : x = (a+)}",
+ "{x : x += a}",
+ "{m() {} = 0}",
+ "{[1+1]}",
+ "[...rest, x]",
+ "[a,b,...rest, x]",
+ "[a,,...rest, x]",
+ "[...rest,]",
+ "[a,b,...rest,]",
+ "[a,,...rest,]",
+ "[...rest,...rest1]",
+ "[a,b,...rest,...rest1]",
+ "[a,,..rest,...rest1]",
NULL};
// clang-format on
RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
arraysize(always_flags));
}
- { // Strict mode.
+ { // All modes.
const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
+ {"var ", " = {};"},
{"'use strict'; const ", " = {};"},
+ {"function f(", ") {}"},
+ {"function f(argument1, ", ") {}"},
+ {"var f = (", ") => {};"},
+ {"var f = (argument1,", ") => {};"},
{NULL, NULL}};
// clang-format off
const char* data[] = {
+ "x => x",
+ "() => x",
+ NULL};
+ // clang-format on
+ RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+ }
+
+ { // Strict mode.
+ const char* context_data[][2] = {
+ {"'use strict'; let ", " = {};"},
+ {"'use strict'; const ", " = {};"},
+ {"'use strict'; function f(", ") {}"},
+ {"'use strict'; function f(argument1, ", ") {}"},
+ {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
"[eval]",
"{ a : arguments }",
"[public]",
@@ -6490,3 +6532,261 @@ TEST(DestructuringNegativeTests) {
arraysize(always_flags));
}
}
+
+
+TEST(DestructuringDisallowPatternsInForVarIn) {
+ i::FLAG_harmony_destructuring = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {
+ {"", ""}, {"function f() {", "}"}, {NULL, NULL}};
+ // clang-format off
+ const char* error_data[] = {
+ "for (let x = {} in null);",
+ "for (let x = {} of null);",
+ NULL};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+
+ // clang-format off
+ const char* success_data[] = {
+ "for (var x = {} in null);",
+ NULL};
+ // clang-format on
+ RunParserSyncTest(context_data, success_data, kSuccess, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDuplicateParams) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {{"'use strict';", ""},
+ {"function outer() { 'use strict';", "}"},
+ {nullptr, nullptr}};
+
+
+ // clang-format off
+ const char* error_data[] = {
+ "function f(x,x){}",
+ "function f(x, {x : x}){}",
+ "function f(x, {x}){}",
+ "function f({x,x}) {}",
+ "function f([x,x]) {}",
+ "function f(x, [y,{z:x}]) {}",
+ "function f([x,{y:x}]) {}",
+ // non-simple parameter list causes duplicates to be errors in sloppy mode.
+ "function f(x, x, {a}) {}",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDuplicateParamsSloppy) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {
+ {"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}};
+
+
+ // clang-format off
+ const char* error_data[] = {
+ // non-simple parameter list causes duplicates to be errors in sloppy mode.
+ "function f(x, {x : x}){}",
+ "function f(x, {x}){}",
+ "function f({x,x}) {}",
+ "function f(x, x, {a}) {}",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDisallowPatternsInSingleParamArrows) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {kAllowHarmonyComputedPropertyNames,
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {{"'use strict';", ""},
+ {"function outer() { 'use strict';", "}"},
+ {"", ""},
+ {"function outer() { ", "}"},
+ {nullptr, nullptr}};
+
+ // clang-format off
+ const char* error_data[] = {
+ "var f = {x} => {};",
+ "var f = {x,y} => {};",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(DestructuringDisallowPatternsInRestParams) {
+ i::FLAG_harmony_destructuring = true;
+ i::FLAG_harmony_arrow_functions = true;
+ i::FLAG_harmony_rest_parameters = true;
+ i::FLAG_harmony_computed_property_names = true;
+ static const ParserFlag always_flags[] = {
+ kAllowHarmonyComputedPropertyNames, kAllowHarmonyArrowFunctions,
+ kAllowHarmonyRestParameters, kAllowHarmonyDestructuring};
+ const char* context_data[][2] = {{"'use strict';", ""},
+ {"function outer() { 'use strict';", "}"},
+ {"", ""},
+ {"function outer() { ", "}"},
+ {nullptr, nullptr}};
+
+ // clang-format off
+ const char* error_data[] = {
+ "function(...{}) {}",
+ "function(...{x}) {}",
+ "function(...[x]) {}",
+ "(...{}) => {}",
+ "(...{x}) => {}",
+ "(...[x]) => {}",
+ nullptr};
+ // clang-format on
+ RunParserSyncTest(context_data, error_data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(SpreadArray) {
+ i::FLAG_harmony_spread_arrays = true;
+
+ const char* context_data[][2] = {
+ {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
+ "[...a]",
+ "[a, ...b]",
+ "[...a,]",
+ "[...a, ,]",
+ "[, ...a]",
+ "[...a, ...b]",
+ "[...a, , ...b]",
+ "[...[...a]]",
+ "[, ...a]",
+ "[, , ...a]",
+ NULL};
+ // clang-format on
+ static const ParserFlag always_flags[] = {kAllowHarmonySpreadArrays};
+ RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(SpreadArrayError) {
+ i::FLAG_harmony_spread_arrays = true;
+
+ const char* context_data[][2] = {
+ {"'use strict';", ""}, {"", ""}, {NULL, NULL}};
+
+ // clang-format off
+ const char* data[] = {
+ "[...]",
+ "[a, ...]",
+ "[..., ]",
+ "[..., ...]",
+ "[ (...a)]",
+ NULL};
+ // clang-format on
+ static const ParserFlag always_flags[] = {kAllowHarmonySpreadArrays};
+ RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(NewTarget) {
+ // clang-format off
+ const char* good_context_data[][2] = {
+ {"function f() {", "}"},
+ {"'use strict'; function f() {", "}"},
+ {"var f = function() {", "}"},
+ {"'use strict'; var f = function() {", "}"},
+ {"({m: function() {", "}})"},
+ {"'use strict'; ({m: function() {", "}})"},
+ {"({m() {", "}})"},
+ {"'use strict'; ({m() {", "}})"},
+ {"({get x() {", "}})"},
+ {"'use strict'; ({get x() {", "}})"},
+ {"({set x(_) {", "}})"},
+ {"'use strict'; ({set x(_) {", "}})"},
+ {"class C {m() {", "}}"},
+ {"class C {get x() {", "}}"},
+ {"class C {set x(_) {", "}}"},
+ {NULL}
+ };
+
+ const char* bad_context_data[][2] = {
+ {"", ""},
+ {"'use strict';", ""},
+ {NULL}
+ };
+
+ const char* data[] = {
+ "new.target",
+ "{ new.target }",
+ "() => { new.target }",
+ "() => new.target",
+ "if (1) { new.target }",
+ "if (1) {} else { new.target }",
+ "while (0) { new.target }",
+ "do { new.target } while (0)",
+ NULL
+ };
+
+ static const ParserFlag always_flags[] = {
+ kAllowHarmonyArrowFunctions,
+ kAllowHarmonyNewTarget,
+ kAllowHarmonySloppy,
+ };
+ // clang-format on
+
+ RunParserSyncTest(good_context_data, data, kSuccess, NULL, 0, always_flags,
+ arraysize(always_flags));
+ RunParserSyncTest(bad_context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+}
+
+
+TEST(LegacyConst) {
+ // clang-format off
+ const char* context_data[][2] = {
+ {"", ""},
+ {"{", "}"},
+ {NULL, NULL}
+ };
+
+ const char* data[] = {
+ "const x",
+ "const x = 1",
+ "for (const x = 1; x < 1; x++) {}",
+ "for (const x in {}) {}",
+ "for (const x of []) {}",
+ NULL
+ };
+ // clang-format on
+
+ static const ParserFlag always_flags[] = {kNoLegacyConst};
+
+ RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+ arraysize(always_flags));
+ RunParserSyncTest(context_data, data, kSuccess);
+}
diff --git a/deps/v8/test/cctest/test-profile-generator.cc b/deps/v8/test/cctest/test-profile-generator.cc
index 0a2c7a5625..221761487c 100644
--- a/deps/v8/test/cctest/test-profile-generator.cc
+++ b/deps/v8/test/cctest/test-profile-generator.cc
@@ -681,14 +681,13 @@ TEST(BailoutReason) {
CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Handle<v8::Script> script =
v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(),
- "function TryCatch() {\n"
- " try {\n"
- " startProfiling();\n"
- " } catch (e) { };\n"
+ "function Debugger() {\n"
+ " debugger;\n"
+ " startProfiling();\n"
"}\n"
"function TryFinally() {\n"
" try {\n"
- " TryCatch();\n"
+ " Debugger();\n"
" } finally { };\n"
"}\n"
"TryFinally();\n"
@@ -703,8 +702,8 @@ TEST(BailoutReason) {
// The tree should look like this:
// (root)
// ""
- // kTryFinally
- // kTryCatch
+ // kTryFinallyStatement
+ // kDebuggerStatement
current = PickChild(current, "");
CHECK(const_cast<v8::CpuProfileNode*>(current));
@@ -712,7 +711,7 @@ TEST(BailoutReason) {
CHECK(const_cast<v8::CpuProfileNode*>(current));
CHECK(!strcmp("TryFinallyStatement", current->GetBailoutReason()));
- current = PickChild(current, "TryCatch");
+ current = PickChild(current, "Debugger");
CHECK(const_cast<v8::CpuProfileNode*>(current));
- CHECK(!strcmp("TryCatchStatement", current->GetBailoutReason()));
+ CHECK(!strcmp("DebuggerStatement", current->GetBailoutReason()));
}
diff --git a/deps/v8/test/cctest/test-reloc-info.cc b/deps/v8/test/cctest/test-reloc-info.cc
index a238c3a7d8..829fd24f4d 100644
--- a/deps/v8/test/cctest/test-reloc-info.cc
+++ b/deps/v8/test/cctest/test-reloc-info.cc
@@ -66,8 +66,8 @@ TEST(Positions) {
writer.Finish();
relocation_info_size = static_cast<int>(buffer_end - writer.pos());
- CodeDesc desc = { buffer.get(), buffer_size, code_size,
- relocation_info_size, NULL };
+ CodeDesc desc = {buffer.get(), buffer_size, code_size, relocation_info_size,
+ 0, NULL};
// Read only (non-statement) positions.
{
@@ -120,4 +120,5 @@ TEST(Positions) {
}
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index 938178efb9..0bae94e219 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -493,7 +493,7 @@ UNINITIALIZED_DEPENDENT_TEST(ContextDeserialization, ContextSerialization) {
&outdated_contexts).ToHandleChecked();
CHECK(root->IsContext());
CHECK(Handle<Context>::cast(root)->global_proxy() == *global_proxy);
- CHECK_EQ(1, outdated_contexts->length());
+ CHECK_EQ(2, outdated_contexts->length());
}
Handle<Object> root2;
@@ -628,13 +628,13 @@ UNINITIALIZED_DEPENDENT_TEST(CustomContextDeserialization,
root =
deserializer.DeserializePartial(isolate, global_proxy,
&outdated_contexts).ToHandleChecked();
- CHECK_EQ(2, outdated_contexts->length());
+ CHECK_EQ(3, outdated_contexts->length());
CHECK(root->IsContext());
Handle<Context> context = Handle<Context>::cast(root);
CHECK(context->global_proxy() == *global_proxy);
Handle<String> o = isolate->factory()->NewStringFromAsciiChecked("o");
Handle<JSObject> global_object(context->global_object(), isolate);
- Handle<Object> property = JSObject::GetDataProperty(global_object, o);
+ Handle<Object> property = JSReceiver::GetDataProperty(global_object, o);
CHECK(property.is_identical_to(global_proxy));
v8::Handle<v8::Context> v8_context = v8::Utils::ToLocal(context);
@@ -859,7 +859,7 @@ static Handle<SharedFunctionInfo> CompileScript(
Isolate* isolate, Handle<String> source, Handle<String> name,
ScriptData** cached_data, v8::ScriptCompiler::CompileOptions options) {
return Compiler::CompileScript(
- source, name, 0, 0, false, false, Handle<Object>(),
+ source, name, 0, 0, v8::ScriptOriginOptions(), Handle<Object>(),
Handle<Context>(isolate->native_context()), NULL, cached_data, options,
NOT_NATIVES_CODE, false);
}
@@ -938,7 +938,7 @@ TEST(CodeCachePromotedToCompilationCache) {
isolate, src, src, &cache, v8::ScriptCompiler::kConsumeCodeCache);
CHECK(isolate->compilation_cache()
- ->LookupScript(src, src, 0, 0, false, false,
+ ->LookupScript(src, src, 0, 0, v8::ScriptOriginOptions(),
isolate->native_context(), SLOPPY)
.ToHandleChecked()
.is_identical_to(copy));
@@ -1098,11 +1098,11 @@ TEST(SerializeToplevelLargeStrings) {
Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
CHECK_EQ(6 * 1999999, Handle<String>::cast(copy_result)->length());
- Handle<Object> property = JSObject::GetDataProperty(
+ Handle<Object> property = JSReceiver::GetDataProperty(
isolate->global_object(), f->NewStringFromAsciiChecked("s"));
CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
- property = JSObject::GetDataProperty(isolate->global_object(),
- f->NewStringFromAsciiChecked("t"));
+ property = JSReceiver::GetDataProperty(isolate->global_object(),
+ f->NewStringFromAsciiChecked("t"));
CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
// Make sure we do not serialize too much, e.g. include the source string.
CHECK_LT(cache->length(), 13000000);
@@ -1595,7 +1595,6 @@ TEST(SerializeInternalReference) {
return;
#endif
// Disable experimental natives that are loaded after deserialization.
- FLAG_turbo_deoptimization = false;
FLAG_context_specialization = false;
FLAG_always_opt = true;
const char* flag = "--turbo-filter=foo";
@@ -1659,6 +1658,31 @@ TEST(SerializeInternalReference) {
}
+TEST(Regress503552) {
+ // Test that the code serializer can deal with weak cells that form a linked
+ // list during incremental marking.
+
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+
+ HandleScope scope(isolate);
+ Handle<String> source = isolate->factory()->NewStringFromAsciiChecked(
+ "function f() {} function g() {}");
+ ScriptData* script_data = NULL;
+ Handle<SharedFunctionInfo> shared = Compiler::CompileScript(
+ source, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
+ Handle<Object>(), Handle<Context>(isolate->native_context()), NULL,
+ &script_data, v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE,
+ false);
+ delete script_data;
+
+ SimulateIncrementalMarking(isolate->heap());
+
+ script_data = CodeSerializer::Serialize(isolate, shared, source);
+ delete script_data;
+}
+
+
TEST(SerializationMemoryStats) {
FLAG_profile_deserialization = true;
FLAG_always_opt = false;
diff --git a/deps/v8/test/cctest/test-spaces.cc b/deps/v8/test/cctest/test-spaces.cc
index 9d22327831..3f5e437223 100644
--- a/deps/v8/test/cctest/test-spaces.cc
+++ b/deps/v8/test/cctest/test-spaces.cc
@@ -145,7 +145,8 @@ class TestCodeRangeScope {
DISALLOW_COPY_AND_ASSIGN(TestCodeRangeScope);
};
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
static void VerifyMemoryChunk(Isolate* isolate,
@@ -358,8 +359,9 @@ TEST(NewSpace) {
CHECK(new_space.HasBeenSetUp());
while (new_space.Available() >= Page::kMaxRegularHeapObjectSize) {
- Object* obj = new_space.AllocateRaw(
- Page::kMaxRegularHeapObjectSize).ToObjectChecked();
+ Object* obj =
+ new_space.AllocateRawUnaligned(Page::kMaxRegularHeapObjectSize)
+ .ToObjectChecked();
CHECK(new_space.Contains(HeapObject::cast(obj)));
}
@@ -384,7 +386,7 @@ TEST(OldSpace) {
CHECK(s->SetUp());
while (s->Available() > 0) {
- s->AllocateRaw(Page::kMaxRegularHeapObjectSize).ToObjectChecked();
+ s->AllocateRawUnaligned(Page::kMaxRegularHeapObjectSize).ToObjectChecked();
}
s->TearDown();
@@ -437,6 +439,9 @@ TEST(SizeOfFirstPageIsLargeEnough) {
if (!isolate->snapshot_available()) return;
if (Snapshot::EmbedsScript(isolate)) return;
+ // If this test fails due to enabling experimental natives that are not part
+ // of the snapshot, we may need to adjust CalculateFirstPageSizes.
+
// Freshly initialized VM gets by with one page per space.
for (int i = FIRST_PAGED_SPACE; i <= LAST_PAGED_SPACE; i++) {
// Debug code can be very large, so skip CODE_SPACE if we are generating it.
@@ -485,7 +490,8 @@ UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
// Try to allocate out of the new space. A new page should be added and
// the
// allocation should succeed.
- v8::internal::AllocationResult allocation = new_space->AllocateRaw(80);
+ v8::internal::AllocationResult allocation =
+ new_space->AllocateRawUnaligned(80);
CHECK(!allocation.IsRetry());
CHECK(new_space->CommittedMemory() == 2 * Page::kPageSize);
diff --git a/deps/v8/test/cctest/test-strings.cc b/deps/v8/test/cctest/test-strings.cc
index 1713e91662..d8d7c96871 100644
--- a/deps/v8/test/cctest/test-strings.cc
+++ b/deps/v8/test/cctest/test-strings.cc
@@ -1222,7 +1222,7 @@ UNINITIALIZED_TEST(OneByteArrayJoin) {
// summing the lengths of the strings (as Smis) overflows and wraps.
LocalContext context(isolate);
v8::HandleScope scope(isolate);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(CompileRun(
"var two_14 = Math.pow(2, 14);"
"var two_17 = Math.pow(2, 17);"
diff --git a/deps/v8/test/cctest/test-thread-termination.cc b/deps/v8/test/cctest/test-thread-termination.cc
index 250e9a344a..c0cc1cb8d1 100644
--- a/deps/v8/test/cctest/test-thread-termination.cc
+++ b/deps/v8/test/cctest/test-thread-termination.cc
@@ -61,7 +61,7 @@ void Loop(const v8::FunctionCallbackInfo<v8::Value>& args) {
void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"function f() {"
@@ -86,7 +86,7 @@ void DoLoop(const v8::FunctionCallbackInfo<v8::Value>& args) {
void DoLoopNoCall(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"var term = true;"
@@ -217,7 +217,7 @@ void TerminateOrReturnObject(const v8::FunctionCallbackInfo<v8::Value>& args) {
void LoopGetProperty(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating(args.GetIsolate()));
v8::Script::Compile(
v8::String::NewFromUtf8(args.GetIsolate(),
@@ -275,7 +275,7 @@ v8::Persistent<v8::String> reenter_script_1;
v8::Persistent<v8::String> reenter_script_2;
void ReenterAfterTermination(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
v8::Isolate* isolate = args.GetIsolate();
CHECK(!v8::V8::IsExecutionTerminating(isolate));
v8::Local<v8::String> script =
@@ -328,7 +328,7 @@ TEST(TerminateAndReenterFromThreadItself) {
void DoLoopCancelTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(args.GetIsolate());
CHECK(!v8::V8::IsExecutionTerminating());
v8::Script::Compile(v8::String::NewFromUtf8(args.GetIsolate(),
"var term = true;"
@@ -426,7 +426,7 @@ TEST(PostponeTerminateException) {
v8::Context::New(CcTest::isolate(), NULL, global);
v8::Context::Scope context_scope(context);
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
static const char* terminate_and_loop =
"terminate(); for (var i = 0; i < 10000; i++);";
@@ -504,7 +504,7 @@ TEST(TerminationInInnerTryCall) {
v8::Context::New(CcTest::isolate(), NULL, global_template);
v8::Context::Scope context_scope(context);
{
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CompileRun("inner_try_call_terminate()");
CHECK(try_catch.HasTerminated());
}
@@ -522,7 +522,7 @@ TEST(TerminateAndTryCall) {
v8::Handle<v8::Context> context = v8::Context::New(isolate, NULL, global);
v8::Context::Scope context_scope(context);
CHECK(!v8::V8::IsExecutionTerminating(isolate));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
CHECK(!v8::V8::IsExecutionTerminating(isolate));
// Terminate execution has been triggered inside TryCall, but re-requested
// to trigger later.
diff --git a/deps/v8/test/cctest/test-threads.cc b/deps/v8/test/cctest/test-threads.cc
index e192bc1559..5f2cdae2a2 100644
--- a/deps/v8/test/cctest/test-threads.cc
+++ b/deps/v8/test/cctest/test-threads.cc
@@ -32,12 +32,7 @@
#include "src/isolate.h"
-enum Turn {
- FILL_CACHE,
- CLEAN_CACHE,
- SECOND_TIME_FILL_CACHE,
- DONE
-};
+enum Turn { FILL_CACHE, CLEAN_CACHE, SECOND_TIME_FILL_CACHE, CACHE_DONE };
static Turn turn = FILL_CACHE;
@@ -76,7 +71,7 @@ class ThreadA : public v8::base::Thread {
// Rerun the script.
CHECK(script->Run()->IsTrue());
- turn = DONE;
+ turn = CACHE_DONE;
}
};
@@ -116,7 +111,7 @@ TEST(JSFunctionResultCachesInTwoThreads) {
threadA.Join();
threadB.Join();
- CHECK_EQ(DONE, turn);
+ CHECK_EQ(CACHE_DONE, turn);
}
class ThreadIdValidationThread : public v8::base::Thread {
diff --git a/deps/v8/test/cctest/test-typedarrays.cc b/deps/v8/test/cctest/test-typedarrays.cc
index d371673b9e..394f6194fd 100644
--- a/deps/v8/test/cctest/test-typedarrays.cc
+++ b/deps/v8/test/cctest/test-typedarrays.cc
@@ -48,7 +48,7 @@ TEST(CopyContentsArray) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CompileRun("var a = new Uint8Array([0, 1, 2, 3]);");
- TestArrayBufferViewContents(env, true);
+ TestArrayBufferViewContents(env, false);
}
diff --git a/deps/v8/test/cctest/test-types.cc b/deps/v8/test/cctest/test-types.cc
index 295cef6d36..fe07093077 100644
--- a/deps/v8/test/cctest/test-types.cc
+++ b/deps/v8/test/cctest/test-types.cc
@@ -1020,15 +1020,10 @@ struct Tests : Rep {
CheckSub(T.Proxy, T.Receiver);
CheckSub(T.OtherObject, T.Object);
CheckSub(T.Undetectable, T.Object);
- CheckSub(T.DetectableObject, T.Object);
- CheckSub(T.GlobalObject, T.DetectableObject);
- CheckSub(T.OtherObject, T.DetectableObject);
- CheckSub(T.GlobalObject, T.Object);
- CheckSub(T.GlobalObject, T.Receiver);
+ CheckSub(T.OtherObject, T.Object);
CheckUnordered(T.Object, T.Proxy);
- CheckUnordered(T.GlobalObject, T.OtherObject);
- CheckUnordered(T.DetectableObject, T.Undetectable);
+ CheckUnordered(T.OtherObject, T.Undetectable);
// Subtyping between concrete structural types
@@ -1350,7 +1345,6 @@ struct Tests : Rep {
CheckDisjoint(T.InternalizedString, T.Symbol);
CheckOverlap(T.Object, T.Receiver);
CheckOverlap(T.OtherObject, T.Object);
- CheckOverlap(T.GlobalObject, T.Object);
CheckOverlap(T.Proxy, T.Receiver);
CheckDisjoint(T.Object, T.Proxy);
@@ -1505,6 +1499,7 @@ struct Tests : Rep {
void Union3() {
// Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+ HandleScope scope(isolate);
for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) {
TypeHandle type1 = *it1;
@@ -1757,6 +1752,7 @@ struct Tests : Rep {
// Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+ HandleScope scope(isolate);
for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
TypeHandle type1 = *it1;
@@ -1963,66 +1959,6 @@ struct Tests : Rep {
}
}
}
-
- void GlobalObjectType() {
- i::Handle<i::Context> context1 = v8::Utils::OpenHandle(
- *v8::Context::New(reinterpret_cast<v8::Isolate*>(isolate)));
- Handle<i::GlobalObject> global_object1(context1->global_object());
- TypeHandle GlobalObjectConstant1 =
- Type::Constant(global_object1, Rep::ToRegion(&zone, isolate));
-
- i::Handle<i::Context> context2 = v8::Utils::OpenHandle(
- *v8::Context::New(reinterpret_cast<v8::Isolate*>(isolate)));
- Handle<i::GlobalObject> global_object2(context2->global_object());
- TypeHandle GlobalObjectConstant2 =
- Type::Constant(global_object2, Rep::ToRegion(&zone, isolate));
-
- CheckSub(GlobalObjectConstant1, T.DetectableObject);
- CheckSub(GlobalObjectConstant2, T.DetectableObject);
- CheckSub(GlobalObjectConstant1, T.GlobalObject);
- CheckSub(GlobalObjectConstant2, T.GlobalObject);
- CheckSub(GlobalObjectConstant1, T.Object);
- CheckSub(GlobalObjectConstant2, T.Object);
-
- CheckUnordered(T.GlobalObject, T.OtherObject);
- CheckUnordered(GlobalObjectConstant1, T.OtherObject);
- CheckUnordered(GlobalObjectConstant2, T.OtherObject);
- CheckUnordered(GlobalObjectConstant1, GlobalObjectConstant2);
-
- CheckDisjoint(T.GlobalObject, T.ObjectClass);
- CheckDisjoint(GlobalObjectConstant1, T.ObjectClass);
- CheckDisjoint(GlobalObjectConstant2, T.ArrayClass);
-
- CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), T.GlobalObject);
- CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), GlobalObjectConstant1);
- CheckUnordered(T.Union(T.ObjectClass, T.ArrayClass), GlobalObjectConstant2);
-
- CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass), T.GlobalObject);
- CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass),
- GlobalObjectConstant1);
- CheckUnordered(T.Union(T.ObjectConstant1, T.ArrayClass),
- GlobalObjectConstant2);
-
- CheckUnordered(T.Union(T.ObjectClass, T.String), T.GlobalObject);
-
- CheckSub(T.Union(T.ObjectConstant1, T.ArrayClass),
- T.Union(T.GlobalObject, T.Object));
-
- CheckDisjoint(T.Union(GlobalObjectConstant1, T.ArrayClass),
- GlobalObjectConstant2);
-
- CheckEqual(T.Union(T.Union(T.Number, GlobalObjectConstant1),
- T.Union(T.SignedSmall, T.GlobalObject)),
- T.Union(T.Number, T.GlobalObject));
-
- CheckEqual(T.Semantic(T.Intersect(T.ObjectClass, T.GlobalObject)), T.None);
-
- CHECK(!T.Intersect(T.ArrayClass, GlobalObjectConstant2)->IsInhabited());
-
- CheckEqual(T.Intersect(T.Union(T.Number, T.OtherObject),
- T.Union(T.Signed32, T.GlobalObject)),
- T.Signed32);
- }
};
typedef Tests<Type, Type*, Zone, ZoneRep> ZoneTests;
@@ -2197,9 +2133,3 @@ TEST(HTypeFromType_zone) { ZoneTests().HTypeFromType(); }
TEST(HTypeFromType_heap) { HeapTests().HTypeFromType(); }
-
-
-TEST(GlobalObjectType_zone) { ZoneTests().GlobalObjectType(); }
-
-
-TEST(GlobalObjectType_heap) { HeapTests().GlobalObjectType(); }
diff --git a/deps/v8/test/cctest/test-unboxed-doubles.cc b/deps/v8/test/cctest/test-unboxed-doubles.cc
index 89f58a62e4..4746e47322 100644
--- a/deps/v8/test/cctest/test-unboxed-doubles.cc
+++ b/deps/v8/test/cctest/test-unboxed-doubles.cc
@@ -1035,7 +1035,7 @@ TEST(DoScavenge) {
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
@@ -1088,7 +1088,8 @@ TEST(DoScavengeWithIncrementalWriteBarrier) {
AlwaysAllocateScope always_allocate(isolate);
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
}
@@ -1373,7 +1374,7 @@ TEST(StoreBufferScanOnScavenge) {
CHECK(isolate->heap()->old_space()->Contains(*obj));
// Create temp object in the new space.
- Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+ Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
CHECK(isolate->heap()->new_space()->Contains(*temp));
// Construct a double value that looks like a pointer to the new space object
@@ -1572,7 +1573,8 @@ static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map,
// Make sure |obj_value| is placed on an old-space evacuation candidate.
SimulateFullSpace(old_space);
- obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, TENURED);
+ obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
+ Strength::WEAK, TENURED);
ec_page = Page::FromAddress(obj_value->address());
CHECK_NE(ec_page, Page::FromAddress(obj->address()));
}
diff --git a/deps/v8/test/cctest/test-utils-arm64.h b/deps/v8/test/cctest/test-utils-arm64.h
index d00ad5e78c..a091bf3932 100644
--- a/deps/v8/test/cctest/test-utils-arm64.h
+++ b/deps/v8/test/cctest/test-utils-arm64.h
@@ -96,13 +96,13 @@ class RegisterDump {
return dump_.sp_;
}
- inline int64_t wspreg() const {
+ inline int32_t wspreg() const {
DCHECK(SPRegAliasesMatch());
- return dump_.wsp_;
+ return static_cast<int32_t>(dump_.wsp_);
}
// Flags accessors.
- inline uint64_t flags_nzcv() const {
+ inline uint32_t flags_nzcv() const {
DCHECK(IsComplete());
DCHECK((dump_.flags_ & ~Flags_mask) == 0);
return dump_.flags_ & Flags_mask;
diff --git a/deps/v8/test/cctest/test-version.cc b/deps/v8/test/cctest/test-version.cc
index 7de4467d6b..50fca16871 100644
--- a/deps/v8/test/cctest/test-version.cc
+++ b/deps/v8/test/cctest/test-version.cc
@@ -46,7 +46,8 @@ void SetVersion(int major, int minor, int build, int patch,
Version::soname_ = soname;
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
static void CheckVersion(int major, int minor, int build,
diff --git a/deps/v8/test/cctest/test-weakmaps.cc b/deps/v8/test/cctest/test-weakmaps.cc
index 64d2876887..31b812e287 100644
--- a/deps/v8/test/cctest/test-weakmaps.cc
+++ b/deps/v8/test/cctest/test-weakmaps.cc
@@ -34,7 +34,6 @@
using namespace v8::internal;
-
static Isolate* GetIsolateFrom(LocalContext* context) {
return reinterpret_cast<Isolate*>((*context)->GetIsolate());
}
@@ -89,8 +88,10 @@ TEST(Weakness) {
Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
Handle<JSObject> object = factory->NewJSObjectFromMap(map);
Handle<Smi> smi(Smi::FromInt(23), isolate);
- Runtime::WeakCollectionSet(weakmap, key, object);
- Runtime::WeakCollectionSet(weakmap, object, smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakmap, key, object, hash);
+ int32_t object_hash = Object::GetOrCreateHash(isolate, object)->value();
+ Runtime::WeakCollectionSet(weakmap, object, smi, object_hash);
}
CHECK_EQ(2, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
@@ -145,7 +146,8 @@ TEST(Shrinking) {
for (int i = 0; i < 32; i++) {
Handle<JSObject> object = factory->NewJSObjectFromMap(map);
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakmap, object, smi);
+ int32_t object_hash = Object::GetOrCreateHash(isolate, object)->value();
+ Runtime::WeakCollectionSet(weakmap, object, smi, object_hash);
}
}
@@ -193,7 +195,8 @@ TEST(Regress2060a) {
Handle<JSObject> object = factory->NewJSObject(function, TENURED);
CHECK(!heap->InNewSpace(object->address()));
CHECK(!first_page->Contains(object->address()));
- Runtime::WeakCollectionSet(weakmap, key, object);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakmap, key, object, hash);
}
}
@@ -235,7 +238,8 @@ TEST(Regress2060b) {
Handle<JSWeakMap> weakmap = AllocateJSWeakMap(isolate);
for (int i = 0; i < 32; i++) {
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakmap, keys[i], smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, keys[i])->value();
+ Runtime::WeakCollectionSet(weakmap, keys[i], smi, hash);
}
// Force compacting garbage collection. The subsequent collections are used
diff --git a/deps/v8/test/cctest/test-weaksets.cc b/deps/v8/test/cctest/test-weaksets.cc
index dbb7311e83..3595af288f 100644
--- a/deps/v8/test/cctest/test-weaksets.cc
+++ b/deps/v8/test/cctest/test-weaksets.cc
@@ -34,7 +34,6 @@
using namespace v8::internal;
-
static Isolate* GetIsolateFrom(LocalContext* context) {
return reinterpret_cast<Isolate*>((*context)->GetIsolate());
}
@@ -90,7 +89,8 @@ TEST(WeakSet_Weakness) {
{
HandleScope scope(isolate);
Handle<Smi> smi(Smi::FromInt(23), isolate);
- Runtime::WeakCollectionSet(weakset, key, smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakset, key, smi, hash);
}
CHECK_EQ(1, ObjectHashTable::cast(weakset->table())->NumberOfElements());
@@ -145,7 +145,8 @@ TEST(WeakSet_Shrinking) {
for (int i = 0; i < 32; i++) {
Handle<JSObject> object = factory->NewJSObjectFromMap(map);
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakset, object, smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, object)->value();
+ Runtime::WeakCollectionSet(weakset, object, smi, hash);
}
}
@@ -193,7 +194,8 @@ TEST(WeakSet_Regress2060a) {
Handle<JSObject> object = factory->NewJSObject(function, TENURED);
CHECK(!heap->InNewSpace(object->address()));
CHECK(!first_page->Contains(object->address()));
- Runtime::WeakCollectionSet(weakset, key, object);
+ int32_t hash = Object::GetOrCreateHash(isolate, key)->value();
+ Runtime::WeakCollectionSet(weakset, key, object, hash);
}
}
@@ -235,7 +237,8 @@ TEST(WeakSet_Regress2060b) {
Handle<JSWeakSet> weakset = AllocateJSWeakSet(isolate);
for (int i = 0; i < 32; i++) {
Handle<Smi> smi(Smi::FromInt(i), isolate);
- Runtime::WeakCollectionSet(weakset, keys[i], smi);
+ int32_t hash = Object::GetOrCreateHash(isolate, keys[i])->value();
+ Runtime::WeakCollectionSet(weakset, keys[i], smi, hash);
}
// Force compacting garbage collection. The subsequent collections are used
diff --git a/deps/v8/test/cctest/trace-extension.cc b/deps/v8/test/cctest/trace-extension.cc
index a95532f931..e7f097f86f 100644
--- a/deps/v8/test/cctest/trace-extension.cc
+++ b/deps/v8/test/cctest/trace-extension.cc
@@ -151,4 +151,5 @@ void TraceExtension::JSEntrySPLevel2(
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8