OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | 301 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
302 RelocInfo::CODE_TARGET); | 302 RelocInfo::CODE_TARGET); |
303 __ bind(&function); | 303 __ bind(&function); |
304 } | 304 } |
305 | 305 |
306 // 5b. Get the code to call from the function and check that the number of | 306 // 5b. Get the code to call from the function and check that the number of |
307 // expected arguments matches what we're providing. If so, jump | 307 // expected arguments matches what we're providing. If so, jump |
308 // (tail-call) to the code in register edx without checking arguments. | 308 // (tail-call) to the code in register edx without checking arguments. |
309 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | 309 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
310 __ movsxlq(rbx, | 310 __ movsxlq(rbx, |
311 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); | 311 FieldOperand(rdx, |
| 312 SharedFunctionInfo::kFormalParameterCountOffset)); |
312 __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); | 313 __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); |
313 __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize)); | 314 __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize)); |
314 __ cmpq(rax, rbx); | 315 __ cmpq(rax, rbx); |
315 __ j(not_equal, | 316 __ j(not_equal, |
316 Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | 317 Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
317 RelocInfo::CODE_TARGET); | 318 RelocInfo::CODE_TARGET); |
318 | 319 |
319 ParameterCount expected(0); | 320 ParameterCount expected(0); |
320 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION); | 321 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION); |
321 } | 322 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 return; | 519 return; |
519 } | 520 } |
520 | 521 |
521 // Calculate the location of the elements array and set elements array member | 522 // Calculate the location of the elements array and set elements array member |
522 // of the JSArray. | 523 // of the JSArray. |
523 // result: JSObject | 524 // result: JSObject |
524 // scratch2: start of next object | 525 // scratch2: start of next object |
525 __ lea(scratch1, Operand(result, JSArray::kSize)); | 526 __ lea(scratch1, Operand(result, JSArray::kSize)); |
526 __ movq(FieldOperand(result, JSArray::kElementsOffset), scratch1); | 527 __ movq(FieldOperand(result, JSArray::kElementsOffset), scratch1); |
527 | 528 |
528 // Initialize the FixedArray and fill it with holes. FixedArray length is not | 529 // Initialize the FixedArray and fill it with holes. FixedArray length is |
529 // stored as a smi. | 530 // stored as a smi. |
530 // result: JSObject | 531 // result: JSObject |
531 // scratch1: elements array | 532 // scratch1: elements array |
532 // scratch2: start of next object | 533 // scratch2: start of next object |
533 __ Move(FieldOperand(scratch1, JSObject::kMapOffset), | 534 __ Move(FieldOperand(scratch1, HeapObject::kMapOffset), |
534 Factory::fixed_array_map()); | 535 Factory::fixed_array_map()); |
535 __ movq(FieldOperand(scratch1, Array::kLengthOffset), | 536 __ Move(FieldOperand(scratch1, FixedArray::kLengthOffset), |
536 Immediate(initial_capacity)); | 537 Smi::FromInt(initial_capacity)); |
537 | 538 |
538 // Fill the FixedArray with the hole value. Inline the code if short. | 539 // Fill the FixedArray with the hole value. Inline the code if short. |
539 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. | 540 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. |
540 static const int kLoopUnfoldLimit = 4; | 541 static const int kLoopUnfoldLimit = 4; |
541 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit); | 542 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit); |
542 __ Move(scratch3, Factory::the_hole_value()); | 543 __ Move(scratch3, Factory::the_hole_value()); |
543 if (initial_capacity <= kLoopUnfoldLimit) { | 544 if (initial_capacity <= kLoopUnfoldLimit) { |
544 // Use a scratch register here to have only one reloc info when unfolding | 545 // Use a scratch register here to have only one reloc info when unfolding |
545 // the loop. | 546 // the loop. |
546 for (int i = 0; i < initial_capacity; i++) { | 547 for (int i = 0; i < initial_capacity; i++) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 bool fill_with_hole, | 581 bool fill_with_hole, |
581 Label* gc_required) { | 582 Label* gc_required) { |
582 Label not_empty, allocated; | 583 Label not_empty, allocated; |
583 | 584 |
584 // Load the initial map from the array function. | 585 // Load the initial map from the array function. |
585 __ movq(elements_array, | 586 __ movq(elements_array, |
586 FieldOperand(array_function, | 587 FieldOperand(array_function, |
587 JSFunction::kPrototypeOrInitialMapOffset)); | 588 JSFunction::kPrototypeOrInitialMapOffset)); |
588 | 589 |
589 // Check whether an empty sized array is requested. | 590 // Check whether an empty sized array is requested. |
590 __ SmiToInteger64(array_size, array_size); | |
591 __ testq(array_size, array_size); | 591 __ testq(array_size, array_size); |
592 __ j(not_zero, ¬_empty); | 592 __ j(not_zero, ¬_empty); |
593 | 593 |
594 // If an empty array is requested allocate a small elements array anyway. This | 594 // If an empty array is requested allocate a small elements array anyway. This |
595 // keeps the code below free of special casing for the empty array. | 595 // keeps the code below free of special casing for the empty array. |
596 int size = JSArray::kSize + FixedArray::SizeFor(kPreallocatedArrayElements); | 596 int size = JSArray::kSize + FixedArray::SizeFor(kPreallocatedArrayElements); |
597 __ AllocateInNewSpace(size, | 597 __ AllocateInNewSpace(size, |
598 result, | 598 result, |
599 elements_array_end, | 599 elements_array_end, |
600 scratch, | 600 scratch, |
601 gc_required, | 601 gc_required, |
602 TAG_OBJECT); | 602 TAG_OBJECT); |
603 __ jmp(&allocated); | 603 __ jmp(&allocated); |
604 | 604 |
605 // Allocate the JSArray object together with space for a FixedArray with the | 605 // Allocate the JSArray object together with space for a FixedArray with the |
606 // requested elements. | 606 // requested elements. |
607 __ bind(¬_empty); | 607 __ bind(¬_empty); |
608 ASSERT(kSmiTagSize == 1 && kSmiTag == 0); | 608 SmiIndex index = |
| 609 masm->SmiToIndex(kScratchRegister, array_size, kPointerSizeLog2); |
609 __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize, | 610 __ AllocateInNewSpace(JSArray::kSize + FixedArray::kHeaderSize, |
610 times_pointer_size, | 611 index.scale, |
611 array_size, | 612 index.reg, |
612 result, | 613 result, |
613 elements_array_end, | 614 elements_array_end, |
614 scratch, | 615 scratch, |
615 gc_required, | 616 gc_required, |
616 TAG_OBJECT); | 617 TAG_OBJECT); |
617 | 618 |
618 // Allocated the JSArray. Now initialize the fields except for the elements | 619 // Allocated the JSArray. Now initialize the fields except for the elements |
619 // array. | 620 // array. |
620 // result: JSObject | 621 // result: JSObject |
621 // elements_array: initial map | 622 // elements_array: initial map |
622 // elements_array_end: start of next object | 623 // elements_array_end: start of next object |
623 // array_size: size of array | 624 // array_size: size of array (smi) |
624 __ bind(&allocated); | 625 __ bind(&allocated); |
625 __ movq(FieldOperand(result, JSObject::kMapOffset), elements_array); | 626 __ movq(FieldOperand(result, JSObject::kMapOffset), elements_array); |
626 __ Move(elements_array, Factory::empty_fixed_array()); | 627 __ Move(elements_array, Factory::empty_fixed_array()); |
627 __ movq(FieldOperand(result, JSArray::kPropertiesOffset), elements_array); | 628 __ movq(FieldOperand(result, JSArray::kPropertiesOffset), elements_array); |
628 // Field JSArray::kElementsOffset is initialized later. | 629 // Field JSArray::kElementsOffset is initialized later. |
629 __ Integer32ToSmi(scratch, array_size); | 630 __ movq(FieldOperand(result, JSArray::kLengthOffset), array_size); |
630 __ movq(FieldOperand(result, JSArray::kLengthOffset), scratch); | |
631 | 631 |
632 // Calculate the location of the elements array and set elements array member | 632 // Calculate the location of the elements array and set elements array member |
633 // of the JSArray. | 633 // of the JSArray. |
634 // result: JSObject | 634 // result: JSObject |
635 // elements_array_end: start of next object | 635 // elements_array_end: start of next object |
636 // array_size: size of array | 636 // array_size: size of array (smi) |
637 __ lea(elements_array, Operand(result, JSArray::kSize)); | 637 __ lea(elements_array, Operand(result, JSArray::kSize)); |
638 __ movq(FieldOperand(result, JSArray::kElementsOffset), elements_array); | 638 __ movq(FieldOperand(result, JSArray::kElementsOffset), elements_array); |
639 | 639 |
640 // Initialize the fixed array. FixedArray length is not stored as a smi. | 640 // Initialize the fixed array. FixedArray length is stored as a smi. |
641 // result: JSObject | 641 // result: JSObject |
642 // elements_array: elements array | 642 // elements_array: elements array |
643 // elements_array_end: start of next object | 643 // elements_array_end: start of next object |
644 // array_size: size of array | 644 // array_size: size of array (smi) |
645 ASSERT(kSmiTag == 0); | |
646 __ Move(FieldOperand(elements_array, JSObject::kMapOffset), | 645 __ Move(FieldOperand(elements_array, JSObject::kMapOffset), |
647 Factory::fixed_array_map()); | 646 Factory::fixed_array_map()); |
648 Label not_empty_2, fill_array; | 647 Label not_empty_2, fill_array; |
649 __ testq(array_size, array_size); | 648 __ SmiTest(array_size); |
650 __ j(not_zero, ¬_empty_2); | 649 __ j(not_zero, ¬_empty_2); |
651 // Length of the FixedArray is the number of pre-allocated elements even | 650 // Length of the FixedArray is the number of pre-allocated elements even |
652 // though the actual JSArray has length 0. | 651 // though the actual JSArray has length 0. |
653 __ movq(FieldOperand(elements_array, Array::kLengthOffset), | 652 __ Move(FieldOperand(elements_array, FixedArray::kLengthOffset), |
654 Immediate(kPreallocatedArrayElements)); | 653 Smi::FromInt(kPreallocatedArrayElements)); |
655 __ jmp(&fill_array); | 654 __ jmp(&fill_array); |
656 __ bind(¬_empty_2); | 655 __ bind(¬_empty_2); |
657 // For non-empty JSArrays the length of the FixedArray and the JSArray is the | 656 // For non-empty JSArrays the length of the FixedArray and the JSArray is the |
658 // same. | 657 // same. |
659 __ movq(FieldOperand(elements_array, Array::kLengthOffset), array_size); | 658 __ movq(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size); |
660 | 659 |
661 // Fill the allocated FixedArray with the hole value if requested. | 660 // Fill the allocated FixedArray with the hole value if requested. |
662 // result: JSObject | 661 // result: JSObject |
663 // elements_array: elements array | 662 // elements_array: elements array |
664 // elements_array_end: start of next object | 663 // elements_array_end: start of next object |
665 __ bind(&fill_array); | 664 __ bind(&fill_array); |
666 if (fill_with_hole) { | 665 if (fill_with_hole) { |
667 Label loop, entry; | 666 Label loop, entry; |
668 __ Move(scratch, Factory::the_hole_value()); | 667 __ Move(scratch, Factory::the_hole_value()); |
669 __ lea(elements_array, Operand(elements_array, | 668 __ lea(elements_array, Operand(elements_array, |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 no_reg, | 1031 no_reg, |
1033 &undo_allocation, | 1032 &undo_allocation, |
1034 RESULT_CONTAINS_TOP); | 1033 RESULT_CONTAINS_TOP); |
1035 | 1034 |
1036 // Initialize the FixedArray. | 1035 // Initialize the FixedArray. |
1037 // rbx: JSObject | 1036 // rbx: JSObject |
1038 // rdi: FixedArray | 1037 // rdi: FixedArray |
1039 // rdx: number of elements | 1038 // rdx: number of elements |
1040 // rax: start of next object | 1039 // rax: start of next object |
1041 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex); | 1040 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex); |
1042 __ movq(Operand(rdi, JSObject::kMapOffset), rcx); // setup the map | 1041 __ movq(Operand(rdi, HeapObject::kMapOffset), rcx); // setup the map |
1043 __ movl(Operand(rdi, FixedArray::kLengthOffset), rdx); // and length | 1042 __ Integer32ToSmi(rdx, rdx); |
| 1043 __ movq(Operand(rdi, FixedArray::kLengthOffset), rdx); // and length |
1044 | 1044 |
1045 // Initialize the fields to undefined. | 1045 // Initialize the fields to undefined. |
1046 // rbx: JSObject | 1046 // rbx: JSObject |
1047 // rdi: FixedArray | 1047 // rdi: FixedArray |
1048 // rax: start of next object | 1048 // rax: start of next object |
1049 // rdx: number of elements | 1049 // rdx: number of elements |
1050 { Label loop, entry; | 1050 { Label loop, entry; |
1051 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); | 1051 __ LoadRoot(rdx, Heap::kUndefinedValueRootIndex); |
1052 __ lea(rcx, Operand(rdi, FixedArray::kHeaderSize)); | 1052 __ lea(rcx, Operand(rdi, FixedArray::kHeaderSize)); |
1053 __ jmp(&entry); | 1053 __ jmp(&entry); |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1294 } | 1294 } |
1295 | 1295 |
1296 | 1296 |
1297 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 1297 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
1298 Generate_JSEntryTrampolineHelper(masm, true); | 1298 Generate_JSEntryTrampolineHelper(masm, true); |
1299 } | 1299 } |
1300 | 1300 |
1301 } } // namespace v8::internal | 1301 } } // namespace v8::internal |
1302 | 1302 |
1303 #endif // V8_TARGET_ARCH_X64 | 1303 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |