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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 if (!FLAG_fast_math) return &std::exp; | 59 if (!FLAG_fast_math) return &std::exp; |
60 size_t actual_size; | 60 size_t actual_size; |
61 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true)); | 61 byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true)); |
62 if (buffer == NULL) return &std::exp; | 62 if (buffer == NULL) return &std::exp; |
63 ExternalReference::InitializeMathExpData(); | 63 ExternalReference::InitializeMathExpData(); |
64 | 64 |
65 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); | 65 MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); |
66 // xmm0: raw double input. | 66 // xmm0: raw double input. |
67 XMMRegister input = xmm0; | 67 XMMRegister input = xmm0; |
68 XMMRegister result = xmm1; | 68 XMMRegister result = xmm1; |
69 __ push(rax); | 69 __ pushq(rax); |
70 __ push(rbx); | 70 __ pushq(rbx); |
71 | 71 |
72 MathExpGenerator::EmitMathExp(&masm, input, result, xmm2, rax, rbx); | 72 MathExpGenerator::EmitMathExp(&masm, input, result, xmm2, rax, rbx); |
73 | 73 |
74 __ pop(rbx); | 74 __ popq(rbx); |
75 __ pop(rax); | 75 __ popq(rax); |
76 __ movsd(xmm0, result); | 76 __ movsd(xmm0, result); |
77 __ Ret(); | 77 __ Ret(); |
78 | 78 |
79 CodeDesc desc; | 79 CodeDesc desc; |
80 masm.GetCode(&desc); | 80 masm.GetCode(&desc); |
81 ASSERT(!RelocInfo::RequiresRelocation(desc)); | 81 ASSERT(!RelocInfo::RequiresRelocation(desc)); |
82 | 82 |
83 CPU::FlushICache(buffer, actual_size); | 83 CPU::FlushICache(buffer, actual_size); |
84 OS::ProtectCode(buffer, actual_size); | 84 OS::ProtectCode(buffer, actual_size); |
85 return FUNCTION_CAST<UnaryMathFunction>(buffer); | 85 return FUNCTION_CAST<UnaryMathFunction>(buffer); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 if (mode == TRACK_ALLOCATION_SITE) { | 374 if (mode == TRACK_ALLOCATION_SITE) { |
375 __ JumpIfJSArrayHasAllocationMemento(rdx, rdi, fail); | 375 __ JumpIfJSArrayHasAllocationMemento(rdx, rdi, fail); |
376 } | 376 } |
377 | 377 |
378 // Check for empty arrays, which only require a map transition and no changes | 378 // Check for empty arrays, which only require a map transition and no changes |
379 // to the backing store. | 379 // to the backing store. |
380 __ movp(r8, FieldOperand(rdx, JSObject::kElementsOffset)); | 380 __ movp(r8, FieldOperand(rdx, JSObject::kElementsOffset)); |
381 __ CompareRoot(r8, Heap::kEmptyFixedArrayRootIndex); | 381 __ CompareRoot(r8, Heap::kEmptyFixedArrayRootIndex); |
382 __ j(equal, &only_change_map); | 382 __ j(equal, &only_change_map); |
383 | 383 |
384 __ push(rax); | 384 __ Push(rax); |
385 | 385 |
386 __ movp(r8, FieldOperand(rdx, JSObject::kElementsOffset)); | 386 __ movp(r8, FieldOperand(rdx, JSObject::kElementsOffset)); |
387 __ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset)); | 387 __ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset)); |
388 // r8 : source FixedDoubleArray | 388 // r8 : source FixedDoubleArray |
389 // r9 : number of elements | 389 // r9 : number of elements |
390 __ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize)); | 390 __ lea(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize)); |
391 __ Allocate(rdi, r11, r14, r15, &gc_required, TAG_OBJECT); | 391 __ Allocate(rdi, r11, r14, r15, &gc_required, TAG_OBJECT); |
392 // r11: destination FixedArray | 392 // r11: destination FixedArray |
393 __ LoadRoot(rdi, Heap::kFixedArrayMapRootIndex); | 393 __ LoadRoot(rdi, Heap::kFixedArrayMapRootIndex); |
394 __ movp(FieldOperand(r11, HeapObject::kMapOffset), rdi); | 394 __ movp(FieldOperand(r11, HeapObject::kMapOffset), rdi); |
395 __ Integer32ToSmi(r14, r9); | 395 __ Integer32ToSmi(r14, r9); |
396 __ movp(FieldOperand(r11, FixedArray::kLengthOffset), r14); | 396 __ movp(FieldOperand(r11, FixedArray::kLengthOffset), r14); |
397 | 397 |
398 // Prepare for conversion loop. | 398 // Prepare for conversion loop. |
399 __ movq(rsi, BitCast<int64_t, uint64_t>(kHoleNanInt64)); | 399 __ movq(rsi, BitCast<int64_t, uint64_t>(kHoleNanInt64)); |
400 __ LoadRoot(rdi, Heap::kTheHoleValueRootIndex); | 400 __ LoadRoot(rdi, Heap::kTheHoleValueRootIndex); |
401 // rsi: the-hole NaN | 401 // rsi: the-hole NaN |
402 // rdi: pointer to the-hole | 402 // rdi: pointer to the-hole |
403 __ jmp(&entry); | 403 __ jmp(&entry); |
404 | 404 |
405 // Call into runtime if GC is required. | 405 // Call into runtime if GC is required. |
406 __ bind(&gc_required); | 406 __ bind(&gc_required); |
407 __ pop(rax); | 407 __ Pop(rax); |
408 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 408 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
409 __ jmp(fail); | 409 __ jmp(fail); |
410 | 410 |
411 // Box doubles into heap numbers. | 411 // Box doubles into heap numbers. |
412 __ bind(&loop); | 412 __ bind(&loop); |
413 __ movq(r14, FieldOperand(r8, | 413 __ movq(r14, FieldOperand(r8, |
414 r9, | 414 r9, |
415 times_8, | 415 times_8, |
416 FixedDoubleArray::kHeaderSize)); | 416 FixedDoubleArray::kHeaderSize)); |
417 // r9 : current element's index | 417 // r9 : current element's index |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 | 451 |
452 // Replace receiver's backing store with newly created and filled FixedArray. | 452 // Replace receiver's backing store with newly created and filled FixedArray. |
453 __ movp(FieldOperand(rdx, JSObject::kElementsOffset), r11); | 453 __ movp(FieldOperand(rdx, JSObject::kElementsOffset), r11); |
454 __ RecordWriteField(rdx, | 454 __ RecordWriteField(rdx, |
455 JSObject::kElementsOffset, | 455 JSObject::kElementsOffset, |
456 r11, | 456 r11, |
457 r15, | 457 r15, |
458 kDontSaveFPRegs, | 458 kDontSaveFPRegs, |
459 EMIT_REMEMBERED_SET, | 459 EMIT_REMEMBERED_SET, |
460 OMIT_SMI_CHECK); | 460 OMIT_SMI_CHECK); |
461 __ pop(rax); | 461 __ Pop(rax); |
462 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 462 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
463 | 463 |
464 __ bind(&only_change_map); | 464 __ bind(&only_change_map); |
465 // Set transitioned map. | 465 // Set transitioned map. |
466 __ movp(FieldOperand(rdx, HeapObject::kMapOffset), rbx); | 466 __ movp(FieldOperand(rdx, HeapObject::kMapOffset), rbx); |
467 __ RecordWriteField(rdx, | 467 __ RecordWriteField(rdx, |
468 HeapObject::kMapOffset, | 468 HeapObject::kMapOffset, |
469 rbx, | 469 rbx, |
470 rdi, | 470 rdi, |
471 kDontSaveFPRegs, | 471 kDontSaveFPRegs, |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 | 633 |
634 static byte* GetNoCodeAgeSequence(uint32_t* length) { | 634 static byte* GetNoCodeAgeSequence(uint32_t* length) { |
635 static bool initialized = false; | 635 static bool initialized = false; |
636 static byte sequence[kNoCodeAgeSequenceLength]; | 636 static byte sequence[kNoCodeAgeSequenceLength]; |
637 *length = kNoCodeAgeSequenceLength; | 637 *length = kNoCodeAgeSequenceLength; |
638 if (!initialized) { | 638 if (!initialized) { |
639 // The sequence of instructions that is patched out for aging code is the | 639 // The sequence of instructions that is patched out for aging code is the |
640 // following boilerplate stack-building prologue that is found both in | 640 // following boilerplate stack-building prologue that is found both in |
641 // FUNCTION and OPTIMIZED_FUNCTION code: | 641 // FUNCTION and OPTIMIZED_FUNCTION code: |
642 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength); | 642 CodePatcher patcher(sequence, kNoCodeAgeSequenceLength); |
643 patcher.masm()->push(rbp); | 643 patcher.masm()->pushq(rbp); |
644 patcher.masm()->movp(rbp, rsp); | 644 patcher.masm()->movp(rbp, rsp); |
645 patcher.masm()->push(rsi); | 645 patcher.masm()->Push(rsi); |
646 patcher.masm()->push(rdi); | 646 patcher.masm()->Push(rdi); |
647 initialized = true; | 647 initialized = true; |
648 } | 648 } |
649 return sequence; | 649 return sequence; |
650 } | 650 } |
651 | 651 |
652 | 652 |
653 bool Code::IsYoungSequence(byte* sequence) { | 653 bool Code::IsYoungSequence(byte* sequence) { |
654 uint32_t young_length; | 654 uint32_t young_length; |
655 byte* young_sequence = GetNoCodeAgeSequence(&young_length); | 655 byte* young_sequence = GetNoCodeAgeSequence(&young_length); |
656 bool result = (!memcmp(sequence, young_sequence, young_length)); | 656 bool result = (!memcmp(sequence, young_sequence, young_length)); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize. | 710 // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize. |
711 return Operand(base_reg_, argument_count_reg_, times_pointer_size, | 711 return Operand(base_reg_, argument_count_reg_, times_pointer_size, |
712 displacement_to_last_argument + (receiver - 1 - index) * kPointerSize); | 712 displacement_to_last_argument + (receiver - 1 - index) * kPointerSize); |
713 } | 713 } |
714 } | 714 } |
715 | 715 |
716 | 716 |
717 } } // namespace v8::internal | 717 } } // namespace v8::internal |
718 | 718 |
719 #endif // V8_TARGET_ARCH_X64 | 719 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |