OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include <stdlib.h> | 28 #include <stdlib.h> |
29 #include <iostream> // NOLINT(readability/streams) | 29 #include <iostream> // NOLINT(readability/streams) |
30 | 30 |
31 #include "src/base/utils/random-number-generator.h" | 31 #include "src/base/utils/random-number-generator.h" |
32 #include "src/macro-assembler.h" | 32 #include "src/macro-assembler.h" |
33 #include "src/mips/macro-assembler-mips.h" | 33 #include "src/mips/macro-assembler-mips.h" |
34 #include "src/mips/simulator-mips.h" | 34 #include "src/mips/simulator-mips.h" |
35 #include "src/v8.h" | 35 #include "src/v8.h" |
36 #include "test/cctest/cctest.h" | 36 #include "test/cctest/cctest.h" |
37 | 37 #include "test/cctest/heap/heap-utils.h" |
38 | 38 |
39 using namespace v8::internal; | 39 using namespace v8::internal; |
40 | 40 |
41 typedef void* (*F)(int x, int y, int p2, int p3, int p4); | 41 typedef void* (*F)(int x, int y, int p2, int p3, int p4); |
42 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); | 42 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); |
43 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); | 43 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); |
44 | 44 |
45 #define __ masm-> | 45 #define __ masm-> |
46 | 46 |
47 | 47 |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 static_cast<int32_t>(0xffffffff)}; | 406 static_cast<int32_t>(0xffffffff)}; |
407 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]); | 407 return std::vector<int32_t>(&kValues[0], &kValues[arraysize(kValues)]); |
408 } | 408 } |
409 | 409 |
410 // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... } | 410 // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... } |
411 #define FOR_INPUTS(ctype, itype, var, test_vector) \ | 411 #define FOR_INPUTS(ctype, itype, var, test_vector) \ |
412 std::vector<ctype> var##_vec = test_vector(); \ | 412 std::vector<ctype> var##_vec = test_vector(); \ |
413 for (std::vector<ctype>::iterator var = var##_vec.begin(); \ | 413 for (std::vector<ctype>::iterator var = var##_vec.begin(); \ |
414 var != var##_vec.end(); ++var) | 414 var != var##_vec.end(); ++var) |
415 | 415 |
416 #define FOR_INPUTS2(ctype, itype, var, var2, test_vector) \ | 416 #define FOR_INPUTS2(ctype, itype, var, vat1, test_vector) \ |
417 std::vector<ctype> var##_vec = test_vector(); \ | 417 std::vector<ctype> var##_vec = test_vector(); \ |
418 std::vector<ctype>::iterator var; \ | 418 std::vector<ctype>::iterator var; \ |
419 std::vector<ctype>::reverse_iterator var2; \ | 419 std::vector<ctype>::reverse_iterator vat1; \ |
420 for (var = var##_vec.begin(), var2 = var##_vec.rbegin(); \ | 420 for (var = var##_vec.begin(), vat1 = var##_vec.rbegin(); \ |
421 var != var##_vec.end(); ++var, ++var2) | 421 var != var##_vec.end(); ++var, ++vat1) |
422 | 422 |
423 #define FOR_ENUM_INPUTS(var, type, test_vector) \ | 423 #define FOR_ENUM_INPUTS(var, type, test_vector) \ |
424 FOR_INPUTS(enum type, type, var, test_vector) | 424 FOR_INPUTS(enum type, type, var, test_vector) |
425 #define FOR_STRUCT_INPUTS(var, type, test_vector) \ | 425 #define FOR_STRUCT_INPUTS(var, type, test_vector) \ |
426 FOR_INPUTS(struct type, type, var, test_vector) | 426 FOR_INPUTS(struct type, type, var, test_vector) |
427 #define FOR_UINT32_INPUTS(var, test_vector) \ | 427 #define FOR_UINT32_INPUTS(var, test_vector) \ |
428 FOR_INPUTS(uint32_t, uint32, var, test_vector) | 428 FOR_INPUTS(uint32_t, uint32, var, test_vector) |
429 #define FOR_INT32_INPUTS(var, test_vector) \ | 429 #define FOR_INT32_INPUTS(var, test_vector) \ |
430 FOR_INPUTS(int32_t, int32, var, test_vector) | 430 FOR_INPUTS(int32_t, int32, var, test_vector) |
431 #define FOR_INT32_INPUTS2(var, var2, test_vector) \ | 431 #define FOR_INT32_INPUTS2(var, vat1, test_vector) \ |
432 FOR_INPUTS2(int32_t, int32, var, var2, test_vector) | 432 FOR_INPUTS2(int32_t, int32, var, vat1, test_vector) |
433 | 433 |
434 #define FOR_UINT64_INPUTS(var, test_vector) \ | 434 #define FOR_UINT64_INPUTS(var, test_vector) \ |
435 FOR_INPUTS(uint64_t, uint32, var, test_vector) | 435 FOR_INPUTS(uint64_t, uint32, var, test_vector) |
436 | 436 |
437 template <typename RET_TYPE, typename IN_TYPE, typename Func> | 437 template <typename RET_TYPE, typename IN_TYPE, typename Func> |
438 RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) { | 438 RET_TYPE run_Cvt(IN_TYPE x, Func GenerateConvertInstructionFunc) { |
439 typedef RET_TYPE (*F_CVT)(IN_TYPE x0, int x1, int x2, int x3, int x4); | 439 typedef RET_TYPE (*F_CVT)(IN_TYPE x0, int x1, int x2, int x3, int x4); |
440 | 440 |
441 Isolate* isolate = CcTest::i_isolate(); | 441 Isolate* isolate = CcTest::i_isolate(); |
442 HandleScope scope(isolate); | 442 HandleScope scope(isolate); |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 [](MacroAssembler* masm, int32_t in_offset, | 1161 [](MacroAssembler* masm, int32_t in_offset, |
1162 int32_t out_offset) { | 1162 int32_t out_offset) { |
1163 __ Uldc1(f0, MemOperand(a0, in_offset), t0); | 1163 __ Uldc1(f0, MemOperand(a0, in_offset), t0); |
1164 __ Usdc1(f0, MemOperand(a0, out_offset), t0); | 1164 __ Usdc1(f0, MemOperand(a0, out_offset), t0); |
1165 })); | 1165 })); |
1166 } | 1166 } |
1167 } | 1167 } |
1168 } | 1168 } |
1169 } | 1169 } |
1170 | 1170 |
| 1171 template <typename Fun> |
| 1172 void AssembleFunction(Isolate* isolate, size_t actual_size, byte* buffer, |
| 1173 Fun f) { |
| 1174 MacroAssembler assembler(isolate, buffer, static_cast<int>(actual_size), |
| 1175 v8::internal::CodeObjectRequired::kYes); |
| 1176 MacroAssembler* masm = &assembler; |
| 1177 f(masm); |
| 1178 __ jr(ra); |
| 1179 |
| 1180 CodeDesc desc; |
| 1181 masm->GetCode(&desc); |
| 1182 } |
| 1183 |
| 1184 TEST(AllocateMacrosNoGCRequired) { |
| 1185 typedef intptr_t (*F0)(); |
| 1186 // Allocate an executable page of memory. |
| 1187 CcTest::InitializeVM(); |
| 1188 size_t actual_size; |
| 1189 byte* buffer = static_cast<byte*>(v8::base::OS::Allocate( |
| 1190 Assembler::kMinimalBufferSize, &actual_size, true)); |
| 1191 CHECK(buffer); |
| 1192 Isolate* isolate = CcTest::i_isolate(); |
| 1193 HandleScope handles(isolate); |
| 1194 |
| 1195 AllocationFlags const kDoubleAligned = |
| 1196 static_cast<AllocationFlags>(DOUBLE_ALIGNMENT); |
| 1197 AllocationFlags const kNoAllocationFlags = |
| 1198 static_cast<AllocationFlags>(NO_ALLOCATION_FLAGS); |
| 1199 |
| 1200 #define CHECK_TAGGED(result) CHECK_EQ(result& kHeapObjectTag, 1); |
| 1201 #define CHECK_DOUBLE_ALIGNED(result) \ |
| 1202 do { \ |
| 1203 CHECK_TAGGED((result)); \ |
| 1204 CHECK_EQ((result)&kDoubleAlignmentMaskTagged, 0); \ |
| 1205 /* Check that the filler was written in the correct place */ \ |
| 1206 CHECK_EQ(*reinterpret_cast<v8::internal::Map***>( \ |
| 1207 (result) - (kHeapObjectTag + kPointerSize)), \ |
| 1208 isolate->factory()->one_pointer_filler_map().location()); \ |
| 1209 } while (false) |
| 1210 |
| 1211 heap::GcAndSweep(isolate->heap(), AllocationSpace::NEW_SPACE); |
| 1212 { |
| 1213 AssembleFunction(isolate, actual_size, buffer, [](MacroAssembler* masm) { |
| 1214 Label gc_required, success; |
| 1215 __ Allocate(kPointerSize, v0, t0, t1, &gc_required, kNoAllocationFlags); |
| 1216 __ jmp(&success); |
| 1217 __ bind(&gc_required); |
| 1218 __ Abort(kNoReason); |
| 1219 __ bind(&success); |
| 1220 }); |
| 1221 F0 f = FUNCTION_CAST<F0>(buffer); |
| 1222 intptr_t test_result = reinterpret_cast<intptr_t>( |
| 1223 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
| 1224 CHECK_TAGGED(test_result); |
| 1225 } |
| 1226 |
| 1227 { |
| 1228 AssembleFunction(isolate, actual_size, buffer, [](MacroAssembler* masm) { |
| 1229 Label gc_required, success; |
| 1230 __ Allocate(kDoubleSize, v0, t0, t1, &gc_required, kDoubleAligned); |
| 1231 __ jmp(&success); |
| 1232 __ bind(&gc_required); |
| 1233 __ Abort(kNoReason); |
| 1234 __ bind(&success); |
| 1235 }); |
| 1236 heap::MakeSureNewSpaceTopIsNotDoubleAligned(isolate->heap()); |
| 1237 F0 f = FUNCTION_CAST<F0>(buffer); |
| 1238 intptr_t test_result = reinterpret_cast<intptr_t>( |
| 1239 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
| 1240 CHECK_DOUBLE_ALIGNED(test_result); |
| 1241 } |
| 1242 { |
| 1243 AssembleFunction(isolate, actual_size, buffer, [](MacroAssembler* masm) { |
| 1244 Label gc_required, success; |
| 1245 __ li(a0, Operand(kPointerSize)); |
| 1246 __ Allocate(a0, v0, t0, t1, &gc_required, kNoAllocationFlags); |
| 1247 __ jmp(&success); |
| 1248 __ bind(&gc_required); |
| 1249 __ Abort(kNoReason); |
| 1250 __ bind(&success); |
| 1251 }); |
| 1252 F0 f = FUNCTION_CAST<F0>(buffer); |
| 1253 intptr_t test_result = reinterpret_cast<intptr_t>( |
| 1254 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
| 1255 CHECK_TAGGED(test_result); |
| 1256 } |
| 1257 |
| 1258 { |
| 1259 AssembleFunction(isolate, actual_size, buffer, [](MacroAssembler* masm) { |
| 1260 Label gc_required, success; |
| 1261 __ li(a0, Operand(kDoubleSize)); |
| 1262 __ Allocate(a0, v0, t0, t1, &gc_required, kDoubleAligned); |
| 1263 __ jmp(&success); |
| 1264 __ bind(&gc_required); |
| 1265 __ Abort(kNoReason); |
| 1266 __ bind(&success); |
| 1267 }); |
| 1268 heap::MakeSureNewSpaceTopIsNotDoubleAligned(isolate->heap()); |
| 1269 F0 f = FUNCTION_CAST<F0>(buffer); |
| 1270 intptr_t test_result = reinterpret_cast<intptr_t>( |
| 1271 CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0)); |
| 1272 CHECK_DOUBLE_ALIGNED(test_result); |
| 1273 } |
| 1274 |
| 1275 #undef CHECK_TAGGED |
| 1276 #undef CHECK_DOUBLE_ALIGNED |
| 1277 } |
| 1278 |
1171 #undef __ | 1279 #undef __ |
OLD | NEW |