| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 CPU::FlushICache(buffer, actual_size); | 170 CPU::FlushICache(buffer, actual_size); |
| 171 OS::ProtectCode(buffer, actual_size); | 171 OS::ProtectCode(buffer, actual_size); |
| 172 return FUNCTION_CAST<UnaryMathFunction>(buffer); | 172 return FUNCTION_CAST<UnaryMathFunction>(buffer); |
| 173 } | 173 } |
| 174 | 174 |
| 175 | 175 |
| 176 // Helper functions for CreateMemMoveFunction. | 176 // Helper functions for CreateMemMoveFunction. |
| 177 #undef __ | 177 #undef __ |
| 178 #define __ ACCESS_MASM(masm) | 178 #define __ ACCESS_MASM(masm) |
| 179 | 179 |
| 180 // Keep around global pointers to these objects so that Valgrind won't complain. | |
| 181 static size_t* medium_handlers = NULL; | |
| 182 static size_t* small_handlers = NULL; | |
| 183 | |
| 184 | |
| 185 enum Direction { FORWARD, BACKWARD }; | 180 enum Direction { FORWARD, BACKWARD }; |
| 186 enum Alignment { MOVE_ALIGNED, MOVE_UNALIGNED }; | 181 enum Alignment { MOVE_ALIGNED, MOVE_UNALIGNED }; |
| 187 | 182 |
| 188 // Expects registers: | 183 // Expects registers: |
| 189 // esi - source, aligned if alignment == ALIGNED | 184 // esi - source, aligned if alignment == ALIGNED |
| 190 // edi - destination, always aligned | 185 // edi - destination, always aligned |
| 191 // ecx - count (copy size in bytes) | 186 // ecx - count (copy size in bytes) |
| 192 // edx - loop count (number of 64 byte chunks) | 187 // edx - loop count (number of 64 byte chunks) |
| 193 void MemMoveEmitMainLoop(MacroAssembler* masm, | 188 void MemMoveEmitMainLoop(MacroAssembler* masm, |
| 194 Label* move_last_15, | 189 Label* move_last_15, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 __ pop(esi); | 241 __ pop(esi); |
| 247 __ pop(edi); | 242 __ pop(edi); |
| 248 __ ret(0); | 243 __ ret(0); |
| 249 } | 244 } |
| 250 | 245 |
| 251 | 246 |
| 252 #undef __ | 247 #undef __ |
| 253 #define __ masm. | 248 #define __ masm. |
| 254 | 249 |
| 255 | 250 |
| 251 class LabelConverter { |
| 252 public: |
| 253 explicit LabelConverter(byte* buffer) : buffer_(buffer) {} |
| 254 int32_t address(Label* l) const { |
| 255 return reinterpret_cast<int32_t>(buffer_) + l->pos(); |
| 256 } |
| 257 private: |
| 258 byte* buffer_; |
| 259 }; |
| 260 |
| 261 |
| 256 OS::MemMoveFunction CreateMemMoveFunction() { | 262 OS::MemMoveFunction CreateMemMoveFunction() { |
| 257 size_t actual_size; | 263 size_t actual_size; |
| 258 // Allocate buffer in executable space. | 264 // Allocate buffer in executable space. |
| 259 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true)); | 265 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true)); |
| 260 if (buffer == NULL) return NULL; | 266 if (buffer == NULL) return NULL; |
| 261 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); | 267 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); |
| 268 LabelConverter conv(buffer); |
| 262 | 269 |
| 263 // Generated code is put into a fixed, unmovable buffer, and not into | 270 // Generated code is put into a fixed, unmovable buffer, and not into |
| 264 // the V8 heap. We can't, and don't, refer to any relocatable addresses | 271 // the V8 heap. We can't, and don't, refer to any relocatable addresses |
| 265 // (e.g. the JavaScript nan-object). | 272 // (e.g. the JavaScript nan-object). |
| 266 | 273 |
| 267 // 32-bit C declaration function calls pass arguments on stack. | 274 // 32-bit C declaration function calls pass arguments on stack. |
| 268 | 275 |
| 269 // Stack layout: | 276 // Stack layout: |
| 270 // esp[12]: Third argument, size. | 277 // esp[12]: Third argument, size. |
| 271 // esp[8]: Second argument, source pointer. | 278 // esp[8]: Second argument, source pointer. |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 445 __ sub(dst, count); | 452 __ sub(dst, count); |
| 446 __ sub(src, count); | 453 __ sub(src, count); |
| 447 __ cmp(count, kSmallCopySize); | 454 __ cmp(count, kSmallCopySize); |
| 448 __ j(below_equal, &small_size); | 455 __ j(below_equal, &small_size); |
| 449 __ jmp(&medium_size); | 456 __ jmp(&medium_size); |
| 450 } | 457 } |
| 451 { | 458 { |
| 452 // Special handlers for 9 <= copy_size < 64. No assumptions about | 459 // Special handlers for 9 <= copy_size < 64. No assumptions about |
| 453 // alignment or move distance, so all reads must be unaligned and | 460 // alignment or move distance, so all reads must be unaligned and |
| 454 // must happen before any writes. | 461 // must happen before any writes. |
| 455 Label f9_16, f17_32, f33_48, f49_63; | 462 Label medium_handlers, f9_16, f17_32, f33_48, f49_63; |
| 456 | 463 |
| 457 __ bind(&f9_16); | 464 __ bind(&f9_16); |
| 458 __ movdbl(xmm0, Operand(src, 0)); | 465 __ movdbl(xmm0, Operand(src, 0)); |
| 459 __ movdbl(xmm1, Operand(src, count, times_1, -8)); | 466 __ movdbl(xmm1, Operand(src, count, times_1, -8)); |
| 460 __ movdbl(Operand(dst, 0), xmm0); | 467 __ movdbl(Operand(dst, 0), xmm0); |
| 461 __ movdbl(Operand(dst, count, times_1, -8), xmm1); | 468 __ movdbl(Operand(dst, count, times_1, -8), xmm1); |
| 462 MemMoveEmitPopAndReturn(&masm); | 469 MemMoveEmitPopAndReturn(&masm); |
| 463 | 470 |
| 464 __ bind(&f17_32); | 471 __ bind(&f17_32); |
| 465 __ movdqu(xmm0, Operand(src, 0)); | 472 __ movdqu(xmm0, Operand(src, 0)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 481 __ movdqu(xmm0, Operand(src, 0x00)); | 488 __ movdqu(xmm0, Operand(src, 0x00)); |
| 482 __ movdqu(xmm1, Operand(src, 0x10)); | 489 __ movdqu(xmm1, Operand(src, 0x10)); |
| 483 __ movdqu(xmm2, Operand(src, 0x20)); | 490 __ movdqu(xmm2, Operand(src, 0x20)); |
| 484 __ movdqu(xmm3, Operand(src, count, times_1, -0x10)); | 491 __ movdqu(xmm3, Operand(src, count, times_1, -0x10)); |
| 485 __ movdqu(Operand(dst, 0x00), xmm0); | 492 __ movdqu(Operand(dst, 0x00), xmm0); |
| 486 __ movdqu(Operand(dst, 0x10), xmm1); | 493 __ movdqu(Operand(dst, 0x10), xmm1); |
| 487 __ movdqu(Operand(dst, 0x20), xmm2); | 494 __ movdqu(Operand(dst, 0x20), xmm2); |
| 488 __ movdqu(Operand(dst, count, times_1, -0x10), xmm3); | 495 __ movdqu(Operand(dst, count, times_1, -0x10), xmm3); |
| 489 MemMoveEmitPopAndReturn(&masm); | 496 MemMoveEmitPopAndReturn(&masm); |
| 490 | 497 |
| 491 medium_handlers = new size_t[4]; | 498 __ bind(&medium_handlers); |
| 492 medium_handlers[0] = reinterpret_cast<intptr_t>(buffer) + f9_16.pos(); | 499 __ dd(conv.address(&f9_16)); |
| 493 medium_handlers[1] = reinterpret_cast<intptr_t>(buffer) + f17_32.pos(); | 500 __ dd(conv.address(&f17_32)); |
| 494 medium_handlers[2] = reinterpret_cast<intptr_t>(buffer) + f33_48.pos(); | 501 __ dd(conv.address(&f33_48)); |
| 495 medium_handlers[3] = reinterpret_cast<intptr_t>(buffer) + f49_63.pos(); | 502 __ dd(conv.address(&f49_63)); |
| 496 | 503 |
| 497 __ bind(&medium_size); // Entry point into this block. | 504 __ bind(&medium_size); // Entry point into this block. |
| 498 __ mov(eax, count); | 505 __ mov(eax, count); |
| 499 __ dec(eax); | 506 __ dec(eax); |
| 500 __ shr(eax, 4); | 507 __ shr(eax, 4); |
| 501 if (FLAG_debug_code) { | 508 if (FLAG_debug_code) { |
| 502 Label ok; | 509 Label ok; |
| 503 __ cmp(eax, 3); | 510 __ cmp(eax, 3); |
| 504 __ j(below_equal, &ok); | 511 __ j(below_equal, &ok); |
| 505 __ int3(); | 512 __ int3(); |
| 506 __ bind(&ok); | 513 __ bind(&ok); |
| 507 } | 514 } |
| 508 __ mov(eax, Operand(eax, times_4, | 515 __ mov(eax, Operand(eax, times_4, conv.address(&medium_handlers))); |
| 509 reinterpret_cast<intptr_t>(medium_handlers))); | |
| 510 __ jmp(eax); | 516 __ jmp(eax); |
| 511 } | 517 } |
| 512 { | 518 { |
| 513 // Specialized copiers for copy_size <= 8 bytes. | 519 // Specialized copiers for copy_size <= 8 bytes. |
| 514 Label f0, f1, f2, f3, f4, f5_8; | 520 Label small_handlers, f0, f1, f2, f3, f4, f5_8; |
| 515 __ bind(&f0); | 521 __ bind(&f0); |
| 516 MemMoveEmitPopAndReturn(&masm); | 522 MemMoveEmitPopAndReturn(&masm); |
| 517 | 523 |
| 518 __ bind(&f1); | 524 __ bind(&f1); |
| 519 __ mov_b(eax, Operand(src, 0)); | 525 __ mov_b(eax, Operand(src, 0)); |
| 520 __ mov_b(Operand(dst, 0), eax); | 526 __ mov_b(Operand(dst, 0), eax); |
| 521 MemMoveEmitPopAndReturn(&masm); | 527 MemMoveEmitPopAndReturn(&masm); |
| 522 | 528 |
| 523 __ bind(&f2); | 529 __ bind(&f2); |
| 524 __ mov_w(eax, Operand(src, 0)); | 530 __ mov_w(eax, Operand(src, 0)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 537 __ mov(Operand(dst, 0), eax); | 543 __ mov(Operand(dst, 0), eax); |
| 538 MemMoveEmitPopAndReturn(&masm); | 544 MemMoveEmitPopAndReturn(&masm); |
| 539 | 545 |
| 540 __ bind(&f5_8); | 546 __ bind(&f5_8); |
| 541 __ mov(eax, Operand(src, 0)); | 547 __ mov(eax, Operand(src, 0)); |
| 542 __ mov(edx, Operand(src, count, times_1, -4)); | 548 __ mov(edx, Operand(src, count, times_1, -4)); |
| 543 __ mov(Operand(dst, 0), eax); | 549 __ mov(Operand(dst, 0), eax); |
| 544 __ mov(Operand(dst, count, times_1, -4), edx); | 550 __ mov(Operand(dst, count, times_1, -4), edx); |
| 545 MemMoveEmitPopAndReturn(&masm); | 551 MemMoveEmitPopAndReturn(&masm); |
| 546 | 552 |
| 547 small_handlers = new size_t[9]; | 553 __ bind(&small_handlers); |
| 548 small_handlers[0] = reinterpret_cast<intptr_t>(buffer) + f0.pos(); | 554 __ dd(conv.address(&f0)); |
| 549 small_handlers[1] = reinterpret_cast<intptr_t>(buffer) + f1.pos(); | 555 __ dd(conv.address(&f1)); |
| 550 small_handlers[2] = reinterpret_cast<intptr_t>(buffer) + f2.pos(); | 556 __ dd(conv.address(&f2)); |
| 551 small_handlers[3] = reinterpret_cast<intptr_t>(buffer) + f3.pos(); | 557 __ dd(conv.address(&f3)); |
| 552 small_handlers[4] = reinterpret_cast<intptr_t>(buffer) + f4.pos(); | 558 __ dd(conv.address(&f4)); |
| 553 small_handlers[5] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos(); | 559 __ dd(conv.address(&f5_8)); |
| 554 small_handlers[6] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos(); | 560 __ dd(conv.address(&f5_8)); |
| 555 small_handlers[7] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos(); | 561 __ dd(conv.address(&f5_8)); |
| 556 small_handlers[8] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos(); | 562 __ dd(conv.address(&f5_8)); |
| 557 | 563 |
| 558 __ bind(&small_size); // Entry point into this block. | 564 __ bind(&small_size); // Entry point into this block. |
| 559 if (FLAG_debug_code) { | 565 if (FLAG_debug_code) { |
| 560 Label ok; | 566 Label ok; |
| 561 __ cmp(count, 8); | 567 __ cmp(count, 8); |
| 562 __ j(below_equal, &ok); | 568 __ j(below_equal, &ok); |
| 563 __ int3(); | 569 __ int3(); |
| 564 __ bind(&ok); | 570 __ bind(&ok); |
| 565 } | 571 } |
| 566 __ mov(eax, Operand(count, times_4, | 572 __ mov(eax, Operand(count, times_4, conv.address(&small_handlers))); |
| 567 reinterpret_cast<intptr_t>(small_handlers))); | |
| 568 __ jmp(eax); | 573 __ jmp(eax); |
| 569 } | 574 } |
| 570 } else { | 575 } else { |
| 571 // No SSE2. | 576 // No SSE2. |
| 572 Label forward; | 577 Label forward; |
| 573 __ cmp(count, 0); | 578 __ cmp(count, 0); |
| 574 __ j(equal, &pop_and_return); | 579 __ j(equal, &pop_and_return); |
| 575 __ cmp(dst, src); | 580 __ cmp(dst, src); |
| 576 __ j(above, &backward); | 581 __ j(above, &backward); |
| 577 __ jmp(&forward); | 582 __ jmp(&forward); |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 Code* stub = GetCodeAgeStub(age, parity); | 1177 Code* stub = GetCodeAgeStub(age, parity); |
| 1173 CodePatcher patcher(sequence, young_length); | 1178 CodePatcher patcher(sequence, young_length); |
| 1174 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); | 1179 patcher.masm()->call(stub->instruction_start(), RelocInfo::NONE32); |
| 1175 } | 1180 } |
| 1176 } | 1181 } |
| 1177 | 1182 |
| 1178 | 1183 |
| 1179 } } // namespace v8::internal | 1184 } } // namespace v8::internal |
| 1180 | 1185 |
| 1181 #endif // V8_TARGET_ARCH_IA32 | 1186 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |