Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/test/cctest/test-macro-assembler-mips.cc b/test/cctest/test-macro-assembler-mips.cc
index 6cb00e4..696ca01 100644
--- a/test/cctest/test-macro-assembler-mips.cc
+++ b/test/cctest/test-macro-assembler-mips.cc
@@ -26,18 +26,20 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
+#include <iostream> // NOLINT(readability/streams)
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
+#include "src/base/utils/random-number-generator.h"
#include "src/macro-assembler.h"
#include "src/mips/macro-assembler-mips.h"
#include "src/mips/simulator-mips.h"
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
using namespace v8::internal;
typedef void* (*F)(int x, int y, int p2, int p3, int p4);
+typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
#define __ masm->
@@ -60,7 +62,7 @@
TEST(CopyBytes) {
CcTest::InitializeVM();
- Isolate* isolate = Isolate::Current();
+ Isolate* isolate = CcTest::i_isolate();
HandleScope handles(isolate);
const int data_size = 1 * KB;
@@ -80,7 +82,8 @@
byte* a0_;
byte* a1_;
- MacroAssembler assembler(isolate, NULL, 0);
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
MacroAssembler* masm = &assembler;
// Code to be generated: The stuff in CopyBytes followed by a store of a0 and
@@ -111,8 +114,8 @@
for (byte* dest = dest_buffer; dest < dest_buffer + fuzz; dest++) {
memset(dest_buffer, 0, data_size);
CHECK(dest + size < dest_buffer + data_size);
- (void) CALL_GENERATED_CODE(f, reinterpret_cast<int>(src),
- reinterpret_cast<int>(dest), size, 0, 0);
+ (void)CALL_GENERATED_CODE(isolate, f, reinterpret_cast<int>(src),
+ reinterpret_cast<int>(dest), size, 0, 0);
// a0 and a1 should point at the first byte after the copied data.
CHECK_EQ(src + size, a0_);
CHECK_EQ(dest + size, a1_);
@@ -140,18 +143,17 @@
v8::Local<v8::Context> context = CcTest::NewContext(PRINT_EXTENSION);
v8::Context::Scope context_scope(context);
- v8::Local<v8::Script> script = v8::Script::Compile(v8_str(code));
- v8::Local<v8::Object> result = v8::Local<v8::Object>::Cast(script->Run());
- // Have to populate the handle manually, as it's not Cast-able.
- i::Handle<i::JSObject> o =
- v8::Utils::OpenHandle<v8::Object, i::JSObject>(result);
+ v8::Local<v8::Script> script =
+ v8::Script::Compile(context, v8_str(code)).ToLocalChecked();
+ v8::Local<v8::Object> result =
+ v8::Local<v8::Object>::Cast(script->Run(context).ToLocalChecked());
+ i::Handle<i::JSReceiver> o = v8::Utils::OpenHandle(*result);
i::Handle<i::JSArray> array1(reinterpret_cast<i::JSArray*>(*o));
i::FixedDoubleArray* a = i::FixedDoubleArray::cast(array1->elements());
double value = a->get_scalar(0);
CHECK(std::isnan(value) &&
bit_cast<uint64_t>(value) ==
- bit_cast<uint64_t>(
- i::FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
+ bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN()));
}
@@ -175,4 +177,240 @@
}
+TEST(jump_tables4) {
+ // Similar to test-assembler-mips jump_tables1, with extra test for branch
+ // trampoline required before emission of the dd table (where trampolines are
+ // blocked), and proper transition to long-branch mode.
+ // Regression test for v8:4294.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, NULL, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ const int kNumCases = 512;
+ int values[kNumCases];
+ isolate->random_number_generator()->NextBytes(values, sizeof(values));
+ Label labels[kNumCases];
+ Label near_start, end;
+
+ __ addiu(sp, sp, -4);
+ __ sw(ra, MemOperand(sp));
+
+ __ mov(v0, zero_reg);
+
+ __ Branch(&end);
+ __ bind(&near_start);
+
+ // Generate slightly less than 32K instructions, which will soon require
+ // trampoline for branch distance fixup.
+ for (int i = 0; i < 32768 - 256; ++i) {
+ __ addiu(v0, v0, 1);
+ }
+
+ Label done;
+ {
+ __ BlockTrampolinePoolFor(kNumCases + 6);
+ PredictableCodeSizeScope predictable(
+ masm, (kNumCases + 6) * Assembler::kInstrSize);
+ Label here;
+
+ __ bal(&here);
+ __ sll(at, a0, 2); // In delay slot.
+ __ bind(&here);
+ __ addu(at, at, ra);
+ __ lw(at, MemOperand(at, 4 * Assembler::kInstrSize));
+ __ jr(at);
+ __ nop(); // Branch delay slot nop.
+ for (int i = 0; i < kNumCases; ++i) {
+ __ dd(&labels[i]);
+ }
+ }
+
+ for (int i = 0; i < kNumCases; ++i) {
+ __ bind(&labels[i]);
+ __ lui(v0, (values[i] >> 16) & 0xffff);
+ __ ori(v0, v0, values[i] & 0xffff);
+ __ Branch(&done);
+ }
+
+ __ bind(&done);
+ __ lw(ra, MemOperand(sp));
+ __ addiu(sp, sp, 4);
+ __ jr(ra);
+ __ nop();
+
+ __ bind(&end);
+ __ Branch(&near_start);
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ for (int i = 0; i < kNumCases; ++i) {
+ int res =
+ reinterpret_cast<int>(CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %d\n", i, res);
+ CHECK_EQ(values[i], res);
+ }
+}
+
+
+TEST(jump_tables5) {
+ if (!IsMipsArchVariant(kMips32r6)) return;
+
+ // Similar to test-assembler-mips jump_tables1, with extra test for emitting a
+ // compact branch instruction before emission of the dd table.
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, nullptr, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ const int kNumCases = 512;
+ int values[kNumCases];
+ isolate->random_number_generator()->NextBytes(values, sizeof(values));
+ Label labels[kNumCases];
+ Label done;
+
+ __ addiu(sp, sp, -4);
+ __ sw(ra, MemOperand(sp));
+
+ {
+ __ BlockTrampolinePoolFor(kNumCases * 2 + 7 + 1);
+ PredictableCodeSizeScope predictable(
+ masm, kNumCases * kPointerSize + ((7 + 1) * Assembler::kInstrSize));
+ Label here;
+
+ __ bal(&here);
+ __ sll(at, a0, 2); // In delay slot.
+ __ bind(&here);
+ __ addu(at, at, ra);
+ __ lw(at, MemOperand(at, 6 * Assembler::kInstrSize));
+ __ jalr(at);
+ __ nop(); // Branch delay slot nop.
+ __ bc(&done);
+ for (int i = 0; i < kNumCases; ++i) {
+ __ dd(&labels[i]);
+ }
+ }
+
+ for (int i = 0; i < kNumCases; ++i) {
+ __ bind(&labels[i]);
+ __ lui(v0, (values[i] >> 16) & 0xffff);
+ __ ori(v0, v0, values[i] & 0xffff);
+ __ jr(ra);
+ __ nop();
+ }
+
+ __ bind(&done);
+ __ lw(ra, MemOperand(sp));
+ __ addiu(sp, sp, 4);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ masm->GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+ for (int i = 0; i < kNumCases; ++i) {
+ int32_t res = reinterpret_cast<int32_t>(
+ CALL_GENERATED_CODE(isolate, f, i, 0, 0, 0, 0));
+ ::printf("f(%d) = %d\n", i, res);
+ CHECK_EQ(values[i], res);
+ }
+}
+
+
+static uint32_t run_lsa(uint32_t rt, uint32_t rs, int8_t sa) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+ MacroAssembler assembler(isolate, nullptr, 0,
+ v8::internal::CodeObjectRequired::kYes);
+ MacroAssembler* masm = &assembler;
+
+ __ Lsa(v0, a0, a1, sa);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assembler.GetCode(&desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+
+ F1 f = FUNCTION_CAST<F1>(code->entry());
+
+ uint32_t res = reinterpret_cast<uint32_t>(
+ CALL_GENERATED_CODE(isolate, f, rt, rs, 0, 0, 0));
+
+ return res;
+}
+
+
+TEST(Lsa) {
+ CcTest::InitializeVM();
+ struct TestCaseLsa {
+ int32_t rt;
+ int32_t rs;
+ uint8_t sa;
+ uint32_t expected_res;
+ };
+
+ struct TestCaseLsa tc[] = {// rt, rs, sa, expected_res
+ {0x4, 0x1, 1, 0x6},
+ {0x4, 0x1, 2, 0x8},
+ {0x4, 0x1, 3, 0xc},
+ {0x4, 0x1, 4, 0x14},
+ {0x4, 0x1, 5, 0x24},
+ {0x0, 0x1, 1, 0x2},
+ {0x0, 0x1, 2, 0x4},
+ {0x0, 0x1, 3, 0x8},
+ {0x0, 0x1, 4, 0x10},
+ {0x0, 0x1, 5, 0x20},
+ {0x4, 0x0, 1, 0x4},
+ {0x4, 0x0, 2, 0x4},
+ {0x4, 0x0, 3, 0x4},
+ {0x4, 0x0, 4, 0x4},
+ {0x4, 0x0, 5, 0x4},
+
+ // Shift overflow.
+ {0x4, INT32_MAX, 1, 0x2},
+ {0x4, INT32_MAX >> 1, 2, 0x0},
+ {0x4, INT32_MAX >> 2, 3, 0xfffffffc},
+ {0x4, INT32_MAX >> 3, 4, 0xfffffff4},
+ {0x4, INT32_MAX >> 4, 5, 0xffffffe4},
+
+ // Signed addition overflow.
+ {INT32_MAX - 1, 0x1, 1, 0x80000000},
+ {INT32_MAX - 3, 0x1, 2, 0x80000000},
+ {INT32_MAX - 7, 0x1, 3, 0x80000000},
+ {INT32_MAX - 15, 0x1, 4, 0x80000000},
+ {INT32_MAX - 31, 0x1, 5, 0x80000000},
+
+ // Addition overflow.
+ {-2, 0x1, 1, 0x0},
+ {-4, 0x1, 2, 0x0},
+ {-8, 0x1, 3, 0x0},
+ {-16, 0x1, 4, 0x0},
+ {-32, 0x1, 5, 0x0}};
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseLsa);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ uint32_t res = run_lsa(tc[i].rt, tc[i].rs, tc[i].sa);
+ PrintF("0x%x =? 0x%x == lsa(v0, %x, %x, %hhu)\n", tc[i].expected_res, res,
+ tc[i].rt, tc[i].rs, tc[i].sa);
+ CHECK_EQ(tc[i].expected_res, res);
+ }
+}
+
#undef __