| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 // edi: constructor | 178 // edi: constructor |
| 179 // eax: initial map | 179 // eax: initial map |
| 180 __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset)); | 180 __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset)); |
| 181 __ shl(edi, kPointerSizeLog2); | 181 __ shl(edi, kPointerSizeLog2); |
| 182 __ AllocateInNewSpace(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS); | 182 __ AllocateInNewSpace(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS); |
| 183 // Allocated the JSObject, now initialize the fields. | 183 // Allocated the JSObject, now initialize the fields. |
| 184 // eax: initial map | 184 // eax: initial map |
| 185 // ebx: JSObject | 185 // ebx: JSObject |
| 186 // edi: start of next object | 186 // edi: start of next object |
| 187 __ mov(Operand(ebx, JSObject::kMapOffset), eax); | 187 __ mov(Operand(ebx, JSObject::kMapOffset), eax); |
| 188 __ mov(ecx, FACTORY->empty_fixed_array()); | 188 Factory* factory = masm->isolate()->factory(); |
| 189 __ mov(ecx, factory->empty_fixed_array()); |
| 189 __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx); | 190 __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx); |
| 190 __ mov(Operand(ebx, JSObject::kElementsOffset), ecx); | 191 __ mov(Operand(ebx, JSObject::kElementsOffset), ecx); |
| 191 // Set extra fields in the newly allocated object. | 192 // Set extra fields in the newly allocated object. |
| 192 // eax: initial map | 193 // eax: initial map |
| 193 // ebx: JSObject | 194 // ebx: JSObject |
| 194 // edi: start of next object | 195 // edi: start of next object |
| 195 { Label loop, entry; | 196 { Label loop, entry; |
| 196 // To allow for truncation. | 197 // To allow for truncation. |
| 197 if (count_constructions) { | 198 if (count_constructions) { |
| 198 __ mov(edx, FACTORY->one_pointer_filler_map()); | 199 __ mov(edx, factory->one_pointer_filler_map()); |
| 199 } else { | 200 } else { |
| 200 __ mov(edx, FACTORY->undefined_value()); | 201 __ mov(edx, factory->undefined_value()); |
| 201 } | 202 } |
| 202 __ lea(ecx, Operand(ebx, JSObject::kHeaderSize)); | 203 __ lea(ecx, Operand(ebx, JSObject::kHeaderSize)); |
| 203 __ jmp(&entry); | 204 __ jmp(&entry); |
| 204 __ bind(&loop); | 205 __ bind(&loop); |
| 205 __ mov(Operand(ecx, 0), edx); | 206 __ mov(Operand(ecx, 0), edx); |
| 206 __ add(Operand(ecx), Immediate(kPointerSize)); | 207 __ add(Operand(ecx), Immediate(kPointerSize)); |
| 207 __ bind(&entry); | 208 __ bind(&entry); |
| 208 __ cmp(ecx, Operand(edi)); | 209 __ cmp(ecx, Operand(edi)); |
| 209 __ j(less, &loop); | 210 __ j(less, &loop); |
| 210 } | 211 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 ecx, | 247 ecx, |
| 247 no_reg, | 248 no_reg, |
| 248 &undo_allocation, | 249 &undo_allocation, |
| 249 RESULT_CONTAINS_TOP); | 250 RESULT_CONTAINS_TOP); |
| 250 | 251 |
| 251 // Initialize the FixedArray. | 252 // Initialize the FixedArray. |
| 252 // ebx: JSObject | 253 // ebx: JSObject |
| 253 // edi: FixedArray | 254 // edi: FixedArray |
| 254 // edx: number of elements | 255 // edx: number of elements |
| 255 // ecx: start of next object | 256 // ecx: start of next object |
| 256 __ mov(eax, FACTORY->fixed_array_map()); | 257 __ mov(eax, factory->fixed_array_map()); |
| 257 __ mov(Operand(edi, FixedArray::kMapOffset), eax); // setup the map | 258 __ mov(Operand(edi, FixedArray::kMapOffset), eax); // setup the map |
| 258 __ SmiTag(edx); | 259 __ SmiTag(edx); |
| 259 __ mov(Operand(edi, FixedArray::kLengthOffset), edx); // and length | 260 __ mov(Operand(edi, FixedArray::kLengthOffset), edx); // and length |
| 260 | 261 |
| 261 // Initialize the fields to undefined. | 262 // Initialize the fields to undefined. |
| 262 // ebx: JSObject | 263 // ebx: JSObject |
| 263 // edi: FixedArray | 264 // edi: FixedArray |
| 264 // ecx: start of next object | 265 // ecx: start of next object |
| 265 { Label loop, entry; | 266 { Label loop, entry; |
| 266 __ mov(edx, FACTORY->undefined_value()); | 267 __ mov(edx, factory->undefined_value()); |
| 267 __ lea(eax, Operand(edi, FixedArray::kHeaderSize)); | 268 __ lea(eax, Operand(edi, FixedArray::kHeaderSize)); |
| 268 __ jmp(&entry); | 269 __ jmp(&entry); |
| 269 __ bind(&loop); | 270 __ bind(&loop); |
| 270 __ mov(Operand(eax, 0), edx); | 271 __ mov(Operand(eax, 0), edx); |
| 271 __ add(Operand(eax), Immediate(kPointerSize)); | 272 __ add(Operand(eax), Immediate(kPointerSize)); |
| 272 __ bind(&entry); | 273 __ bind(&entry); |
| 273 __ cmp(eax, Operand(ecx)); | 274 __ cmp(eax, Operand(ecx)); |
| 274 __ j(below, &loop); | 275 __ j(below, &loop); |
| 275 } | 276 } |
| 276 | 277 |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 __ pushad(); | 556 __ pushad(); |
| 556 __ EnterInternalFrame(); | 557 __ EnterInternalFrame(); |
| 557 __ CallRuntime(Runtime::kNotifyOSR, 0); | 558 __ CallRuntime(Runtime::kNotifyOSR, 0); |
| 558 __ LeaveInternalFrame(); | 559 __ LeaveInternalFrame(); |
| 559 __ popad(); | 560 __ popad(); |
| 560 __ ret(0); | 561 __ ret(0); |
| 561 } | 562 } |
| 562 | 563 |
| 563 | 564 |
| 564 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { | 565 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
| 566 Factory* factory = masm->isolate()->factory(); |
| 567 |
| 565 // 1. Make sure we have at least one argument. | 568 // 1. Make sure we have at least one argument. |
| 566 { Label done; | 569 { Label done; |
| 567 __ test(eax, Operand(eax)); | 570 __ test(eax, Operand(eax)); |
| 568 __ j(not_zero, &done, taken); | 571 __ j(not_zero, &done, taken); |
| 569 __ pop(ebx); | 572 __ pop(ebx); |
| 570 __ push(Immediate(FACTORY->undefined_value())); | 573 __ push(Immediate(factory->undefined_value())); |
| 571 __ push(ebx); | 574 __ push(ebx); |
| 572 __ inc(eax); | 575 __ inc(eax); |
| 573 __ bind(&done); | 576 __ bind(&done); |
| 574 } | 577 } |
| 575 | 578 |
| 576 // 2. Get the function to call (passed as receiver) from the stack, check | 579 // 2. Get the function to call (passed as receiver) from the stack, check |
| 577 // if it is a function. | 580 // if it is a function. |
| 578 Label non_function; | 581 Label non_function; |
| 579 // 1 ~ return address. | 582 // 1 ~ return address. |
| 580 __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize)); | 583 __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 594 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 597 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 595 __ test_b(FieldOperand(ebx, SharedFunctionInfo::kStrictModeByteOffset), | 598 __ test_b(FieldOperand(ebx, SharedFunctionInfo::kStrictModeByteOffset), |
| 596 1 << SharedFunctionInfo::kStrictModeBitWithinByte); | 599 1 << SharedFunctionInfo::kStrictModeBitWithinByte); |
| 597 __ j(not_equal, &shift_arguments); | 600 __ j(not_equal, &shift_arguments); |
| 598 | 601 |
| 599 // Compute the receiver in non-strict mode. | 602 // Compute the receiver in non-strict mode. |
| 600 __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument. | 603 __ mov(ebx, Operand(esp, eax, times_4, 0)); // First argument. |
| 601 __ test(ebx, Immediate(kSmiTagMask)); | 604 __ test(ebx, Immediate(kSmiTagMask)); |
| 602 __ j(zero, &convert_to_object); | 605 __ j(zero, &convert_to_object); |
| 603 | 606 |
| 604 __ cmp(ebx, FACTORY->null_value()); | 607 __ cmp(ebx, factory->null_value()); |
| 605 __ j(equal, &use_global_receiver); | 608 __ j(equal, &use_global_receiver); |
| 606 __ cmp(ebx, FACTORY->undefined_value()); | 609 __ cmp(ebx, factory->undefined_value()); |
| 607 __ j(equal, &use_global_receiver); | 610 __ j(equal, &use_global_receiver); |
| 608 | 611 |
| 609 // We don't use IsObjectJSObjectType here because we jump on success. | 612 // We don't use IsObjectJSObjectType here because we jump on success. |
| 610 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); | 613 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); |
| 611 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 614 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 612 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); | 615 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); |
| 613 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); | 616 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); |
| 614 __ j(below_equal, &shift_arguments); | 617 __ j(below_equal, &shift_arguments); |
| 615 | 618 |
| 616 __ bind(&convert_to_object); | 619 __ bind(&convert_to_object); |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 | 751 |
| 749 // Do not transform the receiver for strict mode functions. | 752 // Do not transform the receiver for strict mode functions. |
| 750 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 753 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 751 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), | 754 __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), |
| 752 1 << SharedFunctionInfo::kStrictModeBitWithinByte); | 755 1 << SharedFunctionInfo::kStrictModeBitWithinByte); |
| 753 __ j(not_equal, &push_receiver); | 756 __ j(not_equal, &push_receiver); |
| 754 | 757 |
| 755 // Compute the receiver in non-strict mode. | 758 // Compute the receiver in non-strict mode. |
| 756 __ test(ebx, Immediate(kSmiTagMask)); | 759 __ test(ebx, Immediate(kSmiTagMask)); |
| 757 __ j(zero, &call_to_object); | 760 __ j(zero, &call_to_object); |
| 758 __ cmp(ebx, FACTORY->null_value()); | 761 Factory* factory = masm->isolate()->factory(); |
| 762 __ cmp(ebx, factory->null_value()); |
| 759 __ j(equal, &use_global_receiver); | 763 __ j(equal, &use_global_receiver); |
| 760 __ cmp(ebx, FACTORY->undefined_value()); | 764 __ cmp(ebx, factory->undefined_value()); |
| 761 __ j(equal, &use_global_receiver); | 765 __ j(equal, &use_global_receiver); |
| 762 | 766 |
| 763 // If given receiver is already a JavaScript object then there's no | 767 // If given receiver is already a JavaScript object then there's no |
| 764 // reason for converting it. | 768 // reason for converting it. |
| 765 // We don't use IsObjectJSObjectType here because we jump on success. | 769 // We don't use IsObjectJSObjectType here because we jump on success. |
| 766 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); | 770 __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset)); |
| 767 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 771 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 768 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); | 772 __ sub(Operand(ecx), Immediate(FIRST_JS_OBJECT_TYPE)); |
| 769 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); | 773 __ cmp(ecx, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE); |
| 770 __ j(below_equal, &push_receiver); | 774 __ j(below_equal, &push_receiver); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 scratch3, | 865 scratch3, |
| 862 gc_required, | 866 gc_required, |
| 863 TAG_OBJECT); | 867 TAG_OBJECT); |
| 864 | 868 |
| 865 // Allocated the JSArray. Now initialize the fields except for the elements | 869 // Allocated the JSArray. Now initialize the fields except for the elements |
| 866 // array. | 870 // array. |
| 867 // result: JSObject | 871 // result: JSObject |
| 868 // scratch1: initial map | 872 // scratch1: initial map |
| 869 // scratch2: start of next object | 873 // scratch2: start of next object |
| 870 __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1); | 874 __ mov(FieldOperand(result, JSObject::kMapOffset), scratch1); |
| 875 Factory* factory = masm->isolate()->factory(); |
| 871 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), | 876 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), |
| 872 FACTORY->empty_fixed_array()); | 877 factory->empty_fixed_array()); |
| 873 // Field JSArray::kElementsOffset is initialized later. | 878 // Field JSArray::kElementsOffset is initialized later. |
| 874 __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0)); | 879 __ mov(FieldOperand(result, JSArray::kLengthOffset), Immediate(0)); |
| 875 | 880 |
| 876 // If no storage is requested for the elements array just set the empty | 881 // If no storage is requested for the elements array just set the empty |
| 877 // fixed array. | 882 // fixed array. |
| 878 if (initial_capacity == 0) { | 883 if (initial_capacity == 0) { |
| 879 __ mov(FieldOperand(result, JSArray::kElementsOffset), | 884 __ mov(FieldOperand(result, JSArray::kElementsOffset), |
| 880 FACTORY->empty_fixed_array()); | 885 factory->empty_fixed_array()); |
| 881 return; | 886 return; |
| 882 } | 887 } |
| 883 | 888 |
| 884 // Calculate the location of the elements array and set elements array member | 889 // Calculate the location of the elements array and set elements array member |
| 885 // of the JSArray. | 890 // of the JSArray. |
| 886 // result: JSObject | 891 // result: JSObject |
| 887 // scratch2: start of next object | 892 // scratch2: start of next object |
| 888 __ lea(scratch1, Operand(result, JSArray::kSize)); | 893 __ lea(scratch1, Operand(result, JSArray::kSize)); |
| 889 __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1); | 894 __ mov(FieldOperand(result, JSArray::kElementsOffset), scratch1); |
| 890 | 895 |
| 891 // Initialize the FixedArray and fill it with holes. FixedArray length is | 896 // Initialize the FixedArray and fill it with holes. FixedArray length is |
| 892 // stored as a smi. | 897 // stored as a smi. |
| 893 // result: JSObject | 898 // result: JSObject |
| 894 // scratch1: elements array | 899 // scratch1: elements array |
| 895 // scratch2: start of next object | 900 // scratch2: start of next object |
| 896 __ mov(FieldOperand(scratch1, FixedArray::kMapOffset), | 901 __ mov(FieldOperand(scratch1, FixedArray::kMapOffset), |
| 897 FACTORY->fixed_array_map()); | 902 factory->fixed_array_map()); |
| 898 __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset), | 903 __ mov(FieldOperand(scratch1, FixedArray::kLengthOffset), |
| 899 Immediate(Smi::FromInt(initial_capacity))); | 904 Immediate(Smi::FromInt(initial_capacity))); |
| 900 | 905 |
| 901 // Fill the FixedArray with the hole value. Inline the code if short. | 906 // Fill the FixedArray with the hole value. Inline the code if short. |
| 902 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. | 907 // Reconsider loop unfolding if kPreallocatedArrayElements gets changed. |
| 903 static const int kLoopUnfoldLimit = 4; | 908 static const int kLoopUnfoldLimit = 4; |
| 904 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit); | 909 ASSERT(kPreallocatedArrayElements <= kLoopUnfoldLimit); |
| 905 if (initial_capacity <= kLoopUnfoldLimit) { | 910 if (initial_capacity <= kLoopUnfoldLimit) { |
| 906 // Use a scratch register here to have only one reloc info when unfolding | 911 // Use a scratch register here to have only one reloc info when unfolding |
| 907 // the loop. | 912 // the loop. |
| 908 __ mov(scratch3, FACTORY->the_hole_value()); | 913 __ mov(scratch3, factory->the_hole_value()); |
| 909 for (int i = 0; i < initial_capacity; i++) { | 914 for (int i = 0; i < initial_capacity; i++) { |
| 910 __ mov(FieldOperand(scratch1, | 915 __ mov(FieldOperand(scratch1, |
| 911 FixedArray::kHeaderSize + i * kPointerSize), | 916 FixedArray::kHeaderSize + i * kPointerSize), |
| 912 scratch3); | 917 scratch3); |
| 913 } | 918 } |
| 914 } else { | 919 } else { |
| 915 Label loop, entry; | 920 Label loop, entry; |
| 916 __ jmp(&entry); | 921 __ jmp(&entry); |
| 917 __ bind(&loop); | 922 __ bind(&loop); |
| 918 __ mov(Operand(scratch1, 0), FACTORY->the_hole_value()); | 923 __ mov(Operand(scratch1, 0), factory->the_hole_value()); |
| 919 __ add(Operand(scratch1), Immediate(kPointerSize)); | 924 __ add(Operand(scratch1), Immediate(kPointerSize)); |
| 920 __ bind(&entry); | 925 __ bind(&entry); |
| 921 __ cmp(scratch1, Operand(scratch2)); | 926 __ cmp(scratch1, Operand(scratch2)); |
| 922 __ j(below, &loop); | 927 __ j(below, &loop); |
| 923 } | 928 } |
| 924 } | 929 } |
| 925 | 930 |
| 926 | 931 |
| 927 // Allocate a JSArray with the number of elements stored in a register. The | 932 // Allocate a JSArray with the number of elements stored in a register. The |
| 928 // register array_function holds the built-in Array function and the register | 933 // register array_function holds the built-in Array function and the register |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 gc_required, | 968 gc_required, |
| 964 TAG_OBJECT); | 969 TAG_OBJECT); |
| 965 | 970 |
| 966 // Allocated the JSArray. Now initialize the fields except for the elements | 971 // Allocated the JSArray. Now initialize the fields except for the elements |
| 967 // array. | 972 // array. |
| 968 // result: JSObject | 973 // result: JSObject |
| 969 // elements_array: initial map | 974 // elements_array: initial map |
| 970 // elements_array_end: start of next object | 975 // elements_array_end: start of next object |
| 971 // array_size: size of array (smi) | 976 // array_size: size of array (smi) |
| 972 __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array); | 977 __ mov(FieldOperand(result, JSObject::kMapOffset), elements_array); |
| 973 __ mov(elements_array, FACTORY->empty_fixed_array()); | 978 Factory* factory = masm->isolate()->factory(); |
| 979 __ mov(elements_array, factory->empty_fixed_array()); |
| 974 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array); | 980 __ mov(FieldOperand(result, JSArray::kPropertiesOffset), elements_array); |
| 975 // Field JSArray::kElementsOffset is initialized later. | 981 // Field JSArray::kElementsOffset is initialized later. |
| 976 __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size); | 982 __ mov(FieldOperand(result, JSArray::kLengthOffset), array_size); |
| 977 | 983 |
| 978 // Calculate the location of the elements array and set elements array member | 984 // Calculate the location of the elements array and set elements array member |
| 979 // of the JSArray. | 985 // of the JSArray. |
| 980 // result: JSObject | 986 // result: JSObject |
| 981 // elements_array_end: start of next object | 987 // elements_array_end: start of next object |
| 982 // array_size: size of array (smi) | 988 // array_size: size of array (smi) |
| 983 __ lea(elements_array, Operand(result, JSArray::kSize)); | 989 __ lea(elements_array, Operand(result, JSArray::kSize)); |
| 984 __ mov(FieldOperand(result, JSArray::kElementsOffset), elements_array); | 990 __ mov(FieldOperand(result, JSArray::kElementsOffset), elements_array); |
| 985 | 991 |
| 986 // Initialize the fixed array. FixedArray length is stored as a smi. | 992 // Initialize the fixed array. FixedArray length is stored as a smi. |
| 987 // result: JSObject | 993 // result: JSObject |
| 988 // elements_array: elements array | 994 // elements_array: elements array |
| 989 // elements_array_end: start of next object | 995 // elements_array_end: start of next object |
| 990 // array_size: size of array (smi) | 996 // array_size: size of array (smi) |
| 991 __ mov(FieldOperand(elements_array, FixedArray::kMapOffset), | 997 __ mov(FieldOperand(elements_array, FixedArray::kMapOffset), |
| 992 FACTORY->fixed_array_map()); | 998 factory->fixed_array_map()); |
| 993 // For non-empty JSArrays the length of the FixedArray and the JSArray is the | 999 // For non-empty JSArrays the length of the FixedArray and the JSArray is the |
| 994 // same. | 1000 // same. |
| 995 __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size); | 1001 __ mov(FieldOperand(elements_array, FixedArray::kLengthOffset), array_size); |
| 996 | 1002 |
| 997 // Fill the allocated FixedArray with the hole value if requested. | 1003 // Fill the allocated FixedArray with the hole value if requested. |
| 998 // result: JSObject | 1004 // result: JSObject |
| 999 // elements_array: elements array | 1005 // elements_array: elements array |
| 1000 if (fill_with_hole) { | 1006 if (fill_with_hole) { |
| 1001 __ SmiUntag(array_size); | 1007 __ SmiUntag(array_size); |
| 1002 __ lea(edi, Operand(elements_array, | 1008 __ lea(edi, Operand(elements_array, |
| 1003 FixedArray::kHeaderSize - kHeapObjectTag)); | 1009 FixedArray::kHeaderSize - kHeapObjectTag)); |
| 1004 __ mov(eax, FACTORY->the_hole_value()); | 1010 __ mov(eax, factory->the_hole_value()); |
| 1005 __ cld(); | 1011 __ cld(); |
| 1006 // Do not use rep stos when filling less than kRepStosThreshold | 1012 // Do not use rep stos when filling less than kRepStosThreshold |
| 1007 // words. | 1013 // words. |
| 1008 const int kRepStosThreshold = 16; | 1014 const int kRepStosThreshold = 16; |
| 1009 Label loop, entry, done; | 1015 Label loop, entry, done; |
| 1010 __ cmp(ecx, kRepStosThreshold); | 1016 __ cmp(ecx, kRepStosThreshold); |
| 1011 __ j(below, &loop); // Note: ecx > 0. | 1017 __ j(below, &loop); // Note: ecx > 0. |
| 1012 __ rep_stos(); | 1018 __ rep_stos(); |
| 1013 __ jmp(&done); | 1019 __ jmp(&done); |
| 1014 __ bind(&loop); | 1020 __ bind(&loop); |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1335 if (FLAG_debug_code) { | 1341 if (FLAG_debug_code) { |
| 1336 __ cmpb(FieldOperand(ecx, Map::kInstanceSizeOffset), | 1342 __ cmpb(FieldOperand(ecx, Map::kInstanceSizeOffset), |
| 1337 JSValue::kSize >> kPointerSizeLog2); | 1343 JSValue::kSize >> kPointerSizeLog2); |
| 1338 __ Assert(equal, "Unexpected string wrapper instance size"); | 1344 __ Assert(equal, "Unexpected string wrapper instance size"); |
| 1339 __ cmpb(FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset), 0); | 1345 __ cmpb(FieldOperand(ecx, Map::kUnusedPropertyFieldsOffset), 0); |
| 1340 __ Assert(equal, "Unexpected unused properties of string wrapper"); | 1346 __ Assert(equal, "Unexpected unused properties of string wrapper"); |
| 1341 } | 1347 } |
| 1342 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx); | 1348 __ mov(FieldOperand(eax, HeapObject::kMapOffset), ecx); |
| 1343 | 1349 |
| 1344 // Set properties and elements. | 1350 // Set properties and elements. |
| 1345 __ Set(ecx, Immediate(FACTORY->empty_fixed_array())); | 1351 Factory* factory = masm->isolate()->factory(); |
| 1352 __ Set(ecx, Immediate(factory->empty_fixed_array())); |
| 1346 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx); | 1353 __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ecx); |
| 1347 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx); | 1354 __ mov(FieldOperand(eax, JSObject::kElementsOffset), ecx); |
| 1348 | 1355 |
| 1349 // Set the value. | 1356 // Set the value. |
| 1350 __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); | 1357 __ mov(FieldOperand(eax, JSValue::kValueOffset), ebx); |
| 1351 | 1358 |
| 1352 // Ensure the object is fully initialized. | 1359 // Ensure the object is fully initialized. |
| 1353 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); | 1360 STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); |
| 1354 | 1361 |
| 1355 // We're done. Return. | 1362 // We're done. Return. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1376 __ push(eax); | 1383 __ push(eax); |
| 1377 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); | 1384 __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); |
| 1378 __ pop(edi); | 1385 __ pop(edi); |
| 1379 __ LeaveInternalFrame(); | 1386 __ LeaveInternalFrame(); |
| 1380 __ mov(ebx, eax); | 1387 __ mov(ebx, eax); |
| 1381 __ jmp(&argument_is_string); | 1388 __ jmp(&argument_is_string); |
| 1382 | 1389 |
| 1383 // Load the empty string into ebx, remove the receiver from the | 1390 // Load the empty string into ebx, remove the receiver from the |
| 1384 // stack, and jump back to the case where the argument is a string. | 1391 // stack, and jump back to the case where the argument is a string. |
| 1385 __ bind(&no_arguments); | 1392 __ bind(&no_arguments); |
| 1386 __ Set(ebx, Immediate(FACTORY->empty_string())); | 1393 __ Set(ebx, Immediate(factory->empty_string())); |
| 1387 __ pop(ecx); | 1394 __ pop(ecx); |
| 1388 __ lea(esp, Operand(esp, kPointerSize)); | 1395 __ lea(esp, Operand(esp, kPointerSize)); |
| 1389 __ push(ecx); | 1396 __ push(ecx); |
| 1390 __ jmp(&argument_is_string); | 1397 __ jmp(&argument_is_string); |
| 1391 | 1398 |
| 1392 // At this point the argument is already a string. Call runtime to | 1399 // At this point the argument is already a string. Call runtime to |
| 1393 // create a string wrapper. | 1400 // create a string wrapper. |
| 1394 __ bind(&gc_required); | 1401 __ bind(&gc_required); |
| 1395 __ IncrementCounter(counters->string_ctor_gc_required(), 1); | 1402 __ IncrementCounter(counters->string_ctor_gc_required(), 1); |
| 1396 __ EnterInternalFrame(); | 1403 __ EnterInternalFrame(); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1591 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
| 1585 generator.Generate(); | 1592 generator.Generate(); |
| 1586 } | 1593 } |
| 1587 | 1594 |
| 1588 | 1595 |
| 1589 #undef __ | 1596 #undef __ |
| 1590 } | 1597 } |
| 1591 } // namespace v8::internal | 1598 } // namespace v8::internal |
| 1592 | 1599 |
| 1593 #endif // V8_TARGET_ARCH_IA32 | 1600 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |