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