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