OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 10159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10170 #define __ masm. | 10170 #define __ masm. |
10171 | 10171 |
10172 | 10172 |
10173 static void MemCopyWrapper(void* dest, const void* src, size_t size) { | 10173 static void MemCopyWrapper(void* dest, const void* src, size_t size) { |
10174 memcpy(dest, src, size); | 10174 memcpy(dest, src, size); |
10175 } | 10175 } |
10176 | 10176 |
10177 | 10177 |
10178 OS::MemCopyFunction CreateMemCopyFunction() { | 10178 OS::MemCopyFunction CreateMemCopyFunction() { |
10179 HandleScope scope; | 10179 HandleScope scope; |
10180 MacroAssembler masm(NULL, 1 * KB); | 10180 size_t actual_size; |
| 10181 // Allocate buffer in executable space. |
| 10182 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, |
| 10183 &actual_size, |
| 10184 true)); |
| 10185 if (buffer == NULL) return &MemCopyWrapper; |
| 10186 MacroAssembler masm(buffer, static_cast<int>(actual_size)); |
10181 | 10187 |
10182 // Generated code is put into a fixed, unmovable, buffer, and not into | 10188 // Generated code is put into a fixed, unmovable, buffer, and not into |
10183 // the V8 heap. We can't, and don't, refer to any relocatable addresses | 10189 // the V8 heap. We can't, and don't, refer to any relocatable addresses |
10184 // (e.g. the JavaScript nan-object). | 10190 // (e.g. the JavaScript nan-object). |
10185 | 10191 |
10186 // 32-bit C declaration function calls pass arguments on stack. | 10192 // 32-bit C declaration function calls pass arguments on stack. |
10187 | 10193 |
10188 // Stack layout: | 10194 // Stack layout: |
10189 // esp[12]: Third argument, size. | 10195 // esp[12]: Third argument, size. |
10190 // esp[8]: Second argument, source pointer. | 10196 // esp[8]: Second argument, source pointer. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10226 __ add(Operand(edx), Immediate(16)); | 10232 __ add(Operand(edx), Immediate(16)); |
10227 __ add(dst, Operand(edx)); | 10233 __ add(dst, Operand(edx)); |
10228 __ add(src, Operand(edx)); | 10234 __ add(src, Operand(edx)); |
10229 __ sub(Operand(count), edx); | 10235 __ sub(Operand(count), edx); |
10230 | 10236 |
10231 // edi is now aligned. Check if esi is also aligned. | 10237 // edi is now aligned. Check if esi is also aligned. |
10232 Label unaligned_source; | 10238 Label unaligned_source; |
10233 __ test(Operand(src), Immediate(0x0F)); | 10239 __ test(Operand(src), Immediate(0x0F)); |
10234 __ j(not_zero, &unaligned_source); | 10240 __ j(not_zero, &unaligned_source); |
10235 { | 10241 { |
10236 __ IncrementCounter(masm.isolate()->counters()->memcopy_aligned(), 1); | |
10237 // Copy loop for aligned source and destination. | 10242 // Copy loop for aligned source and destination. |
10238 __ mov(edx, count); | 10243 __ mov(edx, count); |
10239 Register loop_count = ecx; | 10244 Register loop_count = ecx; |
10240 Register count = edx; | 10245 Register count = edx; |
10241 __ shr(loop_count, 5); | 10246 __ shr(loop_count, 5); |
10242 { | 10247 { |
10243 // Main copy loop. | 10248 // Main copy loop. |
10244 Label loop; | 10249 Label loop; |
10245 __ bind(&loop); | 10250 __ bind(&loop); |
10246 __ prefetch(Operand(src, 0x20), 1); | 10251 __ prefetch(Operand(src, 0x20), 1); |
(...skipping 27 matching lines...) Expand all Loading... |
10274 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); | 10279 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); |
10275 __ pop(esi); | 10280 __ pop(esi); |
10276 __ pop(edi); | 10281 __ pop(edi); |
10277 __ ret(0); | 10282 __ ret(0); |
10278 } | 10283 } |
10279 __ Align(16); | 10284 __ Align(16); |
10280 { | 10285 { |
10281 // Copy loop for unaligned source and aligned destination. | 10286 // Copy loop for unaligned source and aligned destination. |
10282 // If source is not aligned, we can't read it as efficiently. | 10287 // If source is not aligned, we can't read it as efficiently. |
10283 __ bind(&unaligned_source); | 10288 __ bind(&unaligned_source); |
10284 __ IncrementCounter(masm.isolate()->counters()->memcopy_unaligned(), 1); | |
10285 __ mov(edx, ecx); | 10289 __ mov(edx, ecx); |
10286 Register loop_count = ecx; | 10290 Register loop_count = ecx; |
10287 Register count = edx; | 10291 Register count = edx; |
10288 __ shr(loop_count, 5); | 10292 __ shr(loop_count, 5); |
10289 { | 10293 { |
10290 // Main copy loop | 10294 // Main copy loop |
10291 Label loop; | 10295 Label loop; |
10292 __ bind(&loop); | 10296 __ bind(&loop); |
10293 __ prefetch(Operand(src, 0x20), 1); | 10297 __ prefetch(Operand(src, 0x20), 1); |
10294 __ movdqu(xmm0, Operand(src, 0x00)); | 10298 __ movdqu(xmm0, Operand(src, 0x00)); |
(...skipping 23 matching lines...) Expand all Loading... |
10318 __ movdqu(xmm0, Operand(src, count, times_1, -0x10)); | 10322 __ movdqu(xmm0, Operand(src, count, times_1, -0x10)); |
10319 __ movdqu(Operand(dst, count, times_1, -0x10), xmm0); | 10323 __ movdqu(Operand(dst, count, times_1, -0x10), xmm0); |
10320 | 10324 |
10321 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); | 10325 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); |
10322 __ pop(esi); | 10326 __ pop(esi); |
10323 __ pop(edi); | 10327 __ pop(edi); |
10324 __ ret(0); | 10328 __ ret(0); |
10325 } | 10329 } |
10326 | 10330 |
10327 } else { | 10331 } else { |
10328 __ IncrementCounter(masm.isolate()->counters()->memcopy_noxmm(), 1); | |
10329 // SSE2 not supported. Unlikely to happen in practice. | 10332 // SSE2 not supported. Unlikely to happen in practice. |
10330 __ push(edi); | 10333 __ push(edi); |
10331 __ push(esi); | 10334 __ push(esi); |
10332 stack_offset += 2 * kPointerSize; | 10335 stack_offset += 2 * kPointerSize; |
10333 __ cld(); | 10336 __ cld(); |
10334 Register dst = edi; | 10337 Register dst = edi; |
10335 Register src = esi; | 10338 Register src = esi; |
10336 Register count = ecx; | 10339 Register count = ecx; |
10337 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); | 10340 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); |
10338 __ mov(src, Operand(esp, stack_offset + kSourceOffset)); | 10341 __ mov(src, Operand(esp, stack_offset + kSourceOffset)); |
(...skipping 26 matching lines...) Expand all Loading... |
10365 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); | 10368 __ mov(eax, Operand(esp, stack_offset + kDestinationOffset)); |
10366 __ pop(esi); | 10369 __ pop(esi); |
10367 __ pop(edi); | 10370 __ pop(edi); |
10368 __ ret(0); | 10371 __ ret(0); |
10369 } | 10372 } |
10370 | 10373 |
10371 CodeDesc desc; | 10374 CodeDesc desc; |
10372 masm.GetCode(&desc); | 10375 masm.GetCode(&desc); |
10373 ASSERT(desc.reloc_size == 0); | 10376 ASSERT(desc.reloc_size == 0); |
10374 | 10377 |
10375 // Copy the generated code into an executable chunk and return a pointer | 10378 CPU::FlushICache(buffer, actual_size); |
10376 // to the first instruction in it as a C++ function pointer. | 10379 return FUNCTION_CAST<OS::MemCopyFunction>(buffer); |
10377 LargeObjectChunk* chunk = LargeObjectChunk::New(desc.instr_size, EXECUTABLE); | |
10378 if (chunk == NULL) return &MemCopyWrapper; | |
10379 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); | |
10380 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); | |
10381 return FUNCTION_CAST<OS::MemCopyFunction>(chunk->GetStartAddress()); | |
10382 } | 10380 } |
10383 | 10381 |
10384 #undef __ | 10382 #undef __ |
10385 | 10383 |
10386 } } // namespace v8::internal | 10384 } } // namespace v8::internal |
10387 | 10385 |
10388 #endif // V8_TARGET_ARCH_IA32 | 10386 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |