Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 8355035: Refactor elements kind conversion. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Bugfix Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 12 matching lines...) Expand all
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #if defined(V8_TARGET_ARCH_IA32) 30 #if defined(V8_TARGET_ARCH_IA32)
31 31
32 #include "codegen.h" 32 #include "codegen.h"
33 #include "macro-assembler.h"
33 34
34 namespace v8 { 35 namespace v8 {
35 namespace internal { 36 namespace internal {
36 37
37 38
38 // ------------------------------------------------------------------------- 39 // -------------------------------------------------------------------------
39 // Platform-specific RuntimeCallHelper functions. 40 // Platform-specific RuntimeCallHelper functions.
40 41
41 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { 42 void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
42 masm->EnterFrame(StackFrame::INTERNAL); 43 masm->EnterFrame(StackFrame::INTERNAL);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 masm.GetCode(&desc); 259 masm.GetCode(&desc);
259 ASSERT(desc.reloc_size == 0); 260 ASSERT(desc.reloc_size == 0);
260 261
261 CPU::FlushICache(buffer, actual_size); 262 CPU::FlushICache(buffer, actual_size);
262 OS::ProtectCode(buffer, actual_size); 263 OS::ProtectCode(buffer, actual_size);
263 return FUNCTION_CAST<OS::MemCopyFunction>(buffer); 264 return FUNCTION_CAST<OS::MemCopyFunction>(buffer);
264 } 265 }
265 266
266 #undef __ 267 #undef __
267 268
269 // -------------------------------------------------------------------------
270 // Code generators
271
272 #define __ ACCESS_MASM(masm)
273
274 void ElementsTransitionGenerator::GenerateSmiOnlyToObject(
275 MacroAssembler* masm) {
276 // ----------- S t a t e -------------
277 // -- eax : value
278 // -- ebx : target map
279 // -- ecx : key
280 // -- edx : receiver
281 // -- esp[0] : return address
282 // -----------------------------------
283 // Set transitioned map.
284 __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx);
285 __ RecordWriteField(edx,
286 HeapObject::kMapOffset,
287 ebx,
288 edi,
289 kDontSaveFPRegs,
290 EMIT_REMEMBERED_SET,
291 OMIT_SMI_CHECK);
292 }
293
294
295 void ElementsTransitionGenerator::GenerateSmiOnlyToDouble(
296 MacroAssembler* masm, Label* fail) {
297 // ----------- S t a t e -------------
298 // -- eax : value
299 // -- ebx : target map
300 // -- ecx : key
301 // -- edx : receiver
302 // -- esp[0] : return address
303 // -----------------------------------
304 Label loop, entry, convert_hole, gc_required;
305 __ push(eax);
306 __ push(ebx);
307
308 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
309 __ mov(edi, FieldOperand(edi, FixedArray::kLengthOffset));
310
311 // Allocate new FixedDoubleArray.
312 // edx: receiver
313 // edi: length of source FixedArray (smi-tagged)
314 __ lea(esi, Operand(edi, times_4, FixedDoubleArray::kHeaderSize));
315 __ AllocateInNewSpace(esi, eax, ebx, no_reg, &gc_required, TAG_OBJECT);
316
317 // eax: destination FixedDoubleArray
318 // edi: number of elements
319 // edx: receiver
320 __ mov(FieldOperand(eax, HeapObject::kMapOffset),
321 Immediate(masm->isolate()->factory()->fixed_double_array_map()));
322 __ mov(FieldOperand(eax, FixedDoubleArray::kLengthOffset), edi);
323 __ mov(esi, FieldOperand(edx, JSObject::kElementsOffset));
324 // Replace receiver's backing store with newly created FixedDoubleArray.
325 __ mov(FieldOperand(edx, JSObject::kElementsOffset), eax);
326 __ mov(ebx, eax);
327 __ RecordWriteField(edx,
328 JSObject::kElementsOffset,
329 ebx,
330 edi,
331 kDontSaveFPRegs,
332 EMIT_REMEMBERED_SET,
333 OMIT_SMI_CHECK);
334
335 __ mov(edi, FieldOperand(esi, FixedArray::kLengthOffset));
336
337 // Prepare for conversion loop.
338 ExternalReference canonical_the_hole_nan_reference =
339 ExternalReference::address_of_the_hole_nan();
340 XMMRegister the_hole_nan = xmm1;
341 if (CpuFeatures::IsSupported(SSE2)) {
342 CpuFeatures::Scope use_sse2(SSE2);
343 __ movdbl(the_hole_nan,
344 Operand::StaticVariable(canonical_the_hole_nan_reference));
345 }
346 __ jmp(&entry);
347
348 // Call into runtime if GC is required.
349 __ bind(&gc_required);
350 // Restore registers before jumping into runtime.
351 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
352 __ pop(ebx);
353 __ pop(eax);
354 __ jmp(fail);
355
356 // Convert and copy elements
357 // esi: source FixedArray
358 // edi: number of elements to convert/copy
359 __ bind(&loop);
360 __ sub(edi, Immediate(Smi::FromInt(1)));
361 __ mov(ebx, FieldOperand(esi, edi, times_2, FixedArray::kHeaderSize));
362 // ebx: current element from source
363 // edi: index of current element
364 __ JumpIfNotSmi(ebx, &convert_hole);
365
366 // Normal smi, convert it to double and store.
367 __ SmiUntag(ebx);
368 if (CpuFeatures::IsSupported(SSE2)) {
369 CpuFeatures::Scope fscope(SSE2);
370 __ cvtsi2sd(xmm0, ebx);
371 __ movdbl(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize),
372 xmm0);
373 } else {
374 __ push(ebx);
375 __ fild_s(Operand(esp, 0));
376 __ pop(ebx);
377 __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize));
378 }
379 __ jmp(&entry);
380
381 // Found hole, store hole_nan_as_double instead.
382 __ bind(&convert_hole);
383 if (CpuFeatures::IsSupported(SSE2)) {
384 CpuFeatures::Scope use_sse2(SSE2);
385 __ movdbl(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize),
386 the_hole_nan);
387 } else {
388 __ fld_d(Operand::StaticVariable(canonical_the_hole_nan_reference));
389 __ fstp_d(FieldOperand(eax, edi, times_4, FixedDoubleArray::kHeaderSize));
390 }
391
392 __ bind(&entry);
393 __ test(edi, edi);
394 __ j(not_zero, &loop);
395
396 __ pop(ebx);
397 __ pop(eax);
398 // eax: value
399 // ebx: target map
400 // Set transitioned map.
401 __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx);
402 __ RecordWriteField(edx,
403 HeapObject::kMapOffset,
404 ebx,
405 edi,
406 kDontSaveFPRegs,
407 EMIT_REMEMBERED_SET,
408 OMIT_SMI_CHECK);
409 // Restore esi.
410 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
411 }
412
413
414 void ElementsTransitionGenerator::GenerateDoubleToObject(
415 MacroAssembler* masm, Label* fail) {
416 // ----------- S t a t e -------------
417 // -- eax : value
418 // -- ebx : target map
419 // -- ecx : key
420 // -- edx : receiver
421 // -- esp[0] : return address
422 // -----------------------------------
423 Label loop, entry, convert_hole, gc_required;
424 __ push(eax);
425 __ push(edx);
426 __ push(ebx);
427
428 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
429 __ mov(ebx, FieldOperand(edi, FixedDoubleArray::kLengthOffset));
430
431 // Allocate new FixedArray.
432 // ebx: length of source FixedDoubleArray (smi-tagged)
433 __ lea(edi, Operand(ebx, times_2, FixedArray::kHeaderSize));
434 __ AllocateInNewSpace(edi, eax, esi, no_reg, &gc_required, TAG_OBJECT);
435
436 // eax: destination FixedArray
437 // ebx: number of elements
438 __ mov(FieldOperand(eax, HeapObject::kMapOffset),
439 Immediate(masm->isolate()->factory()->fixed_array_map()));
440 __ mov(FieldOperand(eax, FixedArray::kLengthOffset), ebx);
441 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
442
443 __ jmp(&entry);
444
445 // Call into runtime if GC is required.
446 __ bind(&gc_required);
447 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
448 __ pop(ebx);
449 __ pop(edx);
450 __ pop(eax);
451 __ jmp(fail);
452
453 // Box doubles into heap numbers.
454 // edi: source FixedDoubleArray
455 // eax: destination FixedArray
456 __ bind(&loop);
457 __ sub(ebx, Immediate(Smi::FromInt(1)));
458 // ebx: index of current element (smi-tagged)
459 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32);
460 __ cmp(FieldOperand(edi, ebx, times_4, offset), Immediate(kHoleNanUpper32));
461 __ j(equal, &convert_hole);
462
463 // Non-hole double, copy value into a heap number.
464 __ AllocateHeapNumber(edx, esi, no_reg, &gc_required);
465 // edx: new heap number
466 if (CpuFeatures::IsSupported(SSE2)) {
467 CpuFeatures::Scope fscope(SSE2);
468 __ movdbl(xmm0,
469 FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize));
470 __ movdbl(FieldOperand(edx, HeapNumber::kValueOffset), xmm0);
471 } else {
472 __ mov(esi, FieldOperand(edi, ebx, times_4, FixedDoubleArray::kHeaderSize));
473 __ mov(FieldOperand(edx, HeapNumber::kValueOffset), esi);
474 __ mov(esi, FieldOperand(edi, ebx, times_4, offset));
475 __ mov(FieldOperand(edx, HeapNumber::kValueOffset + kPointerSize), esi);
476 }
477 __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize), edx);
478 __ mov(esi, ebx);
479 __ RecordWriteArray(eax,
480 edx,
481 esi,
482 kDontSaveFPRegs,
483 EMIT_REMEMBERED_SET,
484 OMIT_SMI_CHECK);
485 __ jmp(&entry, Label::kNear);
486
487 // Replace the-hole NaN with the-hole pointer.
488 __ bind(&convert_hole);
489 __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize),
490 masm->isolate()->factory()->the_hole_value());
491
492 __ bind(&entry);
493 __ test(ebx, ebx);
494 __ j(not_zero, &loop);
495
496 __ pop(ebx);
497 __ pop(edx);
498 // ebx: target map
499 // edx: receiver
500 // Set transitioned map.
501 __ mov(FieldOperand(edx, HeapObject::kMapOffset), ebx);
502 __ RecordWriteField(edx,
503 HeapObject::kMapOffset,
504 ebx,
505 edi,
506 kDontSaveFPRegs,
507 EMIT_REMEMBERED_SET,
508 OMIT_SMI_CHECK);
509 // Replace receiver's backing store with newly created and filled FixedArray.
510 __ mov(FieldOperand(edx, JSObject::kElementsOffset), eax);
511 __ RecordWriteField(edx,
512 JSObject::kElementsOffset,
513 eax,
514 edi,
515 kDontSaveFPRegs,
516 EMIT_REMEMBERED_SET,
517 OMIT_SMI_CHECK);
518
519 // Restore registers.
520 __ pop(eax);
521 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
522 }
523
524 #undef __
525
268 } } // namespace v8::internal 526 } } // namespace v8::internal
269 527
270 #endif // V8_TARGET_ARCH_IA32 528 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698