| 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 |